openc3-cosmos-cfdp 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +18 -0
  3. data/README.md +181 -0
  4. data/Rakefile +40 -0
  5. data/lib/cfdp.rb +283 -0
  6. data/lib/cfdp_api.rb +204 -0
  7. data/microservices/CFDP/Gemfile +37 -0
  8. data/microservices/CFDP/Rakefile +6 -0
  9. data/microservices/CFDP/app/controllers/application_controller.rb +46 -0
  10. data/microservices/CFDP/app/controllers/cfdp_controller.rb +222 -0
  11. data/microservices/CFDP/app/models/cfdp_checksum.rb +52 -0
  12. data/microservices/CFDP/app/models/cfdp_crc_checksum.rb +41 -0
  13. data/microservices/CFDP/app/models/cfdp_mib.rb +613 -0
  14. data/microservices/CFDP/app/models/cfdp_model.rb +25 -0
  15. data/microservices/CFDP/app/models/cfdp_null_checksum.rb +29 -0
  16. data/microservices/CFDP/app/models/cfdp_pdu.rb +202 -0
  17. data/microservices/CFDP/app/models/cfdp_receive_transaction.rb +590 -0
  18. data/microservices/CFDP/app/models/cfdp_source_transaction.rb +449 -0
  19. data/microservices/CFDP/app/models/cfdp_topic.rb +58 -0
  20. data/microservices/CFDP/app/models/cfdp_transaction.rb +188 -0
  21. data/microservices/CFDP/app/models/cfdp_user.rb +601 -0
  22. data/microservices/CFDP/bin/rails +4 -0
  23. data/microservices/CFDP/bin/rake +4 -0
  24. data/microservices/CFDP/bin/setup +25 -0
  25. data/microservices/CFDP/config/application.rb +55 -0
  26. data/microservices/CFDP/config/boot.rb +4 -0
  27. data/microservices/CFDP/config/credentials.yml.enc +1 -0
  28. data/microservices/CFDP/config/environment.rb +5 -0
  29. data/microservices/CFDP/config/environments/development.rb +53 -0
  30. data/microservices/CFDP/config/environments/production.rb +75 -0
  31. data/microservices/CFDP/config/environments/test.rb +50 -0
  32. data/microservices/CFDP/config/initializers/application_controller_renderer.rb +8 -0
  33. data/microservices/CFDP/config/initializers/backtrace_silencers.rb +7 -0
  34. data/microservices/CFDP/config/initializers/cfdp_initializer.rb +26 -0
  35. data/microservices/CFDP/config/initializers/cors.rb +16 -0
  36. data/microservices/CFDP/config/initializers/filter_parameter_logging.rb +8 -0
  37. data/microservices/CFDP/config/initializers/inflections.rb +16 -0
  38. data/microservices/CFDP/config/initializers/mime_types.rb +4 -0
  39. data/microservices/CFDP/config/initializers/wrap_parameters.rb +9 -0
  40. data/microservices/CFDP/config/locales/en.yml +29 -0
  41. data/microservices/CFDP/config/puma.rb +38 -0
  42. data/microservices/CFDP/config/routes.rb +16 -0
  43. data/microservices/CFDP/config.ru +5 -0
  44. data/microservices/CFDP/init.sh +9 -0
  45. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_ack.rb +82 -0
  46. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_enum.rb +237 -0
  47. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_eof.rb +87 -0
  48. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_file_data.rb +98 -0
  49. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_finished.rb +114 -0
  50. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_keep_alive.rb +65 -0
  51. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_metadata.rb +116 -0
  52. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_nak.rb +91 -0
  53. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_prompt.rb +60 -0
  54. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_tlv.rb +291 -0
  55. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_user_ops.rb +749 -0
  56. data/microservices/CFDP/public/robots.txt +1 -0
  57. data/microservices/CFDP/spec/models/cfdp_pdu_ack_spec.rb +114 -0
  58. data/microservices/CFDP/spec/models/cfdp_pdu_eof_spec.rb +159 -0
  59. data/microservices/CFDP/spec/models/cfdp_pdu_file_data_spec.rb +76 -0
  60. data/microservices/CFDP/spec/models/cfdp_pdu_finished_spec.rb +192 -0
  61. data/microservices/CFDP/spec/models/cfdp_pdu_keep_alive_spec.rb +69 -0
  62. data/microservices/CFDP/spec/models/cfdp_pdu_metadata_spec.rb +346 -0
  63. data/microservices/CFDP/spec/models/cfdp_pdu_nak_spec.rb +126 -0
  64. data/microservices/CFDP/spec/models/cfdp_pdu_prompt_spec.rb +94 -0
  65. data/microservices/CFDP/spec/models/cfdp_pdu_spec.rb +111 -0
  66. data/microservices/CFDP/spec/rails_helper.rb +71 -0
  67. data/microservices/CFDP/spec/requests/cfdp_spec.rb +1965 -0
  68. data/microservices/CFDP/spec/spec_helper.rb +200 -0
  69. data/plugin.txt +67 -0
  70. data/targets/CFDPTEST/cmd_tlm/cmd.txt +5 -0
  71. data/targets/CFDPTEST/cmd_tlm/tlm.txt +4 -0
  72. data/targets/CFDPTEST/procedures/cfdp_test_suite.rb +130 -0
  73. data/targets/CFDPTEST/target.txt +4 -0
  74. metadata +118 -0
