openc3-cosmos-cfdp 2.0.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +18 -0
  3. data/README.md +103 -55
  4. data/Rakefile +12 -0
  5. data/lib/cfdp.py +564 -0
  6. data/lib/cfdp.rb +68 -14
  7. data/lib/cfdp_api.py +302 -0
  8. data/lib/cfdp_api.rb +55 -9
  9. data/microservices/CFDP/Gemfile +18 -4
  10. data/microservices/CFDP/Gemfile.dev +22 -8
  11. data/microservices/CFDP/Gemfile.prod +18 -4
  12. data/microservices/CFDP/Rakefile +13 -2
  13. data/microservices/CFDP/app/controllers/application_controller.rb +2 -2
  14. data/microservices/CFDP/app/controllers/cfdp_controller.rb +62 -31
  15. data/microservices/CFDP/app/models/cfdp_checksum.rb +12 -4
  16. data/microservices/CFDP/app/models/cfdp_crc_checksum.rb +10 -2
  17. data/microservices/CFDP/app/models/cfdp_mib.rb +173 -32
  18. data/microservices/CFDP/app/models/cfdp_null_checksum.rb +10 -2
  19. data/microservices/CFDP/app/models/cfdp_pdu.rb +96 -20
  20. data/microservices/CFDP/app/models/cfdp_receive_transaction.rb +139 -11
  21. data/microservices/CFDP/app/models/cfdp_source_transaction.rb +433 -93
  22. data/microservices/CFDP/app/models/cfdp_topic.rb +2 -2
  23. data/microservices/CFDP/app/models/cfdp_transaction.rb +174 -4
  24. data/microservices/CFDP/app/models/cfdp_user.rb +216 -73
  25. data/microservices/CFDP/config/routes.rb +1 -0
  26. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_ack.rb +7 -6
  27. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_eof.rb +1 -2
  28. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_file_data.rb +2 -25
  29. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_finished.rb +8 -7
  30. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_keep_alive.rb +7 -6
  31. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_metadata.rb +1 -2
  32. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_nak.rb +7 -6
  33. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_prompt.rb +1 -2
  34. data/microservices/CFDP/spec/controllers/cfdp_controller_spec.rb +226 -1
  35. data/microservices/CFDP/spec/models/cfdp_checksum_spec.rb +239 -0
  36. data/microservices/CFDP/spec/models/cfdp_crc_checksum_spec.rb +16 -13
  37. data/microservices/CFDP/spec/models/cfdp_mib_spec.rb +880 -138
  38. data/microservices/CFDP/spec/models/cfdp_null_checksum_spec.rb +111 -0
  39. data/microservices/CFDP/spec/models/cfdp_pdu_file_data_spec.rb +48 -0
  40. data/microservices/CFDP/spec/models/cfdp_pdu_nak_spec.rb +2 -2
  41. data/microservices/CFDP/spec/models/cfdp_pdu_spec.rb +129 -0
  42. data/microservices/CFDP/spec/models/cfdp_receive_transaction_spec.rb +109 -10
  43. data/microservices/CFDP/spec/models/cfdp_source_transaction_spec.rb +357 -0
  44. data/microservices/CFDP/spec/models/cfdp_transaction_spec.rb +282 -5
  45. data/microservices/CFDP/spec/models/cfdp_user_spec.rb +462 -20
  46. data/microservices/CFDP/spec/requests/cfdp_spec.rb +92 -43
  47. data/microservices/CFDP/spec/spec_helper.rb +34 -3
  48. data/plugin.txt +55 -4
  49. data/public/store_img.png +0 -0
  50. data/pyproject.toml +70 -0
  51. data/targets/CFDPTEST/procedures/cfdp_test_suite.py +179 -0
  52. data/targets/CFDPTEST/procedures/cfdp_test_suite.rb +2 -2
  53. data/targets/CFDPTEST/procedures/interrupt_test.rb +31 -0
  54. metadata +25 -12
  55. data/LICENSE.txt +0 -18
