openc3-cosmos-cfdp 1.0.2 → 2.0.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.
- checksums.yaml +4 -4
- data/README.md +10 -1
- data/microservices/CFDP/Gemfile +3 -11
- data/microservices/CFDP/Gemfile.dev +35 -0
- data/microservices/CFDP/Gemfile.prod +29 -0
- data/microservices/CFDP/app/controllers/cfdp_controller.rb +8 -0
- data/microservices/CFDP/app/models/cfdp_crc_checksum.rb +3 -1
- data/microservices/CFDP/app/models/cfdp_mib.rb +2 -1
- data/microservices/CFDP/app/models/cfdp_pdu.rb +43 -19
- data/microservices/CFDP/app/models/cfdp_receive_transaction.rb +7 -2
- data/microservices/CFDP/app/models/cfdp_source_transaction.rb +6 -1
- data/microservices/CFDP/app/models/cfdp_transaction.rb +1 -1
- data/microservices/CFDP/app/models/cfdp_user.rb +14 -4
- data/microservices/CFDP/config/application.rb +0 -11
- data/microservices/CFDP/config/environments/test.rb +1 -1
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_file_data.rb +6 -2
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_finished.rb +17 -5
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_metadata.rb +28 -11
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_tlv.rb +5 -2
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_user_ops.rb +16 -9
- data/microservices/CFDP/spec/controllers/cfdp_controller_spec.rb +373 -0
- data/microservices/CFDP/spec/models/cfdp_crc_checksum_spec.rb +134 -0
- data/microservices/CFDP/spec/models/cfdp_mib_spec.rb +389 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_metadata_spec.rb +102 -1
- data/microservices/CFDP/spec/models/cfdp_pdu_user_ops_spec.rb +562 -0
- data/microservices/CFDP/spec/models/cfdp_receive_transaction_spec.rb +598 -0
- data/microservices/CFDP/spec/models/cfdp_transaction_spec.rb +331 -0
- data/microservices/CFDP/spec/models/cfdp_user_spec.rb +575 -0
- metadata +15 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79139b9f1a0842f2fda723326ecac01d214144f4e42f6fd98a807d684895dcc7
|
4
|
+
data.tar.gz: 2c77f4cd5d8b237b6414277ff9ae43f52739bceac27243e59808346b6dea5e90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7275036dc47dd2b54d60e69bcd3091a2e05fdccd677302463cd10cba10d3d7458ff859c7a5f9ad4466407582357b798890d72bfea7f3b0b6a6a70a6fde39b36
|
7
|
+
data.tar.gz: 93e8b60efdf726c95b3e5bbd77c7d05297de180bdff4eadf532e80c5cbc0e2772d73ad659bc173d0903fe031cc81a01645b0d9bae889a42781800af37a055336
|
data/README.md
CHANGED
@@ -2,13 +2,21 @@
|
|
2
2
|
|
3
3
|
This plugin provides a microservice and corresponding API for handling the CCSDS File Delivery Protocol (CFDP).
|
4
4
|
|
5
|
-
This CFDP implementation is intended to be compliant with
|
5
|
+
This CFDP implementation is intended to be compliant with:
|
6
|
+
|
7
|
+
- CCSDS 727.0-B-5 - Blue Book July 2020
|
8
|
+
- CCSDS 727.0-B-4 - Blue Book January 2007
|
9
|
+
- CCSDS 727.0-B-3 - Blue Book June 2005
|
10
|
+
|
11
|
+
It is also potentially compliant with earlier versions but that has not been evaluated.
|
6
12
|
|
7
13
|
## Installation
|
8
14
|
|
9
15
|
1. Install this plugin in the Admin Tool
|
10
16
|
2. During installation, edit plugin.txt to configure all of your MIB settings (See MIB Configuration Below)
|
11
17
|
|
18
|
+
In particular be sure to set the desired protocol_version_number for each remote entity. protocol_version_number 0 is used for all versions of the standard before the 2020 release. protocol_version_number 1 is used for the current release and potential future releases. This plugin defaults to using protocol_version_number 1.
|
19
|
+
|
12
20
|
## Usage in Scripts
|
13
21
|
|
14
22
|
See: [cfdp.rb]()
|
@@ -158,6 +166,7 @@ Minimum required settings:
|
|
158
166
|
1. Segmentation Control and Flow Label have no effect
|
159
167
|
2. Suspension requests are not queued as specified in 6.5.4.1.2
|
160
168
|
3. Annex B - Store and Forward Overlay Operations are not implemented
|
169
|
+
4. Extended operations and classes 3 and 4 from the earlier CFDP standards are not implemented
|
161
170
|
|
162
171
|
## Contributing
|
163
172
|
|
data/microservices/CFDP/Gemfile
CHANGED
@@ -2,7 +2,7 @@ source ENV['RUBYGEMS_URL'] || "https://rubygems.org"
|
|
2
2
|
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
3
3
|
|
4
4
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
5
|
-
gem 'rails', '~> 7.1.
|
5
|
+
gem 'rails', '~> 7.1' # Left at 7.1 to support earlier cosmos versions
|
6
6
|
|
7
7
|
# Reduces boot times through caching; required in config/boot.rb
|
8
8
|
gem 'bootsnap', '>= 1.9.3', require: false
|
@@ -13,16 +13,8 @@ gem 'rack-cors', '~> 2.0'
|
|
13
13
|
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
14
14
|
gem 'tzinfo-data'
|
15
15
|
|
16
|
-
#
|
17
|
-
|
18
|
-
gem 'rspec-rails', '~> 6.0'
|
19
|
-
gem 'simplecov', '~> 0.20'
|
20
|
-
gem 'simplecov-cobertura', '~> 2.1'
|
21
|
-
end
|
22
|
-
|
23
|
-
group :test do
|
24
|
-
gem 'mock_redis', '>0.39'
|
25
|
-
end
|
16
|
+
# NOTE: Since we're not using the Gemfile.lock we can't include development
|
17
|
+
# or test groups in the Gemfile or bundler tries to install them and fails
|
26
18
|
|
27
19
|
if ENV['OPENC3_DEVEL']
|
28
20
|
gem 'openc3', :path => ENV['OPENC3_DEVEL']
|
@@ -0,0 +1,35 @@
|
|
1
|
+
source ENV['RUBYGEMS_URL'] || "https://rubygems.org"
|
2
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
3
|
+
|
4
|
+
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
5
|
+
gem 'rails', '~> 7.1' # Left at 7.1 to support earlier cosmos versions
|
6
|
+
|
7
|
+
# Reduces boot times through caching; required in config/boot.rb
|
8
|
+
gem 'bootsnap', '>= 1.9.3', require: false
|
9
|
+
|
10
|
+
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
|
11
|
+
gem 'rack-cors', '~> 2.0'
|
12
|
+
|
13
|
+
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
14
|
+
gem 'tzinfo-data'
|
15
|
+
|
16
|
+
group :development, :test do
|
17
|
+
gem 'rspec-rails', '~> 6.0'
|
18
|
+
gem 'simplecov', '~> 0.20'
|
19
|
+
gem 'simplecov-cobertura', '~> 2.1'
|
20
|
+
end
|
21
|
+
group :test do
|
22
|
+
gem 'mock_redis', '>0.39'
|
23
|
+
end
|
24
|
+
|
25
|
+
if ENV['OPENC3_DEVEL']
|
26
|
+
gem 'openc3', :path => ENV['OPENC3_DEVEL']
|
27
|
+
elsif ENV['OPENC3_PATH']
|
28
|
+
gem 'openc3', :path => ENV['OPENC3_PATH']
|
29
|
+
else
|
30
|
+
gem 'openc3', '>= 5.4.2.pre'
|
31
|
+
end
|
32
|
+
|
33
|
+
if ENV['OPENC3_ENTERPRISE_TAG']
|
34
|
+
gem 'openc3-enterprise', '>= 5.4.2.pre'
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
source ENV['RUBYGEMS_URL'] || "https://rubygems.org"
|
2
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
3
|
+
|
4
|
+
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
5
|
+
gem 'rails', '~> 7.1' # Left at 7.1 to support earlier cosmos versions
|
6
|
+
|
7
|
+
# Reduces boot times through caching; required in config/boot.rb
|
8
|
+
gem 'bootsnap', '>= 1.9.3', require: false
|
9
|
+
|
10
|
+
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
|
11
|
+
gem 'rack-cors', '~> 2.0'
|
12
|
+
|
13
|
+
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
14
|
+
gem 'tzinfo-data'
|
15
|
+
|
16
|
+
# NOTE: Since we're not using the Gemfile.lock we can't include development
|
17
|
+
# or test groups in the Gemfile or bundler tries to install them and fails
|
18
|
+
|
19
|
+
if ENV['OPENC3_DEVEL']
|
20
|
+
gem 'openc3', :path => ENV['OPENC3_DEVEL']
|
21
|
+
elsif ENV['OPENC3_PATH']
|
22
|
+
gem 'openc3', :path => ENV['OPENC3_PATH']
|
23
|
+
else
|
24
|
+
gem 'openc3', '>= 5.4.2.pre'
|
25
|
+
end
|
26
|
+
|
27
|
+
if ENV['OPENC3_ENTERPRISE_TAG']
|
28
|
+
gem 'openc3-enterprise', '>= 5.4.2.pre'
|
29
|
+
end
|
@@ -48,6 +48,8 @@ class CfdpController < ApplicationController
|
|
48
48
|
else
|
49
49
|
render :json => { :status => 'error', :message => "Transaction #{params[:transaction_id]} not found" }.as_json(:allow_nan => true), :status => 404
|
50
50
|
end
|
51
|
+
rescue ActionController::ParameterMissing => error
|
52
|
+
render :json => { :status => 'error', :message => error.message }.as_json(:allow_nan => true), :status => 400
|
51
53
|
rescue => error
|
52
54
|
render :json => { :status => 'error', :message => "#{error.message}\n#{error.backtrace.join("\n")}" }.as_json(:allow_nan => true), :status => 500
|
53
55
|
end
|
@@ -62,6 +64,8 @@ class CfdpController < ApplicationController
|
|
62
64
|
else
|
63
65
|
render :json => { :status => 'error', :message => "Transaction #{params[:transaction_id]} not found" }.as_json(:allow_nan => true), :status => 404
|
64
66
|
end
|
67
|
+
rescue ActionController::ParameterMissing => error
|
68
|
+
render :json => { :status => 'error', :message => error.message }.as_json(:allow_nan => true), :status => 400
|
65
69
|
rescue => error
|
66
70
|
render :json => { :status => 'error', :message => "#{error.message}\n#{error.backtrace.join("\n")}" }.as_json(:allow_nan => true), :status => 500
|
67
71
|
end
|
@@ -76,6 +80,8 @@ class CfdpController < ApplicationController
|
|
76
80
|
else
|
77
81
|
render :json => { :status => 'error', :message => "Transaction #{params[:transaction_id]} not found" }.as_json(:allow_nan => true), :status => 404
|
78
82
|
end
|
83
|
+
rescue ActionController::ParameterMissing => error
|
84
|
+
render :json => { :status => 'error', :message => error.message }.as_json(:allow_nan => true), :status => 400
|
79
85
|
rescue => error
|
80
86
|
render :json => { :status => 'error', :message => "#{error.message}\n#{error.backtrace.join("\n")}" }.as_json(:allow_nan => true), :status => 500
|
81
87
|
end
|
@@ -90,6 +96,8 @@ class CfdpController < ApplicationController
|
|
90
96
|
else
|
91
97
|
render :json => { :status => 'error', :message => "Transaction #{params[:transaction_id]} not found" }.as_json(:allow_nan => true), :status => 404
|
92
98
|
end
|
99
|
+
rescue ActionController::ParameterMissing => error
|
100
|
+
render :json => { :status => 'error', :message => error.message }.as_json(:allow_nan => true), :status => 400
|
93
101
|
rescue => error
|
94
102
|
render :json => { :status => 'error', :message => "#{error.message}\n#{error.backtrace.join("\n")}" }.as_json(:allow_nan => true), :status => 500
|
95
103
|
end
|
@@ -17,7 +17,9 @@
|
|
17
17
|
require 'openc3/utilities/crc'
|
18
18
|
|
19
19
|
class CfdpCrcChecksum
|
20
|
-
|
20
|
+
attr_reader :crc
|
21
|
+
|
22
|
+
def initialize(poly = OpenC3::Crc32::DEFAULT_POLY, seed = OpenC3::Crc32::DEFAULT_SEED, xor = true, reflect = true)
|
21
23
|
@crc = OpenC3::Crc32.new(poly, seed, xor, reflect)
|
22
24
|
@checksum = 0
|
23
25
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2025 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# Licensed for Evaluation and Educational Use
|
@@ -13,6 +13,9 @@
|
|
13
13
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
14
14
|
#
|
15
15
|
# The development of this software was funded in-whole or in-part by MethaneSAT LLC.
|
16
|
+
#
|
17
|
+
# The development of this software was funded in-part by Sandia National Laboratories.
|
18
|
+
# See https://github.com/OpenC3/openc3-cosmos-cfdp/pull/12 for details
|
16
19
|
|
17
20
|
require 'openc3/packets/packet'
|
18
21
|
require 'openc3/utilities/crc'
|
@@ -87,19 +90,32 @@ class CfdpPdu < OpenC3::Packet
|
|
87
90
|
end
|
88
91
|
|
89
92
|
# Static header
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
93
|
+
version = pdu.read("VERSION")
|
94
|
+
pdu_hash["VERSION"] = version
|
95
|
+
if version == 0
|
96
|
+
keys = [
|
97
|
+
"TYPE",
|
98
|
+
"DIRECTION",
|
99
|
+
"TRANSMISSION_MODE",
|
100
|
+
"PDU_DATA_LENGTH",
|
101
|
+
"ENTITY_ID_LENGTH",
|
102
|
+
"SEQUENCE_NUMBER_LENGTH",
|
103
|
+
"VARIABLE_DATA"
|
104
|
+
]
|
105
|
+
else
|
106
|
+
keys = [
|
107
|
+
"TYPE",
|
108
|
+
"DIRECTION",
|
109
|
+
"TRANSMISSION_MODE",
|
110
|
+
"LARGE_FILE_FLAG",
|
111
|
+
"PDU_DATA_LENGTH",
|
112
|
+
"SEGMENTATION_CONTROL",
|
113
|
+
"ENTITY_ID_LENGTH",
|
114
|
+
"SEGMENT_METADATA_FLAG",
|
115
|
+
"SEQUENCE_NUMBER_LENGTH",
|
116
|
+
"VARIABLE_DATA"
|
117
|
+
]
|
118
|
+
end
|
103
119
|
keys.each do |key|
|
104
120
|
pdu_hash[key] = pdu.read(key)
|
105
121
|
end
|
@@ -144,8 +160,9 @@ class CfdpPdu < OpenC3::Packet
|
|
144
160
|
end
|
145
161
|
|
146
162
|
def self.build_initial_pdu(type:, destination_entity:, file_size:, segmentation_control: "NOT_PRESERVED", transmission_mode: nil)
|
163
|
+
version = destination_entity['protocol_version_number']
|
147
164
|
pdu = self.new(crcs_required: destination_entity['crcs_required'])
|
148
|
-
pdu.write("VERSION",
|
165
|
+
pdu.write("VERSION", version)
|
149
166
|
pdu.write("TYPE", type)
|
150
167
|
pdu.write("DIRECTION", "TOWARD_FILE_RECEIVER")
|
151
168
|
if transmission_mode
|
@@ -159,14 +176,21 @@ class CfdpPdu < OpenC3::Packet
|
|
159
176
|
else
|
160
177
|
pdu.write("CRC_FLAG", "CRC_NOT_PRESENT")
|
161
178
|
end
|
162
|
-
|
179
|
+
|
180
|
+
# Version 0 doesn't support large files
|
181
|
+
if version == 0 or file_size < 4_294_967_296
|
182
|
+
pdu.write("LARGE_FILE_FLAG", "SMALL_FILE") # Equals 0
|
183
|
+
else
|
163
184
|
pdu.write("LARGE_FILE_FLAG", "LARGE_FILE")
|
185
|
+
end
|
186
|
+
|
187
|
+
if version == 0
|
188
|
+
pdu.write("SEGMENTATION_CONTROL", 0) # Always 0
|
164
189
|
else
|
165
|
-
pdu.write("
|
190
|
+
pdu.write("SEGMENTATION_CONTROL", segmentation_control)
|
166
191
|
end
|
167
|
-
pdu.write("SEGMENTATION_CONTROL", segmentation_control)
|
168
192
|
pdu.write("ENTITY_ID_LENGTH", destination_entity['entity_id_length'])
|
169
|
-
pdu.write("SEGMENT_METADATA_FLAG", "NOT_PRESENT") # Not implemented
|
193
|
+
pdu.write("SEGMENT_METADATA_FLAG", "NOT_PRESENT") # Not implemented - always 0
|
170
194
|
pdu.write("SEQUENCE_NUMBER_LENGTH", destination_entity['sequence_number_length'])
|
171
195
|
return pdu
|
172
196
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2025 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# Licensed for Evaluation and Educational Use
|
@@ -13,6 +13,9 @@
|
|
13
13
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
14
14
|
#
|
15
15
|
# The development of this software was funded in-whole or in-part by MethaneSAT LLC.
|
16
|
+
#
|
17
|
+
# The development of this software was funded in-part by Sandia National Laboratories.
|
18
|
+
# See https://github.com/OpenC3/openc3-cosmos-cfdp/pull/12 for details
|
16
19
|
|
17
20
|
require_relative 'cfdp_transaction'
|
18
21
|
|
@@ -485,7 +488,9 @@ class CfdpReceiveTransaction < CfdpTransaction
|
|
485
488
|
|
486
489
|
CfdpTopic.write_indication("Metadata-Recv", **kw_args)
|
487
490
|
|
488
|
-
|
491
|
+
checksum_type = @metadata_pdu_hash["CHECKSUM_TYPE"]
|
492
|
+
checksum_type ||= 0 # For version 0
|
493
|
+
@checksum = get_checksum(checksum_type)
|
489
494
|
unless @checksum
|
490
495
|
# Use Null checksum if checksum type not available
|
491
496
|
@condition_code = "UNSUPPORTED_CHECKSUM_TYPE"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2025 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# Licensed for Evaluation and Educational Use
|
@@ -13,6 +13,9 @@
|
|
13
13
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
14
14
|
#
|
15
15
|
# The development of this software was funded in-whole or in-part by MethaneSAT LLC.
|
16
|
+
#
|
17
|
+
# The development of this software was funded in-part by Sandia National Laboratories.
|
18
|
+
# See https://github.com/OpenC3/openc3-cosmos-cfdp/pull/12 for details
|
16
19
|
|
17
20
|
require_relative 'cfdp_transaction'
|
18
21
|
|
@@ -127,6 +130,8 @@ class CfdpSourceTransaction < CfdpTransaction
|
|
127
130
|
@source_entity = CfdpMib.source_entity
|
128
131
|
@destination_entity = CfdpMib.entity(destination_entity_id)
|
129
132
|
raise "Unknown destination entity: #{destination_entity_id}" unless @destination_entity
|
133
|
+
version = @destination_entity['protocol_version_number']
|
134
|
+
raise "Closure requested not available in version 0" if version == 0 and closure_requested == "CLOSURE_REQUESTED"
|
130
135
|
@transmission_mode = transmission_mode
|
131
136
|
@transmission_mode = @destination_entity['default_transmission_mode'].upcase unless @transmission_mode
|
132
137
|
@target_name, @packet_name, @item_name = @destination_entity["cmd_info"]
|
@@ -180,7 +180,7 @@ class CfdpTransaction
|
|
180
180
|
|
181
181
|
def get_checksum(checksum_type)
|
182
182
|
case checksum_type
|
183
|
-
when 0 # Modular Checksum
|
183
|
+
when 0, nil # Modular Checksum
|
184
184
|
return CfdpChecksum.new
|
185
185
|
when 1 # Proximity-1 CRC-32 - Poly: 0x00A00805 - Reference CCSDS-211.2-B-3 - Unsure of correct xor/reflect
|
186
186
|
return CfdpCrcChecksum.new(0x00A00805, 0x00000000, false, false)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2025 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# Licensed for Evaluation and Educational Use
|
@@ -13,6 +13,9 @@
|
|
13
13
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
14
14
|
#
|
15
15
|
# The development of this software was funded in-whole or in-part by MethaneSAT LLC.
|
16
|
+
#
|
17
|
+
# The development of this software was funded in-part by Sandia National Laboratories.
|
18
|
+
# See https://github.com/OpenC3/openc3-cosmos-cfdp/pull/12 for details
|
16
19
|
|
17
20
|
require 'thread'
|
18
21
|
require 'openc3/config/config_parser'
|
@@ -144,6 +147,10 @@ class CfdpUser
|
|
144
147
|
@source_threads.each do |st|
|
145
148
|
st.kill if st.alive?
|
146
149
|
end
|
150
|
+
|
151
|
+
@item_name_lookup = {}
|
152
|
+
@source_transactions = []
|
153
|
+
@source_threads = []
|
147
154
|
end
|
148
155
|
|
149
156
|
def start_source_transaction(params, proxy_response_info: nil)
|
@@ -155,6 +162,7 @@ class CfdpUser
|
|
155
162
|
if params[:remote_entity_id] and Integer(params[:remote_entity_id]) != CfdpMib.source_entity_id
|
156
163
|
# Proxy Put
|
157
164
|
destination_entity = CfdpMib.entity(Integer(params[:destination_entity_id]))
|
165
|
+
version = destination_entity['protocol_version_number']
|
158
166
|
pdu = CfdpPdu.build_initial_pdu(type: "FILE_DIRECTIVE", destination_entity: destination_entity, file_size: 0, segmentation_control: "NOT_PRESERVED", transmission_mode: nil)
|
159
167
|
messages_to_user = []
|
160
168
|
# messages_to_user << pdu.build_originating_transaction_id_message(source_entity_id: CfdpMib.source_entity.id, sequence_number: transaction.transaction_seq_num)
|
@@ -183,7 +191,7 @@ class CfdpUser
|
|
183
191
|
if params[:segmentation_control]
|
184
192
|
messages_to_user << pdu.build_proxy_segmentation_control_message(segmentation_control: params[:segmentation_control])
|
185
193
|
end
|
186
|
-
if params[:closure_requested]
|
194
|
+
if version != 0 and params[:closure_requested]
|
187
195
|
messages_to_user << pdu.build_proxy_closure_request_message(closure_requested: params[:closure_requested])
|
188
196
|
end
|
189
197
|
OpenC3::Logger.info("CFDP Transaction #{transaction.id} Proxy Put to Remote Entity #{params[:remote_entity_id]}, Destination Entity #{params[:destination_entity_id]}\nSource File Name: #{params[:source_file_name]}\nDestination File Name: #{params[:destination_file_name]}", scope: ENV['OPENC3_SCOPE'])
|
@@ -494,8 +502,9 @@ class CfdpUser
|
|
494
502
|
end
|
495
503
|
params[:messages_to_user] = []
|
496
504
|
destination_entity = CfdpMib.entity(metadata_pdu_hash["SOURCE_ENTITY_ID"])
|
505
|
+
version = destination_entity['protocol_version_number']
|
497
506
|
pdu = CfdpPdu.build_initial_pdu(type: "FILE_DIRECTIVE", destination_entity: destination_entity, file_size: 0, segmentation_control: "NOT_PRESERVED", transmission_mode: nil)
|
498
|
-
params[:messages_to_user] << pdu.build_directory_listing_response_message(response_code: "SUCCESSFUL", directory_name: directory_name, directory_file_name: directory_file_name)
|
507
|
+
params[:messages_to_user] << pdu.build_directory_listing_response_message(response_code: "SUCCESSFUL", directory_name: directory_name, directory_file_name: directory_file_name, version: version)
|
499
508
|
params[:messages_to_user] << pdu.build_originating_transaction_id_message(source_entity_id: metadata_pdu_hash["SOURCE_ENTITY_ID"], sequence_number: metadata_pdu_hash["SEQUENCE_NUMBER"])
|
500
509
|
start_source_transaction(params)
|
501
510
|
else
|
@@ -505,8 +514,9 @@ class CfdpUser
|
|
505
514
|
params[:destination_file_name] = nil
|
506
515
|
params[:messages_to_user] = []
|
507
516
|
destination_entity = CfdpMib.entity(metadata_pdu_hash["SOURCE_ENTITY_ID"])
|
517
|
+
version = destination_entity['protocol_version_number']
|
508
518
|
pdu = CfdpPdu.build_initial_pdu(type: "FILE_DIRECTIVE", destination_entity: destination_entity, file_size: 0, segmentation_control: "NOT_PRESERVED", transmission_mode: nil)
|
509
|
-
params[:messages_to_user] << pdu.build_directory_listing_response_message(response_code: "UNSUCCESSFUL", directory_name: directory_name, directory_file_name: directory_file_name)
|
519
|
+
params[:messages_to_user] << pdu.build_directory_listing_response_message(response_code: "UNSUCCESSFUL", directory_name: directory_name, directory_file_name: directory_file_name, version: version)
|
510
520
|
params[:messages_to_user] << pdu.build_originating_transaction_id_message(source_entity_id: metadata_pdu_hash["SOURCE_ENTITY_ID"], sequence_number: metadata_pdu_hash["SEQUENCE_NUMBER"])
|
511
521
|
start_source_transaction(params)
|
512
522
|
end
|
@@ -1,18 +1,7 @@
|
|
1
1
|
require_relative "boot"
|
2
2
|
|
3
3
|
require "rails"
|
4
|
-
# Pick the frameworks you want:
|
5
|
-
# require "active_model/railtie"
|
6
|
-
# require "active_job/railtie"
|
7
|
-
# require "active_record/railtie"
|
8
|
-
# require "active_storage/engine"
|
9
4
|
require "action_controller/railtie"
|
10
|
-
# require "action_mailer/railtie"
|
11
|
-
# require "action_mailbox/engine"
|
12
|
-
# require "action_text/engine"
|
13
|
-
# require "action_view/railtie"
|
14
|
-
# require "action_cable/engine"
|
15
|
-
# require "rails/test_unit/railtie"
|
16
5
|
|
17
6
|
# Require the gems listed in Gemfile, including any gems
|
18
7
|
# you've limited to :test, :development, or :production.
|
@@ -28,7 +28,7 @@ Rails.application.configure do
|
|
28
28
|
config.cache_store = :null_store
|
29
29
|
|
30
30
|
# Raise exceptions instead of rendering exception templates.
|
31
|
-
config.action_dispatch.show_exceptions =
|
31
|
+
config.action_dispatch.show_exceptions = :none
|
32
32
|
|
33
33
|
# Disable request forgery protection in test environment.
|
34
34
|
config.action_controller.allow_forgery_protection = false
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2025 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# Licensed for Evaluation and Educational Use
|
@@ -13,6 +13,9 @@
|
|
13
13
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
14
14
|
#
|
15
15
|
# The development of this software was funded in-whole or in-part by MethaneSAT LLC.
|
16
|
+
#
|
17
|
+
# The development of this software was funded in-part by Sandia National Laboratories.
|
18
|
+
# See https://github.com/OpenC3/openc3-cosmos-cfdp/pull/12 for details
|
16
19
|
|
17
20
|
class CfdpPdu < OpenC3::Packet
|
18
21
|
def self.decom_file_data_pdu_contents(pdu, pdu_hash, variable_data)
|
@@ -58,10 +61,11 @@ class CfdpPdu < OpenC3::Packet
|
|
58
61
|
end
|
59
62
|
|
60
63
|
def define_file_data_pdu_contents
|
64
|
+
version = read("VERSION")
|
61
65
|
smf = read("SEGMENT_METADATA_FLAG")
|
62
66
|
|
63
67
|
s = nil
|
64
|
-
if smf == "PRESENT"
|
68
|
+
if version != 0 and smf == "PRESENT"
|
65
69
|
s = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
|
66
70
|
item = s.append_item("RECORD_CONTINUATION_STATE", 2, :UINT)
|
67
71
|
item.states = RECORD_CONTINUATION_STATES
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2025 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# Licensed for Evaluation and Educational Use
|
@@ -13,6 +13,9 @@
|
|
13
13
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
14
14
|
#
|
15
15
|
# The development of this software was funded in-whole or in-part by MethaneSAT LLC.
|
16
|
+
#
|
17
|
+
# The development of this software was funded in-part by Sandia National Laboratories.
|
18
|
+
# See https://github.com/OpenC3/openc3-cosmos-cfdp/pull/12 for details
|
16
19
|
|
17
20
|
class CfdpPdu < OpenC3::Packet
|
18
21
|
def self.decom_finished_pdu_contents(pdu, pdu_hash, variable_data)
|
@@ -21,6 +24,9 @@ class CfdpPdu < OpenC3::Packet
|
|
21
24
|
pdu_hash["CONDITION_CODE"] = s.read("CONDITION_CODE")
|
22
25
|
pdu_hash["DELIVERY_CODE"] = s.read("DELIVERY_CODE")
|
23
26
|
pdu_hash["FILE_STATUS"] = s.read("FILE_STATUS")
|
27
|
+
if pdu_hash['VERSION'] == 0
|
28
|
+
pdu_hash["END_SYSTEM_STATUS"] = s.read("END_SYSTEM_STATUS")
|
29
|
+
end
|
24
30
|
variable_data = variable_data[s.defined_length..-1]
|
25
31
|
while variable_data.length > 0
|
26
32
|
variable_data = decom_tlv(pdu, pdu_hash, variable_data)
|
@@ -45,7 +51,7 @@ class CfdpPdu < OpenC3::Packet
|
|
45
51
|
pdu_header_part_1_length -= CRC_BYTE_SIZE if destination_entity['crcs_required'] # PDU_DATA_LENGTH field should contain CRC length
|
46
52
|
pdu_header = pdu.build_variable_header(source_entity_id: source_entity['id'], transaction_seq_num: transaction_seq_num, destination_entity_id: destination_entity['id'], directive_code: "FINISHED")
|
47
53
|
pdu_header_part_2_length = pdu_header.length - DIRECTIVE_CODE_BYTE_SIZE # Minus 1 = Directive code is part of data per 5.2.1.1
|
48
|
-
pdu_contents = pdu.build_finished_pdu_contents(condition_code: condition_code, delivery_code: delivery_code, file_status: file_status, filestore_responses: filestore_responses, fault_location_entity_id: fault_location_entity_id)
|
54
|
+
pdu_contents = pdu.build_finished_pdu_contents(destination_entity: destination_entity, condition_code: condition_code, delivery_code: delivery_code, file_status: file_status, filestore_responses: filestore_responses, fault_location_entity_id: fault_location_entity_id)
|
49
55
|
pdu.write("VARIABLE_DATA", pdu_header + pdu_contents)
|
50
56
|
pdu.write("PDU_DATA_LENGTH", pdu.length - pdu_header_part_1_length - pdu_header_part_2_length)
|
51
57
|
if destination_entity['crcs_required']
|
@@ -59,7 +65,7 @@ class CfdpPdu < OpenC3::Packet
|
|
59
65
|
s = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
|
60
66
|
item = s.append_item("CONDITION_CODE", 4, :UINT)
|
61
67
|
item.states = CONDITION_CODES
|
62
|
-
s.append_item("
|
68
|
+
item = s.append_item("END_SYSTEM_STATUS", 1, :UINT) # This is SPARE in version 1
|
63
69
|
item = s.append_item("DELIVERY_CODE", 1, :UINT)
|
64
70
|
item.states = DELIVERY_CODES
|
65
71
|
item = s.append_item("FILE_STATUS", 2, :UINT)
|
@@ -67,11 +73,17 @@ class CfdpPdu < OpenC3::Packet
|
|
67
73
|
return s
|
68
74
|
end
|
69
75
|
|
70
|
-
def build_finished_pdu_contents(condition_code:, delivery_code:, file_status:, filestore_responses: [], fault_location_entity_id: nil)
|
76
|
+
def build_finished_pdu_contents(destination_entity:, condition_code:, delivery_code:, file_status:, filestore_responses: [], fault_location_entity_id: nil)
|
77
|
+
version = destination_entity['protocol_version_number']
|
78
|
+
|
71
79
|
structures = []
|
72
80
|
s = define_finished_pdu_contents()
|
73
81
|
s.write("CONDITION_CODE", condition_code)
|
74
|
-
|
82
|
+
if version >= 1
|
83
|
+
s.write("END_SYSTEM_STATUS", 0) # This Spare bit should probably be 0 - not specified in the standard
|
84
|
+
else
|
85
|
+
s.write("END_SYSTEM_STATUS", 1) # 1 = Generated by End System
|
86
|
+
end
|
75
87
|
s.write("DELIVERY_CODE", delivery_code)
|
76
88
|
s.write("FILE_STATUS", file_status)
|
77
89
|
structures << s
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
# Copyright
|
3
|
+
# Copyright 2025 OpenC3, Inc.
|
4
4
|
# All Rights Reserved.
|
5
5
|
#
|
6
6
|
# Licensed for Evaluation and Educational Use
|
@@ -13,13 +13,20 @@
|
|
13
13
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
14
14
|
#
|
15
15
|
# The development of this software was funded in-whole or in-part by MethaneSAT LLC.
|
16
|
+
#
|
17
|
+
# The development of this software was funded in-part by Sandia National Laboratories.
|
18
|
+
# See https://github.com/OpenC3/openc3-cosmos-cfdp/pull/12 for details
|
16
19
|
|
17
20
|
class CfdpPdu < OpenC3::Packet
|
18
21
|
def self.decom_metadata_pdu_contents(pdu, pdu_hash, variable_data)
|
19
22
|
s, s2 = pdu.define_metadata_pdu_contents
|
20
23
|
s.buffer = variable_data
|
21
|
-
pdu_hash[
|
22
|
-
|
24
|
+
if pdu_hash['VERSION'] >= 1
|
25
|
+
pdu_hash["CLOSURE_REQUESTED"] = s.read("CLOSURE_REQUESTED")
|
26
|
+
pdu_hash["CHECKSUM_TYPE"] = s.read("CHECKSUM_TYPE")
|
27
|
+
else
|
28
|
+
pdu_hash["SEGMENTATION_CONTROL"] = s.read("SEGMENTATION_CONTROL")
|
29
|
+
end
|
23
30
|
pdu_hash["FILE_SIZE"] = s.read("FILE_SIZE")
|
24
31
|
source_file_name_length = s.read("SOURCE_FILE_NAME_LENGTH")
|
25
32
|
s.buffer = variable_data[0..(s.defined_length + source_file_name_length - 1)]
|
@@ -59,7 +66,8 @@ class CfdpPdu < OpenC3::Packet
|
|
59
66
|
else
|
60
67
|
checksum_type = 0
|
61
68
|
end
|
62
|
-
|
69
|
+
# This always sets the checksum type to 0 if version is 0
|
70
|
+
pdu_contents = pdu.build_metadata_pdu_contents(destination_entity: destination_entity, segmentation_control: segmentation_control, source_entity: source_entity, closure_requested: closure_requested, checksum_type: checksum_type, file_size: file_size, source_file_name: source_file_name, destination_file_name: destination_file_name, options: options)
|
63
71
|
pdu.write("VARIABLE_DATA", pdu_header + pdu_contents)
|
64
72
|
pdu.write("PDU_DATA_LENGTH", pdu.length - pdu_header_part_1_length - pdu_header_part_2_length)
|
65
73
|
if destination_entity['crcs_required']
|
@@ -71,7 +79,8 @@ class CfdpPdu < OpenC3::Packet
|
|
71
79
|
|
72
80
|
def define_metadata_pdu_contents
|
73
81
|
s = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
|
74
|
-
s.append_item("
|
82
|
+
item = s.append_item("SEGMENTATION_CONTROL", 1, :UINT) # RESERVED in version 1
|
83
|
+
item.states = SEGMENTATION_MODES
|
75
84
|
item = s.append_item("CLOSURE_REQUESTED", 1, :UINT)
|
76
85
|
item.states = CLOSURE_MODES
|
77
86
|
s.append_item("RESERVED2", 2, :UINT)
|
@@ -92,16 +101,24 @@ class CfdpPdu < OpenC3::Packet
|
|
92
101
|
return s, s2
|
93
102
|
end
|
94
103
|
|
95
|
-
def build_metadata_pdu_contents(source_entity:, closure_requested:, checksum_type:, file_size:, source_file_name: nil, destination_file_name: nil, options: [])
|
104
|
+
def build_metadata_pdu_contents(destination_entity:, segmentation_control:, source_entity:, closure_requested:, checksum_type:, file_size:, source_file_name: nil, destination_file_name: nil, options: [])
|
105
|
+
version = destination_entity['protocol_version_number']
|
96
106
|
s, s2 = define_metadata_pdu_contents()
|
97
|
-
|
98
|
-
|
99
|
-
|
107
|
+
if version >= 1
|
108
|
+
s.write("SEGMENTATION_CONTROL", 0) # Always 0 in version 1
|
109
|
+
if closure_requested
|
110
|
+
s.write("CLOSURE_REQUESTED", closure_requested)
|
111
|
+
else
|
112
|
+
s.write("CLOSURE_REQUESTED", source_entity['transaction_closure_requested'])
|
113
|
+
end
|
114
|
+
s.write("CHECKSUM_TYPE", checksum_type)
|
100
115
|
else
|
101
|
-
s.write("
|
116
|
+
s.write("SEGMENTATION_CONTROL", segmentation_control)
|
117
|
+
s.write("CLOSURE_REQUESTED", 0)
|
118
|
+
s.write("CHECKSUM_TYPE", 0)
|
102
119
|
end
|
103
120
|
s.write("RESERVED2", 0)
|
104
|
-
|
121
|
+
|
105
122
|
s.write("FILE_SIZE", file_size)
|
106
123
|
s.write("SOURCE_FILE_NAME_LENGTH", source_file_name.to_s.length)
|
107
124
|
s.write("SOURCE_FILE_NAME", source_file_name.to_s) if source_file_name.to_s.length > 0
|