openc3-cosmos-cfdp 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +18 -0
- data/README.md +181 -0
- data/Rakefile +40 -0
- data/lib/cfdp.rb +283 -0
- data/lib/cfdp_api.rb +204 -0
- data/microservices/CFDP/Gemfile +37 -0
- data/microservices/CFDP/Rakefile +6 -0
- data/microservices/CFDP/app/controllers/application_controller.rb +46 -0
- data/microservices/CFDP/app/controllers/cfdp_controller.rb +222 -0
- data/microservices/CFDP/app/models/cfdp_checksum.rb +52 -0
- data/microservices/CFDP/app/models/cfdp_crc_checksum.rb +41 -0
- data/microservices/CFDP/app/models/cfdp_mib.rb +613 -0
- data/microservices/CFDP/app/models/cfdp_model.rb +25 -0
- data/microservices/CFDP/app/models/cfdp_null_checksum.rb +29 -0
- data/microservices/CFDP/app/models/cfdp_pdu.rb +202 -0
- data/microservices/CFDP/app/models/cfdp_receive_transaction.rb +590 -0
- data/microservices/CFDP/app/models/cfdp_source_transaction.rb +449 -0
- data/microservices/CFDP/app/models/cfdp_topic.rb +58 -0
- data/microservices/CFDP/app/models/cfdp_transaction.rb +188 -0
- data/microservices/CFDP/app/models/cfdp_user.rb +601 -0
- data/microservices/CFDP/bin/rails +4 -0
- data/microservices/CFDP/bin/rake +4 -0
- data/microservices/CFDP/bin/setup +25 -0
- data/microservices/CFDP/config/application.rb +55 -0
- data/microservices/CFDP/config/boot.rb +4 -0
- data/microservices/CFDP/config/credentials.yml.enc +1 -0
- data/microservices/CFDP/config/environment.rb +5 -0
- data/microservices/CFDP/config/environments/development.rb +53 -0
- data/microservices/CFDP/config/environments/production.rb +75 -0
- data/microservices/CFDP/config/environments/test.rb +50 -0
- data/microservices/CFDP/config/initializers/application_controller_renderer.rb +8 -0
- data/microservices/CFDP/config/initializers/backtrace_silencers.rb +7 -0
- data/microservices/CFDP/config/initializers/cfdp_initializer.rb +26 -0
- data/microservices/CFDP/config/initializers/cors.rb +16 -0
- data/microservices/CFDP/config/initializers/filter_parameter_logging.rb +8 -0
- data/microservices/CFDP/config/initializers/inflections.rb +16 -0
- data/microservices/CFDP/config/initializers/mime_types.rb +4 -0
- data/microservices/CFDP/config/initializers/wrap_parameters.rb +9 -0
- data/microservices/CFDP/config/locales/en.yml +29 -0
- data/microservices/CFDP/config/puma.rb +38 -0
- data/microservices/CFDP/config/routes.rb +16 -0
- data/microservices/CFDP/config.ru +5 -0
- data/microservices/CFDP/init.sh +9 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_ack.rb +82 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_enum.rb +237 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_eof.rb +87 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_file_data.rb +98 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_finished.rb +114 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_keep_alive.rb +65 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_metadata.rb +116 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_nak.rb +91 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_prompt.rb +60 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_tlv.rb +291 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_user_ops.rb +749 -0
- data/microservices/CFDP/public/robots.txt +1 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_ack_spec.rb +114 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_eof_spec.rb +159 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_file_data_spec.rb +76 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_finished_spec.rb +192 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_keep_alive_spec.rb +69 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_metadata_spec.rb +346 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_nak_spec.rb +126 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_prompt_spec.rb +94 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_spec.rb +111 -0
- data/microservices/CFDP/spec/rails_helper.rb +71 -0
- data/microservices/CFDP/spec/requests/cfdp_spec.rb +1965 -0
- data/microservices/CFDP/spec/spec_helper.rb +200 -0
- data/plugin.txt +67 -0
- data/targets/CFDPTEST/cmd_tlm/cmd.txt +5 -0
- data/targets/CFDPTEST/cmd_tlm/tlm.txt +4 -0
- data/targets/CFDPTEST/procedures/cfdp_test_suite.rb +130 -0
- data/targets/CFDPTEST/target.txt +4 -0
- 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
|