data/lib/cfdp.py ADDED
@@ -0,0 +1,564 @@
1
+ # Copyright 2026 OpenC3, Inc.
2
+ # All Rights Reserved.
3
+ #
4
+ # Licensed for Evaluation and Educational Use
5
+ #
6
+ # This file may only be used commercially under the terms of a commercial license
7
+ # purchased from OpenC3, Inc.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
+ #
13
+ # The development of this software was funded in-whole or in-part by MethaneSAT LLC.
14
+
15
+ import time
16
+
17
+ from cfdp_api import CfdpApi
18
+ from openc3.environment import OPENC3_SCOPE
19
+
20
+
21
+ def _get_wait():
22
+ # Available when running inside ScriptRunner. Returns the actual time waited;
23
+ # a value less than the requested time means the user hit Go. Imported lazily
24
+ # (mirrors the Ruby `defined? wait`) so simply importing cfdp does not pull in
25
+ # the full openc3.script stack.
26
+ try:
27
+ from openc3.script import wait
28
+
29
+ return wait
30
+ except Exception:
31
+ return None
32
+
33
+
34
+ def cfdp_put(
35
+ destination_entity_id,
36
+ source_file_name=None,
37
+ destination_file_name=None,
38
+ closure_requested=None,
39
+ transmission_mode=None,
40
+ filestore_requests=None,
41
+ fault_handler_overrides=None,
42
+ flow_label=None,
43
+ segmentation_control="NOT_PRESERVED",
44
+ messages_to_user=None,
45
+ remote_entity_id=None, # Used to indicate proxy put
46
+ timeout=600,
47
+ api_timeout=5,
48
+ microservice_name="CFDP",
49
+ prefix="/cfdp",
50
+ schema="http",
51
+ hostname=None,
52
+ port=2905,
53
+ url=None,
54
+ scope=OPENC3_SCOPE,
55
+ ):
56
+ api = CfdpApi(
57
+ timeout=api_timeout,
58
+ microservice_name=microservice_name,
59
+ prefix=prefix,
60
+ schema=schema,
61
+ hostname=hostname,
62
+ port=port,
63
+ url=url,
64
+ scope=scope,
65
+ )
66
+ continuation = api.subscribe(scope=scope) if timeout else None
67
+ transaction_id = api.put(
68
+ destination_entity_id=destination_entity_id,
69
+ source_file_name=source_file_name,
70
+ destination_file_name=destination_file_name,
71
+ transmission_mode=transmission_mode,
72
+ closure_requested=closure_requested,
73
+ filestore_requests=filestore_requests,
74
+ fault_handler_overrides=fault_handler_overrides,
75
+ flow_label=flow_label,
76
+ segmentation_control=segmentation_control,
77
+ messages_to_user=messages_to_user,
78
+ remote_entity_id=remote_entity_id, # Used to indicate proxy put
79
+ scope=scope,
80
+ )
81
+ if not timeout:
82
+ return transaction_id
83
+ indication_type = "Proxy-Put-Response" if remote_entity_id else "Transaction-Finished"
84
+ indication = cfdp_wait_for_indication(
85
+ api=api,
86
+ transaction_id=transaction_id,
87
+ indication_type=indication_type,
88
+ continuation=continuation,
89
+ timeout=timeout,
90
+ scope=scope,
91
+ )
92
+ return transaction_id, indication
93
+
94
+
95
+ def cfdp_put_dir(
96
+ destination_entity_id,
97
+ source_directory_name,
98
+ closure_requested=None,
99
+ transmission_mode=None,
100
+ filestore_requests=None,
101
+ fault_handler_overrides=None,
102
+ flow_label=None,
103
+ segmentation_control="NOT_PRESERVED",
104
+ messages_to_user=None,
105
+ remote_entity_id=None, # Used to indicate proxy put
106
+ timeout=600,
107
+ api_timeout=5,
108
+ microservice_name="CFDP",
109
+ prefix="/cfdp",
110
+ schema="http",
111
+ hostname=None,
112
+ port=2905,
113
+ url=None,
114
+ scope=OPENC3_SCOPE,
115
+ ):
116
+ api = CfdpApi(
117
+ timeout=api_timeout,
118
+ microservice_name=microservice_name,
119
+ prefix=prefix,
120
+ schema=schema,
121
+ hostname=hostname,
122
+ port=port,
123
+ url=url,
124
+ scope=scope,
125
+ )
126
+ continuation = api.subscribe(scope=scope) if timeout else None
127
+ transaction_ids = api.put_dir(
128
+ destination_entity_id=destination_entity_id,
129
+ source_directory_name=source_directory_name,
130
+ transmission_mode=transmission_mode,
131
+ closure_requested=closure_requested,
132
+ filestore_requests=filestore_requests,
133
+ fault_handler_overrides=fault_handler_overrides,
134
+ flow_label=flow_label,
135
+ segmentation_control=segmentation_control,
136
+ messages_to_user=messages_to_user,
137
+ remote_entity_id=remote_entity_id, # Used to indicate proxy put
138
+ scope=scope,
139
+ )
140
+ if not timeout:
141
+ return transaction_ids
142
+ indications = []
143
+ for transaction_id in transaction_ids:
144
+ indication_type = "Proxy-Put-Response" if remote_entity_id else "Transaction-Finished"
145
+ indication = cfdp_wait_for_indication(
146
+ api=api,
147
+ transaction_id=transaction_id,
148
+ indication_type=indication_type,
149
+ continuation=continuation,
150
+ timeout=timeout,
151
+ scope=scope,
152
+ )
153
+ indications.append([transaction_id, indication])
154
+ return transaction_ids, indications
155
+
156
+
157
+ def cfdp_cancel(
158
+ transaction_id,
159
+ remote_entity_id=None,
160
+ timeout=600,
161
+ api_timeout=5,
162
+ microservice_name="CFDP",
163
+ prefix="/cfdp",
164
+ schema="http",
165
+ hostname=None,
166
+ port=2905,
167
+ url=None,
168
+ scope=OPENC3_SCOPE,
169
+ ):
170
+ api = CfdpApi(
171
+ timeout=api_timeout,
172
+ microservice_name=microservice_name,
173
+ prefix=prefix,
174
+ schema=schema,
175
+ hostname=hostname,
176
+ port=port,
177
+ url=url,
178
+ scope=scope,
179
+ )
180
+ continuation = api.subscribe(scope=scope) if timeout else None
181
+ transaction_id = api.cancel(
182
+ transaction_id=transaction_id, remote_entity_id=remote_entity_id, scope=scope
183
+ )
184
+ indication = None
185
+ if transaction_id:
186
+ if timeout:
187
+ indication = cfdp_wait_for_indication(
188
+ api=api,
189
+ transaction_id=transaction_id,
190
+ indication_type="Transaction-Finished",
191
+ continuation=continuation,
192
+ timeout=timeout,
193
+ scope=scope,
194
+ )
195
+ if indication is None and remote_entity_id and timeout:
196
+ indication = cfdp_wait_for_indication(
197
+ api=api,
198
+ transaction_id=transaction_id,
199
+ indication_type="Proxy-Put-Response",
200
+ continuation=continuation,
201
+ timeout=timeout,
202
+ scope=scope,
203
+ )
204
+ return indication
205
+
206
+
207
+ def cfdp_suspend(
208
+ transaction_id,
209
+ remote_entity_id=None,
210
+ timeout=600,
211
+ api_timeout=5,
212
+ microservice_name="CFDP",
213
+ prefix="/cfdp",
214
+ schema="http",
215
+ hostname=None,
216
+ port=2905,
217
+ url=None,
218
+ scope=OPENC3_SCOPE,
219
+ ):
220
+ api = CfdpApi(
221
+ timeout=api_timeout,
222
+ microservice_name=microservice_name,
223
+ prefix=prefix,
224
+ schema=schema,
225
+ hostname=hostname,
226
+ port=port,
227
+ url=url,
228
+ scope=scope,
229
+ )
230
+ continuation = api.subscribe(scope=scope) if timeout else None
231
+ transaction_id = api.suspend(
232
+ transaction_id=transaction_id, remote_entity_id=remote_entity_id, scope=scope
233
+ )
234
+ indication = None
235
+ if transaction_id:
236
+ if not remote_entity_id and timeout:
237
+ indication = cfdp_wait_for_indication(
238
+ api=api,
239
+ transaction_id=transaction_id,
240
+ indication_type="Suspended",
241
+ continuation=continuation,
242
+ timeout=timeout,
243
+ scope=scope,
244
+ )
245
+ if indication is None and remote_entity_id and timeout:
246
+ indication = cfdp_wait_for_indication(
247
+ api=api,
248
+ transaction_id=transaction_id,
249
+ indication_type="Remote-Suspend-Response",
250
+ continuation=continuation,
251
+ timeout=timeout,
252
+ scope=scope,
253
+ )
254
+ return indication
255
+
256
+
257
+ def cfdp_resume(
258
+ transaction_id,
259
+ remote_entity_id=None,
260
+ timeout=600,
261
+ api_timeout=5,
262
+ microservice_name="CFDP",
263
+ prefix="/cfdp",
264
+ schema="http",
265
+ hostname=None,
266
+ port=2905,
267
+ url=None,
268
+ scope=OPENC3_SCOPE,
269
+ ):
270
+ api = CfdpApi(
271
+ timeout=api_timeout,
272
+ microservice_name=microservice_name,
273
+ prefix=prefix,
274
+ schema=schema,
275
+ hostname=hostname,
276
+ port=port,
277
+ url=url,
278
+ scope=scope,
279
+ )
280
+ continuation = api.subscribe(scope=scope) if timeout else None
281
+ transaction_id = api.resume(
282
+ transaction_id=transaction_id, remote_entity_id=remote_entity_id, scope=scope
283
+ )
284
+ indication = None
285
+ if transaction_id:
286
+ if not remote_entity_id and timeout:
287
+ indication = cfdp_wait_for_indication(
288
+ api=api,
289
+ transaction_id=transaction_id,
290
+ indication_type="Resumed",
291
+ continuation=continuation,
292
+ timeout=timeout,
293
+ scope=scope,
294
+ )
295
+ if indication is None and remote_entity_id and timeout:
296
+ indication = cfdp_wait_for_indication(
297
+ api=api,
298
+ transaction_id=transaction_id,
299
+ indication_type="Remote-Resume-Response",
300
+ continuation=continuation,
301
+ timeout=timeout,
302
+ scope=scope,
303
+ )
304
+ return indication
305
+
306
+
307
+ def cfdp_report(
308
+ transaction_id,
309
+ remote_entity_id=None,
310
+ report_file_name=None,
311
+ timeout=600,
312
+ api_timeout=5,
313
+ microservice_name="CFDP",
314
+ prefix="/cfdp",
315
+ schema="http",
316
+ hostname=None,
317
+ port=2905,
318
+ url=None,
319
+ scope=OPENC3_SCOPE,
320
+ ):
321
+ api = CfdpApi(
322
+ timeout=api_timeout,
323
+ microservice_name=microservice_name,
324
+ prefix=prefix,
325
+ schema=schema,
326
+ hostname=hostname,
327
+ port=port,
328
+ url=url,
329
+ scope=scope,
330
+ )
331
+ continuation = api.subscribe(scope=scope) if timeout else None
332
+ transaction_id = api.report(
333
+ transaction_id=transaction_id,
334
+ remote_entity_id=remote_entity_id,
335
+ report_file_name=report_file_name,
336
+ scope=scope,
337
+ )
338
+ indication = None
339
+ if transaction_id:
340
+ if not remote_entity_id and timeout:
341
+ indication = cfdp_wait_for_indication(
342
+ api=api,
343
+ transaction_id=transaction_id,
344
+ indication_type="Report",
345
+ continuation=continuation,
346
+ timeout=timeout,
347
+ scope=scope,
348
+ )
349
+ if indication is None and remote_entity_id and timeout:
350
+ indication = cfdp_wait_for_indication(
351
+ api=api,
352
+ transaction_id=transaction_id,
353
+ indication_type="Remote-Report-Response",
354
+ continuation=continuation,
355
+ timeout=timeout,
356
+ scope=scope,
357
+ )
358
+ return indication
359
+
360
+
361
+ def cfdp_subscribe(
362
+ api_timeout=5,
363
+ microservice_name="CFDP",
364
+ prefix="/cfdp",
365
+ schema="http",
366
+ hostname=None,
367
+ port=2905,
368
+ url=None,
369
+ scope=OPENC3_SCOPE,
370
+ ):
371
+ api = CfdpApi(
372
+ timeout=api_timeout,
373
+ microservice_name=microservice_name,
374
+ prefix=prefix,
375
+ schema=schema,
376
+ hostname=hostname,
377
+ port=port,
378
+ url=url,
379
+ scope=scope,
380
+ )
381
+ return api.subscribe(scope=scope)
382
+
383
+
384
+ def cfdp_indications(
385
+ transaction_id=None,
386
+ indication_type=None,
387
+ continuation=None,
388
+ include_continuation=True,
389
+ timeout=None,
390
+ api_timeout=5,
391
+ limit=100,
392
+ microservice_name="CFDP",
393
+ prefix="/cfdp",
394
+ schema="http",
395
+ hostname=None,
396
+ port=2905,
397
+ url=None,
398
+ scope=OPENC3_SCOPE,
399
+ ):
400
+ api = CfdpApi(
401
+ timeout=api_timeout,
402
+ microservice_name=microservice_name,
403
+ prefix=prefix,
404
+ schema=schema,
405
+ hostname=hostname,
406
+ port=port,
407
+ url=url,
408
+ scope=scope,
409
+ )
410
+ return cfdp_wait_for_indication(
411
+ api=api,
412
+ transaction_id=transaction_id,
413
+ indication_type=indication_type,
414
+ continuation=continuation,
415
+ include_continuation=include_continuation,
416
+ timeout=timeout,
417
+ limit=limit,
418
+ scope=scope,
419
+ )
420
+
421
+
422
+ def cfdp_directory_listing(
423
+ remote_entity_id,
424
+ directory_name,
425
+ directory_file_name,
426
+ timeout=600,
427
+ api_timeout=5,
428
+ microservice_name="CFDP",
429
+ prefix="/cfdp",
430
+ schema="http",
431
+ hostname=None,
432
+ port=2905,
433
+ url=None,
434
+ scope=OPENC3_SCOPE,
435
+ ):
436
+ api = CfdpApi(
437
+ timeout=api_timeout,
438
+ microservice_name=microservice_name,
439
+ prefix=prefix,
440
+ schema=schema,
441
+ hostname=hostname,
442
+ port=port,
443
+ url=url,
444
+ scope=scope,
445
+ )
446
+ continuation = api.subscribe(scope=scope) if timeout else None
447
+ transaction_id = api.directory_listing(
448
+ remote_entity_id=remote_entity_id,
449
+ directory_name=directory_name,
450
+ directory_file_name=directory_file_name,
451
+ scope=scope,
452
+ )
453
+ indications = []
454
+ if transaction_id:
455
+ if timeout:
456
+ indications.append(
457
+ cfdp_wait_for_indication(
458
+ api=api,
459
+ transaction_id=transaction_id,
460
+ indication_type="Transaction-Finished",
461
+ continuation=continuation,
462
+ timeout=timeout,
463
+ scope=scope,
464
+ )
465
+ )
466
+ if timeout:
467
+ indications.append(
468
+ cfdp_wait_for_indication(
469
+ api=api,
470
+ transaction_id=transaction_id,
471
+ indication_type="Directory-Listing-Response",
472
+ continuation=continuation,
473
+ timeout=timeout,
474
+ scope=scope,
475
+ )
476
+ )
477
+ return [indication for indication in indications if indication is not None]
478
+
479
+
480
+ def cfdp_transactions(
481
+ active=True,
482
+ api_timeout=5,
483
+ microservice_name="CFDP",
484
+ prefix="/cfdp",
485
+ schema="http",
486
+ hostname=None,
487
+ port=2905,
488
+ url=None,
489
+ scope=OPENC3_SCOPE,
490
+ ):
491
+ api = CfdpApi(
492
+ timeout=api_timeout,
493
+ microservice_name=microservice_name,
494
+ prefix=prefix,
495
+ schema=schema,
496
+ hostname=hostname,
497
+ port=port,
498
+ url=url,
499
+ scope=scope,
500
+ )
501
+ return api.transactions(active=active, scope=scope)
502
+
503
+
504
+ # Helper methods
505
+
506
+
507
+ def cfdp_wait_for_indication(
508
+ api,
509
+ transaction_id=None,
510
+ indication_type=None,
511
+ continuation=None,
512
+ include_continuation=False,
513
+ timeout=600,
514
+ limit=1000,
515
+ scope=OPENC3_SCOPE,
516
+ ):
517
+ if timeout is None:
518
+ timeout = 0
519
+ start_time = time.time()
520
+ end_time = start_time + timeout
521
+ if not continuation:
522
+ continuation = "0-0"
523
+ done = False
524
+ while not done:
525
+ result = api.indications(
526
+ transaction_id=transaction_id, continuation=continuation, limit=limit, scope=scope
527
+ )
528
+ continuation = result["continuation"]
529
+ indications = result["indications"]
530
+ if indications and len(indications) > 0:
531
+ if not indication_type:
532
+ if include_continuation:
533
+ return indications, continuation
534
+ else:
535
+ return indications
536
+ for indication in indications:
537
+ if indication["indication_type"] == indication_type:
538
+ if include_continuation:
539
+ return indication, continuation
540
+ else:
541
+ return indication
542
+ if time.time() >= end_time:
543
+ if timeout > 0:
544
+ raise RuntimeError("CFDP Timeout")
545
+ done = True
546
+ if done:
547
+ break
548
+ wait_func = _get_wait()
549
+ if wait_func is not None:
550
+ wait_time = wait_func(1)
551
+ if wait_time < 1.0: # User hit go
552
+ break
553
+ else:
554
+ time.sleep(1)
555
+ if indication_type:
556
+ if include_continuation:
557
+ return None, continuation
558
+ else:
559
+ return None
560
+ else:
561
+ if include_continuation:
562
+ return [], continuation
563
+ else:
564
+ return []
data/lib/cfdp.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- # Copyright 2023 OpenC3, Inc.
3
+ # Copyright 2026 OpenC3, Inc.
4
4
  # All Rights Reserved.
