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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 254a8c3fa0ae6e2ec535bc5c565ad7e376706858dbd1a87e394a70998bca8a33
4
+ data.tar.gz: '08d510acfdb03663b4f3426dff1a6a9dbbeada23e0b1d0b5a3ea2160341b3ac8'
5
+ SHA512:
6
+ metadata.gz: 3d93dd03e13bcae8c6fea52df4ad07320ab9097c5c3e9d2241c988682189d03edfcef9f274d7a02cde434d930dc0b9b3f851a82efa7d9b6d8dbd8e34e03c877f
7
+ data.tar.gz: 409424118dd69bd8ee1d14fdd88bc3fcc6759f4e4edb694aa94b2af3ffac387504a70a5167b6f6aef1c2d28ea0c932ab6395af9d261a3693fca03957cabde3f1
data/LICENSE.txt ADDED
@@ -0,0 +1,18 @@
1
+ # OpenC3 Evaluation and Educational License
2
+ #
3
+ # Copyright 2023 OpenC3, Inc.
4
+ #
5
+ # This work is licensed for evaluation and educational purposes only.
6
+ # It may NOT be used for formal development, integration and test, operations
7
+ # or any other commercial purpose without the purchase of a commercial license
8
+ # from OpenC3, Inc.
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all copies
11
+ # or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15
+ # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,181 @@
1
+ # OpenC3 COSMOS CFDP Plugin
2
+
3
+ This plugin provides a microservice and corresponding API for handling the CCSDS File Delivery Protocol (CFDP).
4
+
5
+ This CFDP implementation is intended to be compliant with CCSDS 727.0-B-5 - Blue Book July 2020.
6
+
7
+ ## Installation
8
+
9
+ 1. Install this plugin in the Admin Tool
10
+ 2. During installation, edit plugin.txt to configure all of your MIB settings (See MIB Configuration Below)
11
+
12
+ ## Usage in Scripts
13
+
14
+ See: [cfdp.rb]()
15
+
16
+ ```
17
+ require 'cfdp'
18
+
19
+ # Send a file and wait up to 10 minutes for complete (Default mode)
20
+ transaction_id, indication = cfdp_put(destination_entity_id: 1, source_file_name: "file_to_send.bin", destination_file_name: "received_file.bin")
21
+
22
+ # Force UNACKNOWLEDGED mode
23
+ transaction_id, indication = cfdp_put(destination_entity_id: 1, source_file_name: "file_to_send.bin", destination_file_name: "received_file.bin", transmission_mode: "UNACKNOWLEDGED")
24
+
25
+ # Force UNACKNOWLEDGED mode and request closure
26
+ transaction_id, indication = cfdp_put(destination_entity_id: 1, source_file_name: "file_to_send.bin", destination_file_name: "received_file.bin", transmission_mode: "UNACKNOWLEDGED", closure_requested: "CLOSURE_REQUESTED")
27
+
28
+ # Force ACKNOWLEDGED mode
29
+ transaction_id, indication = cfdp_put(destination_entity_id: 1, source_file_name: "file_to_send.bin", destination_file_name: "received_file.bin", transmission_mode: "ACKNOWLEDGED")
30
+
31
+ # Send a file and don't wait
32
+ continuation = cfdp_subscribe()
33
+ transaction_id = cfdp_put(destination_entity_id: 1, source_file_name: "file_to_send.bin", destination_file_name: "received_file.bin", timeout: nil)
34
+ ...
35
+ DO_OTHER_THINGS
36
+ ...
37
+ indication = cfdp_indications(transaction_id: transaction_id, indication_type: 'Transaction-Finished', continuation: continuation)
38
+
39
+ # Cancel a transaction
40
+ indication = cfdp_cancel(transaction_id: transaction_id)
41
+
42
+ # Suspend a transaction
43
+ indication = cfdp_suspend(transaction_id: transaction_id)
44
+
45
+ # Resume a suspended transaction
46
+ indication = cfdp_resume(transaction_id: transaction_id)
47
+
48
+ # Get a report on a transaction
49
+ indication = cfdp_report(transaction_id: transaction_id)
50
+ puts indication["status_report"]
51
+
52
+ # Get a list of transactions
53
+ transactions = cfdp_transactions(active: true)
54
+
55
+ # Filestore requests
56
+ requests = []
57
+ requests << ["CREATE_FILE", file_name]
58
+ requests << ["DELETE_FILE", file_name]
59
+ requests << ["RENAME_FILE", old_file_name, new_file_name]
60
+ requests << ["APPEND_FILE", file_name, appended_file_name]
61
+ requests << ["REPLACE_FILE", replaced_file_name, contents_file_name]
62
+ requests << ["CREATE_DIRECTORY", directory_name]
63
+ requests << ["REMOVE_DIRECTORY", directory_name]
64
+ requests << ["DENY_FILE", file_name]
65
+ requests << ["DENY_DIRECTORY", directory_name]
66
+ transaction_id, indication = cfdp_put(destination_entity_id: 1, filestore_requests: requests)
67
+ indication["filestore_responses"].each do |response|
68
+ puts "Filestore failed: #{response}" if response["STATUS_CODE"] != "SUCCESSFUL"
69
+ end
70
+
71
+ # Proxy operations
72
+ # These add remote_entity_id to specify a remote entity
73
+
74
+ # Get a file (using proxy put) and wait for it to be received
75
+ remote_entity_id = 1
76
+ my_entity_id = 2
77
+ transaction_id, indication = cfdp_put(remote_entity_id: remote_entity_id, destination_entity_id: my_entity_id, source_file_name: "file_to_send.bin", destination_file_name: "received_file.bin")
78
+
79
+ # Cancel a proxy put transaction
80
+ indication = cfdp_cancel(transaction_id: transaction_id, remote_entity_id: 1)
81
+
82
+ # Suspend a remote transaction
83
+ indication = cfdp_suspend(transaction_id: transaction_id, remote_entity_id: 1)
84
+
85
+ # Resume a remote transaction
86
+ indication = cfdp_resume(transaction_id: transaction_id, remote_entity_id: 1)
87
+
88
+ # Get a status report on a remote transaction
89
+ indication = cfdp_report(transaction_id: transaction_id, remote_entity_id: 1, report_file_name: "my_report.txt")
90
+
91
+ # Get a remote directory listing
92
+ indications = cfdp_directory_listing(remote_entity_id: 1, directory_name: "/files", directory_file_name: "my_listing.txt")
93
+
94
+ ```
95
+
96
+ ## MIB Configuration
97
+
98
+ The CFDP Management Information Base (MIB) is configured by passing options to the CFDP microservice in plugin.txt.
99
+ Note: This will always need to be configured for your application
100
+
101
+ Most settings are associated with the most recently mentioned source_entity_id or destination_entity_id.
102
+
103
+ Minimum required settings:
104
+
105
+ - A source_entity_id and corresponding tlm_info must be given.
106
+ - At least one destination_entity_id must be defined with a corresponding cmd_info.
107
+ - root_path must be defined
108
+ - bucket should be set if the root_path is in a bucket. Otherwise the root path is assumed to be a mounted volume.
109
+
110
+ ### Source Entity Configuration
111
+
112
+ | Setting Name | Description | Allowed Values | Default Value |
113
+ | ------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------- | ------------------------------- |
114
+ | root_path | The path to send/receive files from | Valid directory | N/A - Must be given |
115
+ | bucket | The bucket to send/receive files from | Valid bucket Name | nil - Serve from mounted volume |
116
+ | source_entity_id | The entity id for this CFDP microservice | Any integer | N/A - Must be given |
117
+ | tlm_info | A target_name, packet_name, and item_name to receive PDUs. Multiple tlm_info options can be given | COSMOS packet information | N/A - Must be given |
118
+ | eof_sent_indication | Issue EOF-Sent.indication | true or false | true |
119
+ | eof_recv_indication | Issue EOF-Recv.indication | true or false | true |
120
+ | file_segment_recv_indication | Issue File-Segment-Recv.indication | true or false | true |
121
+ | transaction_finished_indication | Issue Transaction-Finished.indication | true or false | true |
122
+ | suspended_indication | Issue Suspended.indication | true or false | true |
123
+ | resume_indication | Issue Resume.indication | true or false | true |
124
+
125
+ ### Remote Entity Configuration
126
+
127
+ | destination_entity_id | Id of a remote entity to configure | Any integer | N/A - Must be given |
128
+ | ----------------------------- | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
129
+ | cmd_info | The target_name, packet_name, and item_name to send PDUs for the destination entity | COSMOS packet information | N/A - Must be given |
130
+ | protocol_version_number | CFDP Version Number Needed at Destination | 0 or 1 | 1 - CFDP Blue Book Rev 5+ |
131
+ | ack_timer_interval | Ack timeout in seconds | Any integer | 600 seconds |
132
+ | nak_timer_interval | Nak timeout in seconds | Any integer | 600 seconds |
133
+ | keep_alive_interval | Keep Alive Period in seconds | Any integer | 600 seconds |
134
+ | check_interval | Interval to check for transaction complete in seconds | Any integer | 600 seconds |
135
+ | maximum_file_segment_length | Maximum amount of file data in a segment in bytes | Any integer | 1024 bytes |
136
+ | ack_timer_expiration_limit | Number of times to wait for the ack timeout before declaring a fault | Any integer | 1 |
137
+ | transaction_inactivity_limit | Number of times to wait for the keep alive timeout before declaring the transaction inactive fault | Any integer | 1 |
138
+ | check_limit | Number of times to check for transaction complete before declaring a fault | Any integer | 1 |
139
+ | keep_alive_discrepancy_limit | Maximum difference between keep alive progress and source progress allowed before declaring a fault. | Any integer | 1024000 bytes |
140
+ | immediate_nak_mode | Send NAKs as soon as something is noticed missing | true or false | true |
141
+ | crcs_required | Does this entity want PDUs with CRCs | true or false | true |
142
+ | enable_acks | Send Acks in Acknowledged mode | true or false | true |
143
+ | enable_keep_alive | Send Keep Alives in Acknowledged mode | true or false | true |
144
+ | enable_finished | Send Finished PDU if closure requested or acknowledged mode | true or false | true |
145
+ | enable_eof_nak | Send A NAK in response to EOF | true of false | false |
146
+ | default_transmission_mode | Default put mode | ACKNOWLEDGED or UNACKNOWLEDGED | UNACKNOWLEDGED |
147
+ | entity_id_length | Size of entity ids in bytes minus one | 0 to 7 | 0 = 1 byte |
148
+ | sequence_number_length | Size of sequence numbers in bytes minus one | 0 to 7 | 0 = 1 byte |
149
+ | default_checksum_type | Checksum type number | 0 to 15 | 0 = Default CFDP checksum |
150
+ | transaction_closure_requested | Default closure requested setting | CLOSURE_REQUESTED or CLOSURE_NOT_REQUESTED | CLOSURE_REQUESTED |
151
+ | incomplete_file_disposition | What to do with an incomplete file | DISCARD or RETAIN | DISCARD |
152
+ | fault_handler | Fault handler setting | (ACK_LIMIT_REACHED, KEEP_ALIVE_LIMIT_REACHED, INVALID_TRANSMISSION_MODE, FILESTORE_REJECTION, FILE_CHECKSUM_FAILURE, FILE_SIZE_ERROR, NAK_LIMIT_REACHED, INACTIVITY_DETECTED, INVALID_FILE_STRUCTURE, CHECK_LIMIT_REACHED, or UNSUPPORTED_CHECKSUM_TYPE) followed by (ISSUE_NOTICE_OF_CANCELLATION, ISSUE_NOTICE_OF_SUSPENSION, IGNORE_ERROR, or ABANDON_TRANSACTION) | See Code |
153
+
154
+ ## Known Limitations
155
+
156
+ 1. Segmentation Control and Flow Label have no effect
157
+ 2. Suspension requests are not queued as specified in 6.5.4.1.2
158
+ 3. Annex B - Store and Forward Overlay Operations are not implemented
159
+
160
+ ## Contributing
161
+
162
+ We encourage you to contribute to OpenC3 COSMOS and this project!
163
+
164
+ Contributing is easy.
165
+
166
+ 1. Fork the project
167
+ 2. Create a feature branch
168
+ 3. Make your changes
169
+ 4. Submit a pull request
170
+
171
+ YOU MUST AGREE TO OUR CONTRIBUTOR LICENSE AGREEMENT TO SUBMIT CODE TO THIS PROJECT: See [CONTRIBUTING.txt](CONTRIBUTING.txt)
172
+
173
+ Most importantly:
174
+
175
+ FOR ALL CONTRIBUTIONS TO THE OPENC3 COSMOS PROJECT AND ASSOCIATED PLUGINS, OPENC3, INC. MAINTAINS ALL RIGHTS TO ALL CODE CONTRIBUTED INCLUDING THE RIGHT TO LICENSE IT UNDER OTHER TERMS.
176
+
177
+ ## License
178
+
179
+ OpenC3 Evaluation and Educational License
180
+
181
+ See [LICENSE.txt](LICENSE.txt)
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ PLUGIN_NAME = Dir['*.gemspec'][0].split('.')[0..-2].join('.')
2
+
3
+ require 'fileutils'
4
+
5
+ task :require_version do
6
+ unless ENV['VERSION']
7
+ puts "VERSION is required: rake build VERSION=X.Y.Z"
8
+ exit 1
9
+ end
10
+ end
11
+
12
+ task :build => [:require_version] do
13
+ split_version = ENV['VERSION'].to_s.split('.')
14
+ major = split_version[0]
15
+ minor = split_version[1]
16
+ if ENV['VERSION'] =~ /[a-zA-Z]+/
17
+ # Prerelease version
18
+ remainder = split_version[2..-1].join(".")
19
+ remainder.gsub!('-', '.pre.') # Rubygems replaces dashes with .pre.
20
+ remainder_split = remainder.split('.')
21
+ patch = remainder_split[0]
22
+ other = remainder_split[1..-1].join('.')
23
+ gem_version = "#{major}.#{minor}.#{patch}.#{other}"
24
+ else
25
+ gem_version = ENV['VERSION']
26
+ end
27
+ gem_name = PLUGIN_NAME + '-' + gem_version + '.gem'
28
+
29
+ # Build using sh built into Rake:
30
+ # https://rubydoc.info/gems/rake/FileUtils#sh-instance_method
31
+ if File.exist?("./microservices/CFDP/Gemfile.lock")
32
+ FileUtils.rm("./microservices/CFDP/Gemfile.lock")
33
+ end
34
+ sh('gem', 'build', PLUGIN_NAME)
35
+ sh("openc3cli validate #{gem_name}") do |ok, status|
36
+ if !ok && status.exitstatus == 127 # command not found
37
+ puts "Install the openc3 gem to validate! (gem install openc3)"
38
+ end
39
+ end
40
+ end
data/lib/cfdp.rb ADDED
@@ -0,0 +1,283 @@
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
+ require_relative 'cfdp_api'
18
+
19
+ def cfdp_put(
20
+ destination_entity_id:,
21
+ source_file_name: nil,
22
+ destination_file_name: nil,
23
+ closure_requested: nil,
24
+ transmission_mode: nil,
25
+ filestore_requests: [],
26
+ fault_handler_overrides: [],
27
+ flow_label: nil,
28
+ segmentation_control: "NOT_PRESERVED",
29
+ messages_to_user: [],
30
+ remote_entity_id: nil, # Used to indicate proxy put
31
+ timeout: 600,
32
+ api_timeout: 5,
33
+ microservice_name: 'CFDP',
34
+ prefix: '/cfdp',
35
+ schema: 'http',
36
+ hostname: nil,
37
+ port: 2905,
38
+ url: nil,
39
+ scope: $openc3_scope)
40
+
41
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
42
+ continuation = api.subscribe(scope: scope) if timeout
43
+ transaction_id = api.put(
44
+ destination_entity_id: destination_entity_id,
45
+ source_file_name: source_file_name,
46
+ destination_file_name: destination_file_name,
47
+ transmission_mode: transmission_mode,
48
+ closure_requested: closure_requested,
49
+ filestore_requests: filestore_requests,
50
+ fault_handler_overrides: fault_handler_overrides,
51
+ flow_label: flow_label,
52
+ segmentation_control: segmentation_control,
53
+ messages_to_user: messages_to_user,
54
+ remote_entity_id: remote_entity_id, # Used to indicate proxy put
55
+ scope: $openc3_scope)
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
60
+ return transaction_id, indication
61
+ end
62
+
63
+ def cfdp_cancel(
64
+ transaction_id:,
65
+ remote_entity_id: nil,
66
+ timeout: 600,
67
+ api_timeout: 5,
68
+ microservice_name: 'CFDP',
69
+ prefix: '/cfdp',
70
+ schema: 'http',
71
+ hostname: nil,
72
+ port: 2905,
73
+ url: nil,
74
+ scope: $openc3_scope)
75
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
76
+ continuation = api.subscribe(scope: scope) if timeout
77
+ transaction_id = api.cancel(transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope: scope)
78
+ 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
81
+ return indication
82
+ end
83
+
84
+ def cfdp_suspend(
85
+ transaction_id:,
86
+ remote_entity_id: nil,
87
+ timeout: 600,
88
+ api_timeout: 5,
89
+ microservice_name: 'CFDP',
90
+ prefix: '/cfdp',
91
+ schema: 'http',
92
+ hostname: nil,
93
+ port: 2905,
94
+ url: nil,
95
+ scope: $openc3_scope)
96
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
97
+ continuation = api.subscribe(scope: scope) if timeout
98
+ transaction_id = api.suspend(transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope: scope)
99
+ 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
102
+ return indication
103
+ end
104
+
105
+ def cfdp_resume(
106
+ transaction_id:,
107
+ remote_entity_id: nil,
108
+ timeout: 600,
109
+ api_timeout: 5,
110
+ microservice_name: 'CFDP',
111
+ prefix: '/cfdp',
112
+ schema: 'http',
113
+ hostname: nil,
114
+ port: 2905,
115
+ url: nil,
116
+ scope: $openc3_scope)
117
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
118
+ continuation = api.subscribe(scope: scope) if timeout
119
+ transaction_id = api.resume(transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope: scope)
120
+ 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
123
+ return indication
124
+ end
125
+
126
+ def cfdp_report(
127
+ transaction_id:,
128
+ remote_entity_id: nil,
129
+ report_file_name: nil,
130
+ timeout: 600,
131
+ api_timeout: 5,
132
+ microservice_name: 'CFDP',
133
+ prefix: '/cfdp',
134
+ schema: 'http',
135
+ hostname: nil,
136
+ port: 2905,
137
+ url: nil,
138
+ scope: $openc3_scope)
139
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
140
+ continuation = api.subscribe(scope: scope) if timeout
141
+ transaction_id = api.report(transaction_id: transaction_id, remote_entity_id: remote_entity_id, report_file_name: report_file_name, scope: scope)
142
+ 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
145
+ return indication
146
+ end
147
+
148
+ def cfdp_subscribe(
149
+ api_timeout: 5,
150
+ microservice_name: 'CFDP',
151
+ prefix: '/cfdp',
152
+ schema: 'http',
153
+ hostname: nil,
154
+ port: 2905,
155
+ url: nil,
156
+ scope: $openc3_scope)
157
+
158
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
159
+ return api.subscribe(scope: scope)
160
+ end
161
+
162
+ def cfdp_indications(
163
+ transaction_id: nil,
164
+ indication_type: nil,
165
+ continuation: nil,
166
+ include_continuation: true,
167
+ timeout: nil,
168
+ api_timeout: 5,
169
+ limit: 100,
170
+ microservice_name: 'CFDP',
171
+ prefix: '/cfdp',
172
+ schema: 'http',
173
+ hostname: nil,
174
+ port: 2905,
175
+ url: nil,
176
+ scope: $openc3_scope)
177
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
178
+ return cfdp_wait_for_indication(api: api, transaction_id: transaction_id, indication_type: indication_type, continuation: continuation, include_continuation: include_continuation, timeout: timeout, limit: limit, scope: scope)
179
+ end
180
+
181
+ def cfdp_directory_listing(
182
+ remote_entity_id:,
183
+ directory_name:,
184
+ directory_file_name:,
185
+ timeout: 600,
186
+ api_timeout: 5,
187
+ microservice_name: 'CFDP',
188
+ prefix: '/cfdp',
189
+ schema: 'http',
190
+ hostname: nil,
191
+ port: 2905,
192
+ url: nil,
193
+ scope: $openc3_scope)
194
+
195
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
196
+ continuation = api.subscribe(scope: scope) if timeout
197
+ transaction_id = api.directory_listing(remote_entity_id: remote_entity_id, directory_name: directory_name, directory_file_name: directory_file_name, scope: scope)
198
+ 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
201
+ return indications.compact
202
+ end
203
+
204
+ def cfdp_transactions(
205
+ active: true,
206
+ api_timeout: 5,
207
+ microservice_name: 'CFDP',
208
+ prefix: '/cfdp',
209
+ schema: 'http',
210
+ hostname: nil,
211
+ port: 2905,
212
+ url: nil,
213
+ scope: $openc3_scope)
214
+
215
+ api = CfdpApi.new(timeout: api_timeout, microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, url: url, scope: scope)
216
+ return api.transactions(active: active, scope: scope)
217
+ end
218
+
219
+ # Helper methods
220
+
221
+ def cfdp_wait_for_indication(
222
+ api:,
223
+ transaction_id: nil,
224
+ indication_type: nil,
225
+ continuation: nil,
226
+ include_continuation: false,
227
+ timeout: 600,
228
+ limit: 1000,
229
+ scope: $openc3_scope)
230
+
231
+ timeout ||= 0
232
+ start_time = Time.now
233
+ end_time = start_time + timeout
234
+ continuation = '0-0' unless continuation
235
+ done = false
236
+ while not done
237
+ result = api.indications(transaction_id: transaction_id, continuation: continuation, limit: limit, scope: scope)
238
+ continuation = result['continuation']
239
+ indications = result['indications']
240
+ if indications and indications.length > 0
241
+ unless indication_type
242
+ if include_continuation
243
+ return indications, continuation
244
+ else
245
+ return indications
246
+ end
247
+ end
248
+ indications.each do |indication|
249
+ if indication['indication_type'] == indication_type
250
+ if include_continuation
251
+ return indication, continuation
252
+ else
253
+ return indication
254
+ end
255
+ end
256
+ end
257
+ end
258
+ if Time.now >= end_time
259
+ raise "CFDP Timeout" if timeout > 0
260
+ done = true
261
+ end
262
+ break if done
263
+ if defined? wait
264
+ wait_time = wait(1)
265
+ break if wait_time < 1.0 # User hit go
266
+ else
267
+ sleep(1)
268
+ end
269
+ end
270
+ if indication_type
271
+ if include_continuation
272
+ return nil, continuation
273
+ else
274
+ return nil
275
+ end
276
+ else
277
+ if include_continuation
278
+ return [], continuation
279
+ else
280
+ return []
281
+ end
282
+ end
283
+ end