@@ -0,0 +1,749 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2023 OpenC3, Inc.
4
+ # All Rights Reserved.
5
+ #
6
+ # Licensed for Evaluation and Educational Use
7
+ #
8
+ # This file may only be used commercially under the terms of a commercial license
9
+ # purchased from OpenC3, Inc.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+ #
15
+ # The development of this software was funded in-whole or in-part by MethaneSAT LLC.
16
+
17
+ class CfdpPdu < OpenC3::Packet
18
+
19
+ # Table 5-2
20
+ def define_length_value
21
+ s = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
22
+ s.append_item("LENGTH", 8, :UINT)
23
+ s.append_item("VALUE", 0, :BLOCK)
24
+ return s
25
+ end
26
+
27
+ # Table 6-1
28
+ def define_reserved_cfdp_message_header
29
+ s = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
30
+ item = s.append_item("MSG_ID", 32, :STRING)
31
+ item = s.append_item("MSG_TYPE", 8, :UINT)
32
+ item.states = USER_MESSAGE_TYPES
33
+ return s
34
+ end
35
+
36
+ # Table 6-2
37
+ def define_originating_transaction_id_message_fixed_header
38
+ s = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
39
+ s.append_item("RESERVED1", 1, :UINT)
40
+ s.append_item("ENTITY_ID_LENGTH", 3, :UINT)
41
+ s.append_item("RESERVED2", 1, :UINT)
42
+ s.append_item("SEQUENCE_NUMBER_LENGTH", 3, :UINT)
43
+ return s
44
+ end
45
+
46
+ def define_originating_transaction_id_message_variable_data(id_length:, seq_num_length:)
47
+ s = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
48
+ s.append_item("SOURCE_ENTITY_ID", id_length * 8, :UINT)
49
+ s.append_item("SEQUENCE_NUMBER", seq_num_length * 8, :UINT, nil, :BIG_ENDIAN, :TRUNCATE)
50
+ return s
51
+ end
52
+
53
+ def build_originating_transaction_id_message_contents(source_entity_id:, sequence_number:)
54
+ id_length = read("ENTITY_ID_LENGTH")
55
+ seq_num_length = read("SEQUENCE_NUMBER_LENGTH")
56
+ s2 = define_originating_transaction_id_message_fixed_header()
57
+ s2.write("RESERVED1", 0)
58
+ s2.write("ENTITY_ID_LENGTH", id_length)
59
+ s2.write("RESERVED2", 0)
60
+ s2.write("SEQUENCE_NUMBER_LENGTH", seq_num_length)
61
+ s3 = define_originating_transaction_id_message_variable_data(id_length: id_length + 1, seq_num_length: seq_num_length + 1)
62
+ s3.write("SOURCE_ENTITY_ID", source_entity_id)
63
+ s3.write("SEQUENCE_NUMBER", sequence_number)
64
+ return s2.buffer(false) + s3.buffer(false)
65
+ end
66
+
67
+ def build_originating_transaction_id_message(source_entity_id:, sequence_number:)
68
+ s1 = define_reserved_cfdp_message_header()
69
+ s1.write("MSG_ID", "cfdp")
70
+ s1.write("MSG_TYPE", "ORIGINATING_TRANSACTION_ID")
71
+ return s1.buffer(length) + build_originating_transaction_id_message_contents(source_entity_id: source_entity_id, sequence_number: sequence_number)
72
+ end
73
+
74
+ def decom_originating_transaction_id_message(message_to_user)
75
+ result = {}
76
+ message_to_user = message_to_user[5..-1] # Remove header
77
+ s = define_originating_transaction_id_message_fixed_header()
78
+ s.buffer = message_to_user[0..(s.defined_length - 1)]
79
+ id_length = s.read("ENTITY_ID_LENGTH")
80
+ seq_num_length = s.read("SEQUENCE_NUMBER_LENGTH")
81
+ message_to_user = message_to_user[s.defined_length..-1]
82
+ s2 = define_originating_transaction_id_message_variable_data(id_length: id_length + 1, seq_num_length: seq_num_length + 1)
83
+ s2.buffer = message_to_user[0..(s2.defined_length - 1)]
84
+ result["SOURCE_ENTITY_ID"] = s2.read("SOURCE_ENTITY_ID")
85
+ result["SEQUENCE_NUMBER"] = s2.read("SEQUENCE_NUMBER")
86
+ message_to_user = message_to_user[s2.defined_length..-1]
87
+ result["MSG_TYPE"] = "ORIGINATING_TRANSACTION_ID"
88
+ return result, message_to_user
89
+ end
90
+
91
+ # Table 6-4
92
+ def define_proxy_put_request_message
93
+ id_length = read("ENTITY_ID_LENGTH") + 1
94
+ s = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
95
+ s.append_item("LENGTH", 8, :UINT)
96
+ s.append_item("DESTINATION_ENTITY_ID", id_length * 8, :UINT)
97
+ return s, define_length_value(), define_length_value()
98
+ end
99
+
100
+ def build_proxy_put_request_message(destination_entity_id:, source_file_name: nil, destination_file_name: nil)
101
+ s1 = define_reserved_cfdp_message_header()
102
+ s1.write("MSG_ID", "cfdp")
103
+ s1.write("MSG_TYPE", "PROXY_PUT_REQUEST")
104
+ dei, sfn, dfn = define_proxy_put_request_message()
105
+ dei.write("LENGTH", read("ENTITY_ID_LENGTH") + 1)
106
+ dei.write("DESTINATION_ENTITY_ID", destination_entity_id)
107
+ sfn.write("LENGTH", source_file_name.to_s.length)
108
+ sfn.write("VALUE", source_file_name.to_s)
109
+ dfn.write("LENGTH", destination_file_name.to_s.length)
110
+ dfn.write("VALUE", destination_file_name.to_s)
111
+ return s1.buffer(false) + dei.buffer(false) + sfn.buffer(false) + dfn.buffer(false)
112
+ end
113
+
114
+ def decom_proxy_put_request_message(message_to_user)
115
+ result = {}
116
+ message_to_user = message_to_user[5..-1] # Remove header
117
+ dei, sfn, dfn = define_proxy_put_request_message()
118
+ dei.buffer = message_to_user[0..(dei.defined_length - 1)]
119
+ result["DESTINATION_ENTITY_ID"] = dei.read("DESTINATION_ENTITY_ID")
120
+ message_to_user = message_to_user[dei.defined_length..-1]
121
+ sfn.buffer = message_to_user
122
+ length = sfn.read("LENGTH")
123
+ sfn.buffer = sfn.buffer(false)[0..length] # Includes length field
124
+ source_file_name = sfn.read("VALUE")
125
+ result["SOURCE_FILE_NAME"] = source_file_name if source_file_name.length > 0
126
+ message_to_user = message_to_user[(length + 1)..-1]
127
+ dfn.buffer = message_to_user
128
+ length = dfn.read("LENGTH")
129
+ dfn.buffer = dfn.buffer(false)[0..length] # Includes length field
130
+ destination_file_name = dfn.read("VALUE")
131
+ result["DESTINATION_FILE_NAME"] = destination_file_name if destination_file_name.length > 0
132
+ result["MSG_TYPE"] = "PROXY_PUT_REQUEST"
133
+ return result
134
+ end
135
+
136
+ # Table 6-5
137
+ def define_proxy_message_to_user_message
138
+ return define_length_value()
139
+ end
140
+
141
+ def build_proxy_message_to_user_message(message_to_user:)
142
+ s1 = define_reserved_cfdp_message_header()
143
+ s1.write("MSG_ID", "cfdp")
144
+ s1.write("MSG_TYPE", "PROXY_MESSAGE_TO_USER")
145
+ s2 = define_proxy_message_to_user_message()
146
+ s2.write("LENGTH", message_to_user.length)
147
+ s2.write("VALUE", message_to_user)
148
+ return s1.buffer(false) + s2.buffer(false)
149
+ end
150
+
151
+ def decom_proxy_message_to_user_message(message_to_user)
152
+ result = {}
153
+ message_to_user = message_to_user[5..-1] # Remove header
154
+ s = define_proxy_message_to_user_message()
155
+ s.buffer = message_to_user
156
+ length = s.read("LENGTH")
157
+ if length > 0
158
+ result["MESSAGE_TO_USER"] = s.read("VALUE")[0..(length - 1)]
159
+ else
160
+ result["MESSAGE_TO_USER"] = ""
161
+ end
162
+ result["MSG_TYPE"] = "PROXY_MESSAGE_TO_USER"
163
+ return result
164
+ end
165
+
166
+ # Table 6-6
167
+ def define_proxy_filestore_request_message
168
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
169
+ s1.append_item("LENGTH", 8, :UINT)
170
+ item = s1.append_item("ACTION_CODE", 4, :UINT)
171
+ item.states = ACTION_CODES
172
+ s1.append_item("SPARE", 4, :UINT)
173
+ return s1, define_length_value(), define_length_value()
174
+ end
175
+
176
+ def build_proxy_filestore_request_message(action_code:, first_file_name:, second_file_name: nil)
177
+ s1 = define_reserved_cfdp_message_header()
178
+ s1.write("MSG_ID", "cfdp")
179
+ s1.write("MSG_TYPE", "PROXY_FILESTORE_REQUEST")
180
+ s2, s3, s4 = define_proxy_filestore_request_message()
181
+ s2.write("ACTION_CODE", action_code)
182
+ s2.write("SPARE", 0)
183
+ s3.write("LENGTH", first_file_name.to_s.length)
184
+ s3.write("VALUE", first_file_name.to_s)
185
+ s4.write("LENGTH", second_file_name.to_s.length)
186
+ s4.write("VALUE", second_file_name.to_s)
187
+ s2.write("LENGTH", s2.length + s3.length + s4.length)
188
+ return s1.buffer(false) + s2.buffer(false) + s3.buffer(false) + s4.buffer(false)
189
+ end
190
+
191
+ def decom_proxy_filestore_request_message(message_to_user)
192
+ result = {}
193
+ message_to_user = message_to_user[5..-1] # Remove header
194
+ s2, s3, s4 = define_proxy_filestore_request_message()
195
+ s2.buffer = message_to_user[0..(s2.defined_length - 1)]
196
+ message_to_user = message_to_user[s2.defined_length..-1]
197
+ s3.buffer = message_to_user
198
+ first_file_name_length = s3.read("LENGTH")
199
+ s3.buffer = message_to_user[0..first_file_name_length]
200
+ message_to_user = message_to_user[(first_file_name_length + 1)..-1]
201
+ s4.buffer = message_to_user
202
+ second_file_name_length = s4.read("LENGTH")
203
+ s4.buffer = message_to_user[0..second_file_name_length]
204
+ result["ACTION_CODE"] = s2.read("ACTION_CODE")
205
+ result["FIRST_FILE_NAME"] = s3.read("VALUE") if first_file_name_length > 0
206
+ result["SECOND_FILE_NAME"] = s4.read("VALUE") if second_file_name_length > 0
207
+ result["MSG_TYPE"] = "PROXY_FILESTORE_REQUEST"
208
+ return result
209
+ end
210
+
211
+ # Table 6-7
212
+ def define_proxy_fault_handler_override_message
213
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
214
+ item = s1.append_item("CONDITION_CODE", 4, :UINT)
215
+ item.states = CONDITION_CODES
216
+ item = s1.append_item("HANDLER_CODE", 4, :UINT)
217
+ item.states = HANDLER_CODES
218
+ return s1
219
+ end
220
+
221
+ def build_proxy_fault_handler_override_message(condition_code:, handler_code:)
222
+ s1 = define_reserved_cfdp_message_header()
223
+ s1.write("MSG_ID", "cfdp")
224
+ s1.write("MSG_TYPE", "PROXY_FAULT_HANDLER_OVERRIDE")
225
+ s2 = define_proxy_fault_handler_override_message()
226
+ s2.write("CONDITION_CODE", condition_code)
227
+ s2.write("HANDLER_CODE", handler_code)
228
+ return s1.buffer(false) + s2.buffer(false)
229
+ end
230
+
231
+ def decom_proxy_fault_handler_override_message(message_to_user)
232
+ result = {}
233
+ message_to_user = message_to_user[5..-1] # Remove header
234
+ s1 = define_proxy_fault_handler_override_message()
235
+ s1.buffer = message_to_user
236
+ result["CONDITION_CODE"] = s1.read("CONDITION_CODE")
237
+ result["HANDLER_CODE"] = s1.read("HANDLER_CODE")
238
+ result["MSG_TYPE"] = "PROXY_FAULT_HANDLER_OVERRIDE"
239
+ return result
240
+ end
241
+
242
+ # Table 6-8
243
+ def define_proxy_transmission_mode_message
244
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
245
+ item = s1.append_item("SPARE", 7, :UINT)
246
+ item = s1.append_item("TRANSMISSION_MODE", 1, :UINT)
247
+ item.states = TRANSMISSION_MODES
248
+ return s1
249
+ end
250
+
251
+ def build_proxy_transmission_mode_message(transmission_mode:)
252
+ s1 = define_reserved_cfdp_message_header()
253
+ s1.write("MSG_ID", "cfdp")
254
+ s1.write("MSG_TYPE", "PROXY_TRANSMISSION_MODE")
255
+ s2 = define_proxy_transmission_mode_message()
256
+ s2.write("SPARE", 0)
257
+ s2.write("TRANSMISSION_MODE", transmission_mode)
258
+ return s1.buffer(false) + s2.buffer(false)
259
+ end
260
+
261
+ def decom_proxy_transmission_mode_message(message_to_user)
262
+ result = {}
263
+ message_to_user = message_to_user[5..-1] # Remove header
264
+ s2 = define_proxy_transmission_mode_message()
265
+ s2.buffer = message_to_user
266
+ result["TRANSMISSION_MODE"] = s2.read("TRANSMISSION_MODE")
267
+ result["MSG_TYPE"] = "PROXY_TRANSMISSION_MODE"
268
+ return result
269
+ end
270
+
271
+ # Table 6-9
272
+ def define_proxy_flow_label_message
273
+ return define_length_value()
274
+ end
275
+
276
+ def build_proxy_flow_label_message(flow_label:)
277
+ s1 = define_reserved_cfdp_message_header()
278
+ s1.write("MSG_ID", "cfdp")
279
+ s1.write("MSG_TYPE", "PROXY_FLOW_LABEL")
280
+ s2 = define_proxy_flow_label_message()
281
+ s2.write("LENGTH", flow_label.to_s.length)
282
+ s2.write("VALUE", flow_label.to_s)
283
+ return s1.buffer(false) + s2.buffer(false)
284
+ end
285
+
286
+ def decom_proxy_flow_label_message(message_to_user)
287
+ result = {}
288
+ message_to_user = message_to_user[5..-1] # Remove header
289
+ s2 = define_proxy_flow_label_message()
290
+ s2.buffer = message_to_user
291
+ length = s2.read("LENGTH")
292
+ s2.buffer = message_to_user[0..length]
293
+ result["FLOW_LABEL"] = s2.read("VALUE")
294
+ result["MSG_TYPE"] = "PROXY_FLOW_LABEL"
295
+ return result
296
+ end
297
+
298
+ # Table 6-10
299
+ def define_proxy_segmentation_control_message
300
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
301
+ item = s1.append_item("SPARE", 7, :UINT)
302
+ item = s1.append_item("SEGMENTATION_CONTROL", 1, :UINT)
303
+ item.states = SEGMENTATION_MODES
304
+ return s1
305
+ end
306
+
307
+ def build_proxy_segmentation_control_message(segmentation_control:)
308
+ s1 = define_reserved_cfdp_message_header()
309
+ s1.write("MSG_ID", "cfdp")
310
+ s1.write("MSG_TYPE", "PROXY_SEGMENTATION_CONTROL")
311
+ s2 = define_proxy_segmentation_control_message()
312
+ s2.write("SPARE", 0)
313
+ s2.write("SEGMENTATION_CONTROL", segmentation_control)
314
+ return s1.buffer(false) + s2.buffer(false)
315
+ end
316
+
317
+ def decom_proxy_segmentation_control_message(message_to_user)
318
+ result = {}
319
+ message_to_user = message_to_user[5..-1] # Remove header
320
+ s2 = define_proxy_segmentation_control_message()
321
+ s2.buffer = message_to_user
322
+ result["SEGMENTATION_CONTROL"] = s2.read("SEGMENTATION_CONTROL")
323
+ result["MSG_TYPE"] = "PROXY_SEGMENTATION_CONTROL"
324
+ return result
325
+ end
326
+
327
+ # Table 6-11
328
+ def define_proxy_closure_request_message
329
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
330
+ item = s1.append_item("SPARE", 7, :UINT)
331
+ item = s1.append_item("CLOSURE_REQUESTED", 1, :UINT)
332
+ item.states = CLOSURE_MODES
333
+ return s1
334
+ end
335
+
336
+ def build_proxy_closure_request_message(closure_requested:)
337
+ s1 = define_reserved_cfdp_message_header()
338
+ s1.write("MSG_ID", "cfdp")
339
+ s1.write("MSG_TYPE", "PROXY_CLOSURE_REQUEST")
340
+ s2 = define_proxy_closure_request_message()
341
+ s2.write("SPARE", 0)
342
+ s2.write("CLOSURE_REQUESTED", closure_requested)
343
+ return s1.buffer(false) + s2.buffer(false)
344
+ end
345
+
346
+ def decom_proxy_closure_request_message(message_to_user)
347
+ result = {}
348
+ message_to_user = message_to_user[5..-1] # Remove header
349
+ s2 = define_proxy_closure_request_message()
350
+ s2.buffer = message_to_user
351
+ result["CLOSURE_REQUESTED"] = s2.read("CLOSURE_REQUESTED")
352
+ result["MSG_TYPE"] = "PROXY_CLOSURE_REQUEST"
353
+ return result
354
+ end
355
+
356
+ # Table 6-12
357
+ def define_proxy_put_response_message
358
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
359
+ item = s1.append_item("CONDITION_CODE", 4, :UINT)
360
+ item.states = CONDITION_CODES
361
+ s1.append_item("SPARE", 1, :UINT)
362
+ item = s1.append_item("DELIVERY_CODE", 1, :UINT)
363
+ item.states = DELIVERY_CODES
364
+ item = s1.append_item("FILE_STATUS", 2, :UINT)
365
+ item.states = FILE_STATUS_CODES
366
+ return s1
367
+ end
368
+
369
+ def build_proxy_put_response_message(condition_code:, delivery_code:, file_status:)
370
+ s1 = define_reserved_cfdp_message_header()
371
+ s1.write("MSG_ID", "cfdp")
372
+ s1.write("MSG_TYPE", "PROXY_PUT_RESPONSE")
373
+ s2 = define_proxy_put_response_message()
374
+ s2.write("CONDITION_CODE", condition_code)
375
+ s2.write("DELIVERY_CODE", delivery_code)
376
+ s2.write("FILE_STATUS", file_status)
377
+ return s1.buffer(false) + s2.buffer(false)
378
+ end
379
+
380
+ def decom_proxy_put_response_message(message_to_user)
381
+ result = {}
382
+ message_to_user = message_to_user[5..-1] # Remove header
383
+ s2 = define_proxy_put_response_message()
384
+ result["CONDITION_CODE"] = s2.read("CONDITION_CODE")
385
+ result["DELIVERY_CODE"] = s2.read("DELIVERY_CODE")
386
+ result["FILE_STATUS"] = s2.read("FILE_STATUS")
387
+ result["MSG_TYPE"] = "PROXY_PUT_RESPONSE"
388
+ return result
389
+ end
390
+
391
+ # Table 6-13
392
+ def define_proxy_filestore_response_message
393
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
394
+ s1.append_item("LENGTH", 8, :UINT)
395
+ item = s1.append_item("ACTION_CODE", 4, :UINT)
396
+ item.states = ACTION_CODES
397
+ status_code_item = s1.append_item("STATUS_CODE", 4, :UINT)
398
+ return s1, status_code_item, define_length_value(), define_length_value(), define_length_value()
399
+ end
400
+
401
+ def build_proxy_filestore_response_message(action_code:, status_code:, first_file_name:, second_file_name: nil, filestore_message:)
402
+ s1 = define_reserved_cfdp_message_header()
403
+ s1.write("MSG_ID", "cfdp")
404
+ s1.write("MSG_TYPE", "PROXY_FILESTORE_RESPONSE")
405
+ s2, status_code_item, s3, s4, s5 = define_proxy_filestore_response_message()
406
+ s2.write("ACTION_CODE", action_code)
407
+ CfdpPdu.add_status_code_states(action_code: action_code, status_code_item: status_code_item)
408
+ s2.write("STATUS_CODE", status_code)
409
+ s3.write("LENGTH", first_file_name.to_s.length)
410
+ s3.write("VALUE", first_file_name.to_s)
411
+ s4.write("LENGTH", second_file_name.to_s.length)
412
+ s4.write("VALUE", second_file_name.to_s)
413
+ s5.write("LENGTH", filestore_message.to_s.length)
414
+ s5.write("VALUE", filestore_message.to_s)
415
+ return s1.buffer(false) + s2.buffer(false) + s3.buffer(false) + s4.buffer(false) + s5.buffer(false)
416
+ end
417
+
418
+ def decom_proxy_filestore_response_message(message_to_user)
419
+ result = {}
420
+ message_to_user = message_to_user[5..-1] # Remove header
421
+ s2, status_code_item, s3, s4, s5 = define_proxy_filestore_response_message()
422
+ s2.buffer = message_to_user[0..(s2.defined_length - 1)]
423
+ result["ACTION_CODE"] = s2.read("ACTION_CODE")
424
+ result["STATUS_CODE"] = s2.read("STATUS_CODE")
425
+ message_to_user = message_to_user[s2.defined_length..-1]
426
+ s3.buffer = message_to_user
427
+ length = s3.read("LENGTH")
428
+ s3.buffer = s3.buffer(false)[0..length]
429
+ first_file_name = s3.read("VALUE")
430
+ result["FIRST_FILE_NAME"] = first_file_name if first_file_name.length > 0
431
+ message_to_user = message_to_user[(length + 1)..-1]
432
+ s4.buffer = message_to_user
433
+ length = s4.read("LENGTH")
434
+ s4.buffer = s4.buffer(false)[0..length]
435
+ second_file_name = s4.read("VALUE")
436
+ result["SECOND_FILE_NAME"] = second_file_name if second_file_name.length > 0
437
+ message_to_user = message_to_user[(length + 1)..-1]
438
+ s5.buffer = message_to_user
439
+ length = s5.read("LENGTH")
440
+ s5.buffer = s5.buffer(false)[0..length]
441
+ filestore_message = s5.read("VALUE")
442
+ result["FILESTORE_MESSAGE"] = filestore_message if filestore_message.length > 0
443
+ result["MSG_TYPE"] = "PROXY_FILESTORE_RESPONSE"
444
+ return result
445
+ end
446
+
447
+ # 6.2.6.2
448
+ def build_proxy_put_cancel_message
449
+ s1 = define_reserved_cfdp_message_header()
450
+ s1.write("MSG_ID", "cfdp")
451
+ s1.write("MSG_TYPE", "PROXY_PUT_CANCEL")
452
+ return s1.buffer(false)
453
+ end
454
+
455
+ def decom_proxy_put_cancel_message(message_to_user)
456
+ result = {}
457
+ result["MSG_TYPE"] = "PROXY_PUT_CANCEL"
458
+ return result
459
+ end
460
+
461
+ # Table 6-15
462
+ def define_directory_listing_request_message
463
+ return define_length_value(), define_length_value()
464
+ end
465
+
466
+ def build_directory_listing_request_message(directory_name:, directory_file_name:)
467
+ s1 = define_reserved_cfdp_message_header()
468
+ s1.write("MSG_ID", "cfdp")
469
+ s1.write("MSG_TYPE", "DIRECTORY_LISTING_REQUEST")
470
+ s2, s3 = define_directory_listing_request_message()
471
+ s2.write("LENGTH", directory_name.to_s.length)
472
+ s2.write("VALUE", directory_name.to_s)
473
+ s3.write("LENGTH", directory_file_name.to_s.length)
474
+ s3.write("VALUE", directory_file_name.to_s)
475
+ return s1.buffer(false) + s2.buffer(false) + s3.buffer(false)
476
+ end
477
+
478
+ def decom_directory_listing_request_message(message_to_user)
479
+ result = {}
480
+ message_to_user = message_to_user[5..-1] # Remove header
481
+ s2, s3 = define_directory_listing_request_message()
482
+ s2.buffer = message_to_user
483
+ length = s2.read("LENGTH")
484
+ s2.buffer = s2.buffer(false)[0..length]
485
+ directory_name = s2.read("VALUE")
486
+ result["DIRECTORY_NAME"] = directory_name if directory_name.length > 0
487
+ message_to_user = message_to_user[(length + 1)..-1]
488
+ s3.buffer = message_to_user
489
+ length = s3.read("LENGTH")
490
+ s3.buffer = s3.buffer(false)[0..length]
491
+ directory_file_name = s3.read("VALUE")
492
+ result["DIRECTORY_FILE_NAME"] = directory_file_name if directory_file_name.length > 0
493
+ result["MSG_TYPE"] = "DIRECTORY_LISTING_REQUEST"
494
+ return result
495
+ end
496
+
497
+ # Table 6-16
498
+ def define_directory_listing_response_message
499
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
500
+ item = s1.append_item("RESPONSE_CODE", 1, :UINT)
501
+ item.states = { "SUCCESSFUL" => 0, "UNSUCCESSFUL" => 1 }
502
+ s1.append_item("SPARE", 7, :UINT)
503
+ return s1, define_length_value(), define_length_value()
504
+ end
505
+
506
+ def build_directory_listing_response_message(response_code:, directory_name:, directory_file_name:)
507
+ s1 = define_reserved_cfdp_message_header()
508
+ s1.write("MSG_ID", "cfdp")
509
+ s1.write("MSG_TYPE", "DIRECTORY_LISTING_RESPONSE")
510
+ fixed, s2, s3 = define_directory_listing_response_message()
511
+ fixed.write("RESPONSE_CODE", response_code)
512
+ fixed.write("SPARE", 0)
513
+ s2.write("LENGTH", directory_name.to_s.length)
514
+ s2.write("VALUE", directory_name.to_s)
515
+ s3.write("LENGTH", directory_file_name.to_s.length)
516
+ s3.write("VALUE", directory_file_name.to_s)
517
+ return s1.buffer(false) + fixed.buffer(false) + s2.buffer(false) + s3.buffer(false)
518
+ end
519
+
520
+ def decom_directory_listing_response_message(message_to_user)
521
+ result = {}
522
+ message_to_user = message_to_user[5..-1] # Remove header
523
+ fixed, s2, s3 = define_directory_listing_response_message()
524
+ fixed.buffer = message_to_user[0..(fixed.defined_length - 1)]
525
+ result["RESPONSE_CODE"] = fixed.read("RESPONSE_CODE")
526
+ message_to_user = message_to_user[fixed.defined_length..-1]
527
+ s2.buffer = message_to_user
528
+ length = s2.read("LENGTH")
529
+ s2.buffer = s2.buffer(false)[0..length]
530
+ directory_name = s2.read("VALUE")
531
+ result["DIRECTORY_NAME"] = directory_name if directory_name.length > 0
532
+ message_to_user = message_to_user[(length + 1)..-1]
533
+ s3.buffer = message_to_user
534
+ length = s3.read("LENGTH")
535
+ s3.buffer = s3.buffer(false)[0..length]
536
+ directory_file_name = s3.read("VALUE")
537
+ result["DIRECTORY_FILE_NAME"] = directory_file_name if directory_file_name.length > 0
538
+ result["MSG_TYPE"] = "DIRECTORY_LISTING_RESPONSE"
539
+ return result
540
+ end
541
+
542
+ # Table 6-18
543
+ def define_remote_status_report_request_message_unique
544
+ return define_length_value()
545
+ end
546
+
547
+ def build_remote_status_report_request_message(source_entity_id:, sequence_number:, report_file_name:)
548
+ s1 = define_reserved_cfdp_message_header()
549
+ s1.write("MSG_ID", "cfdp")
550
+ s1.write("MSG_TYPE", "REMOTE_STATUS_REPORT_REQUEST")
551
+ data = build_originating_transaction_id_message(source_entity_id: source_entity_id, sequence_number: sequence_number)
552
+ s2 = define_remote_status_report_request_message_unique()
553
+ s2.write("LENGTH", report_file_name.to_s.length)
554
+ s2.write("VALUE", report_file_name.to_s)
555
+ return s1.buffer(false) + data + s2.buffer(false)
556
+ end
557
+
558
+ def decom_remote_status_report_request_message(message_to_user)
559
+ message_to_user = message_to_user[5..-1] # Remove header
560
+ result, message_to_user = decom_originating_transaction_id_message(message_to_user)
561
+ s2 = define_remote_status_report_request_message_unique()
562
+ s2.buffer = message_to_user
563
+ length = s2.read("LENGTH")
564
+ s2.buffer = s2.buffer(false)[0..length]
565
+ report_file_name = s2.read("VALUE")
566
+ result["REPORT_FILE_NAME"] = report_file_name if report_file_name.length > 0
567
+ result["MSG_TYPE"] = "REMOTE_STATUS_REPORT_REQUEST"
568
+ return result
569
+ end
570
+
571
+ # Table 6-19
572
+ def define_remote_status_report_response_message_unique
573
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
574
+ item = s1.append_item("TRANSACTION_STATUS", 2, :UINT)
575
+ item.states = TRANSACTION_STATUS_CODES
576
+ s1.append_item("SPARE", 5, :UINT)
577
+ item = s1.append_item("RESPONSE_CODE", 1, :UINT)
578
+ item.states = { "SUCCESSFUL" => 0, "UNSUCCESSFUL" => 1 }
579
+ return s1
580
+ end
581
+
582
+ def build_remote_status_report_response_message(source_entity_id:, sequence_number:, transaction_status:, response_code:)
583
+ s1 = define_reserved_cfdp_message_header()
584
+ s1.write("MSG_ID", "cfdp")
585
+ s1.write("MSG_TYPE", "REMOTE_STATUS_REPORT_RESPONSE")
586
+ s2 = define_remote_status_report_response_message_unique()
587
+ s2.write("TRANSACTION_STATUS", transaction_status)
588
+ s2.write("SPARE", 0)
589
+ s2.write("RESPONSE_CODE", response_code)
590
+ data = build_originating_transaction_id_message(source_entity_id: source_entity_id, sequence_number: sequence_number)
591
+ return s1.buffer(false) + s2.buffer(false) + data
592
+ end
593
+
594
+ def decom_remote_status_report_response_message(message_to_user)
595
+ message_to_user = message_to_user[5..-1] # Remove header
596
+ s2 = define_remote_status_report_response_message_unique()
597
+ s2.buffer = message_to_user[0..(s2.defined_length - 1)]
598
+ message_to_user = message_to_user[s2.defined_length..-1]
599
+ result, message_to_user = decom_originating_transaction_id_message(message_to_user)
600
+ result["TRANSACTION_STATUS"] = s2.read("TRANSACTION_STATUS")
601
+ result["RESPONSE_CODE"] = s2.read("RESPONSE_CODE")
602
+ result["MSG_TYPE"] = "REMOTE_STATUS_REPORT_RESPONSE"
603
+ return result
604
+ end
605
+
606
+ # Table 6-21
607
+ def build_remote_suspend_request_message(source_entity_id:, sequence_number:)
608
+ s1 = define_reserved_cfdp_message_header()
609
+ s1.write("MSG_ID", "cfdp")
610
+ s1.write("MSG_TYPE", "REMOTE_SUSPEND_REQUEST")
611
+ data = build_originating_transaction_id_message(source_entity_id: source_entity_id, sequence_number: sequence_number)
612
+ return s1.buffer(false) + data
613
+ end
614
+
615
+ def decom_remote_suspend_request_message(message_to_user)
616
+ message_to_user = message_to_user[5..-1] # Remove header
617
+ result, message_to_user = decom_originating_transaction_id_message(message_to_user)
618
+ result["MSG_TYPE"] = "REMOTE_SUSPEND_REQUEST"
619
+ return result
620
+ end
621
+
622
+ # Table 6-22
623
+ def define_remote_suspend_response_message_unique
624
+ s1 = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
625
+ item = s1.append_item("SUSPENSION_INDICATOR", 1, :UINT)
626
+ item.states = { "NOT_SUSPENDED" => 0, "SUSPENDED" => 1 }
627
+ item = s1.append_item("TRANSACTION_STATUS", 2, :UINT)
628
+ item.states = TRANSACTION_STATUS_CODES
629
+ s1.append_item("SPARE", 5, :UINT)
630
+ return s1
631
+ end
632
+
633
+ def build_remote_suspend_response_message(source_entity_id:, sequence_number:, transaction_status:, suspension_indicator:)
634
+ s1 = define_reserved_cfdp_message_header()
635
+ s1.write("MSG_ID", "cfdp")
636
+ s1.write("MSG_TYPE", "REMOTE_SUSPEND_RESPONSE")
637
+ s2 = define_remote_suspend_response_message_unique()
638
+ s2.write("SUSPENSION_INDICATOR", suspension_indicator)
639
+ s2.write("TRANSACTION_STATUS", transaction_status)
640
+ s2.write("SPARE", 0)
641
+ data = build_originating_transaction_id_message(source_entity_id: source_entity_id, sequence_number: sequence_number)
642
+ return s1.buffer(false) + s2.buffer(false) + data
643
+ end
644
+
645
+ def decom_remote_suspend_response_message(message_to_user)
646
+ message_to_user = message_to_user[5..-1] # Remove header
647
+ s2 = define_remote_suspend_response_message_unique()
648
+ s2.buffer = message_to_user[0..(s2.defined_length - 1)]
649
+ message_to_user = message_to_user[s2.defined_length..-1]
650
+ result, message_to_user = decom_originating_transaction_id_message(message_to_user)
651
+ result["SUSPENSION_INDICATOR"] = s2.read("SUSPENSION_INDICATOR")
652
+ result["TRANSACTION_STATUS"] = s2.read("TRANSACTION_STATUS")
653
+ result["MSG_TYPE"] = "REMOTE_SUSPEND_RESPONSE"
654
+ return result
655
+ end
656
+
657
+ # Table 6-24
658
+ def build_remote_resume_request_message(source_entity_id:, sequence_number:)
659
+ s1 = define_reserved_cfdp_message_header()
660
+ s1.write("MSG_ID", "cfdp")
661
+ s1.write("MSG_TYPE", "REMOTE_RESUME_REQUEST")
662
+ data = build_originating_transaction_id_message(source_entity_id: source_entity_id, sequence_number: sequence_number)
663
+ return s1.buffer(false) + data
664
+ end
665
+
666
+ def decom_remote_resume_request_message(message_to_user)
667
+ message_to_user = message_to_user[5..-1] # Remove header
668
+ result, message_to_user = decom_originating_transaction_id_message(message_to_user)
669
+ result["MSG_TYPE"] = "REMOTE_RESUME_REQUEST"
670
+ return result
671
+ end
672
+
673
+ # Table 6-25
674
+ def build_remote_resume_response_message(source_entity_id:, sequence_number:, transaction_status:, suspension_indicator:)
675
+ s1 = define_reserved_cfdp_message_header()
676
+ s1.write("MSG_ID", "cfdp")
677
+ s1.write("MSG_TYPE", "REMOTE_RESUME_RESPONSE")
678
+ s2 = define_remote_suspend_response_message_unique()
679
+ s2.write("SUSPENSION_INDICATOR", suspension_indicator)
680
+ s2.write("TRANSACTION_STATUS", transaction_status)
681
+ s2.write("SPARE", 0)
682
+ data = build_originating_transaction_id_message(source_entity_id: source_entity_id, sequence_number: sequence_number)
683
+ return s1.buffer(false) + s2.buffer(false) + data
684
+ end
685
+
686
+ def decom_remote_resume_response_message(message_to_user)
687
+ result = decom_remote_suspend_response_message(message_to_user)
688
+ result["MSG_TYPE"] = "REMOTE_RESUME_RESPONSE"
689
+ return result
690
+ end
691
+
692
+ def decom_message_to_user(message_to_user)
693
+ s1 = define_reserved_cfdp_message_header()
694
+ if message_to_user.length >= 5 # Minimum size
695
+ s1.buffer = message_to_user[0..(s1.defined_length - 1)]
696
+ if s1.read("MSG_ID") == 'cfdp'
697
+ case s1.read("MSG_TYPE")
698
+ when "PROXY_PUT_REQUEST"
699
+ return decom_proxy_put_request_message(message_to_user)
700
+ when "PROXY_MESSAGE_TO_USER"
701
+ return decom_proxy_message_to_user_message(message_to_user)
702
+ when "PROXY_FILESTORE_REQUEST"
703
+ return decom_proxy_filestore_request_message(message_to_user)
704
+ when "PROXY_FAULT_HANDLER_OVERRIDE"
705
+ return decom_proxy_fault_handler_override_message(message_to_user)
706
+ when "PROXY_TRANSMISSION_MODE"
707
+ return decom_proxy_transmission_mode_message(message_to_user)
708
+ when "PROXY_FLOW_LABEL"
709
+ return decom_proxy_flow_label_message(message_to_user)
710
+ when "PROXY_SEGMENTATION_CONTROL"
711
+ return decom_proxy_segmentation_control_message(message_to_user)
712
+ when "PROXY_PUT_RESPONSE"
713
+ return decom_proxy_put_response_message(message_to_user)
714
+ when "PROXY_FILESTORE_RESPONSE"
715
+ return decom_proxy_filestore_response_message(message_to_user)
716
+ when "PROXY_PUT_CANCEL"
717
+ return decom_proxy_put_cancel_message(message_to_user)
718
+ when "ORIGINATING_TRANSACTION_ID"
719
+ result, message_to_user = decom_originating_transaction_id_message(message_to_user)
720
+ return result
721
+ when "PROXY_CLOSURE_REQUEST"
722
+ return decom_proxy_closure_request_message(message_to_user)
723
+ when "DIRECTORY_LISTING_REQUEST"
724
+ return decom_directory_listing_request_message(message_to_user)
725
+ when "DIRECTORY_LISTING_RESPONSE"
726
+ return decom_directory_listing_response_message(message_to_user)
727
+ when "REMOTE_STATUS_REPORT_REQUEST"
728
+ return decom_remote_status_report_request_message(message_to_user)
729
+ when "REMOTE_STATUS_REPORT_RESPONSE"
730
+ return decom_remote_status_report_response_message(message_to_user)
731
+ when "REMOTE_SUSPEND_REQUEST"
732
+ return decom_remote_suspend_request_message(message_to_user)
733
+ when "REMOTE_SUSPEND_RESPONSE"
734
+ return decom_remote_suspend_response_message(message_to_user)
735
+ when "REMOTE_RESUME_REQUEST"
736
+ return decom_remote_resume_request_message(message_to_user)
737
+ when "REMOTE_RESUME_RESPONSE"
738
+ return decom_remote_resume_response_message(message_to_user)
739
+ else
740
+ return {"MSG_TYPE" => "UNKNOWN", "MSG_TYPE_VALUE" => s1.read("MSG_TYPE"), "DATA" => message_to_user}
741
+ end
742
+ else
743
+ return {"MSG_TYPE" => "UNKNOWN", "DATA" => message_to_user}
744
+ end
745
+ else
746
+ return {"MSG_TYPE" => "UNKNOWN", "DATA" => message_to_user}
747
+ end
748
+ end
749
+ end