5
5
  #
6
6
  # Licensed for Evaluation and Educational Use
@@ -54,12 +54,56 @@ def cfdp_put(
54
54
  remote_entity_id: remote_entity_id, # Used to indicate proxy put
55
55
  scope: $openc3_scope)
56
56
  return transaction_id unless timeout
57
- indication = nil
58
- indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Transaction-Finished', continuation: continuation, timeout: timeout, scope: scope) if timeout
59
- indication ||= cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Proxy-Put-Response', continuation: continuation, timeout: timeout, scope: scope) if remote_entity_id and timeout
57
+ indication_type = remote_entity_id ? 'Proxy-Put-Response' : 'Transaction-Finished'
58
+ indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: indication_type, continuation: continuation, timeout: timeout, scope: scope)
60
59
  return transaction_id, indication
61
60
  end
62
61
 
62
+ def cfdp_put_dir(
63
+ destination_entity_id:,
64
+ source_directory_name:,
65
+ closure_requested: nil,
66
+ transmission_mode: nil,
67
+ filestore_requests: [],
68
+ fault_handler_overrides: [],
69
+ flow_label: nil,
70
+ segmentation_control: "NOT_PRESERVED",
71
+ messages_to_user: [],
72
+ remote_entity_id: nil, # Used to indicate proxy put
73
+ timeout: 600,
74
+ api_timeout: 5,
75
+ microservice_name: 'CFDP',
76
+ prefix: '/cfdp',
77
+ schema: 'http',
78
+ hostname: nil,
79
+ port: 2905,
80
+ url: nil,
81
+ scope: $openc3_scope)
82
+
83
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
84
+ continuation = api.subscribe(scope: scope) if timeout
85
+ transaction_ids = api.put_dir(
86
+ destination_entity_id: destination_entity_id,
87
+ source_directory_name: source_directory_name,
88
+ transmission_mode: transmission_mode,
89
+ closure_requested: closure_requested,
90
+ filestore_requests: filestore_requests,
91
+ fault_handler_overrides: fault_handler_overrides,
92
+ flow_label: flow_label,
93
+ segmentation_control: segmentation_control,
94
+ messages_to_user: messages_to_user,
95
+ remote_entity_id: remote_entity_id, # Used to indicate proxy put
96
+ scope: $openc3_scope)
97
+ return transaction_ids unless timeout
98
+ indications = []
99
+ transaction_ids.each do |transaction_id|
100
+ indication_type = remote_entity_id ? 'Proxy-Put-Response' : 'Transaction-Finished'
101
+ indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: indication_type, continuation: continuation, timeout: timeout, scope: scope)
102
+ indications << [transaction_id, indication]
103
+ end
104
+ return transaction_ids, indications
105
+ end
106
+
63
107
  def cfdp_cancel(
64
108
  transaction_id:,
65
109
  remote_entity_id: nil,
@@ -76,8 +120,10 @@ def cfdp_cancel(
76
120
  continuation = api.subscribe(scope: scope) if timeout
77
121
  transaction_id = api.cancel(transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope: scope)
78
122
  indication = nil
79
- indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Transaction-Finished', continuation: continuation, timeout: timeout, scope: scope) if timeout
80
- indication ||= cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Proxy-Put-Response', continuation: continuation, timeout: timeout, scope: scope) if remote_entity_id and timeout
123
+ if transaction_id
124
+ indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Transaction-Finished', continuation: continuation, timeout: timeout, scope: scope) if timeout
125
+ indication ||= cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Proxy-Put-Response', continuation: continuation, timeout: timeout, scope: scope) if remote_entity_id and timeout
126
+ end
81
127
  return indication
82
128
  end
83
129
 
@@ -97,8 +143,10 @@ def cfdp_suspend(
97
143
  continuation = api.subscribe(scope: scope) if timeout
98
144
  transaction_id = api.suspend(transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope: scope)
99
145
  indication = nil
100
- indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Suspended', continuation: continuation, timeout: timeout, scope: scope) if not remote_entity_id and timeout
101
- indication ||= cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Remote-Suspend-Response', continuation: continuation, timeout: timeout, scope: scope) if remote_entity_id and timeout
146
+ if transaction_id
147
+ indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Suspended', continuation: continuation, timeout: timeout, scope: scope) if not remote_entity_id and timeout
148
+ indication ||= cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Remote-Suspend-Response', continuation: continuation, timeout: timeout, scope: scope) if remote_entity_id and timeout
149
+ end
102
150
  return indication
103
151
  end
104
152
 
@@ -118,8 +166,10 @@ def cfdp_resume(
118
166
  continuation = api.subscribe(scope: scope) if timeout
119
167
  transaction_id = api.resume(transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope: scope)
120
168
  indication = nil
121
- indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Resumed', continuation: continuation, timeout: timeout, scope: scope) if not remote_entity_id and timeout
122
- indication ||= cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Remote-Resume-Response', continuation: continuation, timeout: timeout, scope: scope) if remote_entity_id and timeout
169
+ if transaction_id
170
+ indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Resumed', continuation: continuation, timeout: timeout, scope: scope) if not remote_entity_id and timeout
171
+ indication ||= cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Remote-Resume-Response', continuation: continuation, timeout: timeout, scope: scope) if remote_entity_id and timeout
172
+ end
123
173
  return indication
124
174
  end
125
175
 
@@ -140,8 +190,10 @@ def cfdp_report(
140
190
  continuation = api.subscribe(scope: scope) if timeout
141
191
  transaction_id = api.report(transaction_id: transaction_id, remote_entity_id: remote_entity_id, report_file_name: report_file_name, scope: scope)
142
192
  indication = nil
143
- indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Report', continuation: continuation, timeout: timeout, scope: scope) if not remote_entity_id and timeout
144
- indication ||= cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Remote-Report-Response', continuation: continuation, timeout: timeout, scope: scope) if remote_entity_id and timeout
193
+ if transaction_id
194
+ indication = cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Report', continuation: continuation, timeout: timeout, scope: scope) if not remote_entity_id and timeout
195
+ indication ||= cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Remote-Report-Response', continuation: continuation, timeout: timeout, scope: scope) if remote_entity_id and timeout
196
+ end
145
197
  return indication
146
198
  end
147
199
 
@@ -196,8 +248,10 @@ def cfdp_directory_listing(
196
248
  continuation = api.subscribe(scope: scope) if timeout
197
249
  transaction_id = api.directory_listing(remote_entity_id: remote_entity_id, directory_name: directory_name, directory_file_name: directory_file_name, scope: scope)
198
250
  indications = []
199
- indications << cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Transaction-Finished', continuation: continuation, timeout: timeout, scope: scope) if timeout
200
- indications << cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Directory-Listing-Response', continuation: continuation, timeout: timeout, scope: scope) if timeout
251
+ if transaction_id
252
+ indications << cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Transaction-Finished', continuation: continuation, timeout: timeout, scope: scope) if timeout
253
+ indications << cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: 'Directory-Listing-Response', continuation: continuation, timeout: timeout, scope: scope) if timeout
254
+ end
201
255
  return indications.compact
202
256
  end
203
257