openc3-cosmos-cfdp 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +18 -0
  3. data/README.md +181 -0
  4. data/Rakefile +40 -0
  5. data/lib/cfdp.rb +283 -0
  6. data/lib/cfdp_api.rb +204 -0
  7. data/microservices/CFDP/Gemfile +37 -0
  8. data/microservices/CFDP/Rakefile +6 -0
  9. data/microservices/CFDP/app/controllers/application_controller.rb +46 -0
  10. data/microservices/CFDP/app/controllers/cfdp_controller.rb +222 -0
  11. data/microservices/CFDP/app/models/cfdp_checksum.rb +52 -0
  12. data/microservices/CFDP/app/models/cfdp_crc_checksum.rb +41 -0
  13. data/microservices/CFDP/app/models/cfdp_mib.rb +613 -0
  14. data/microservices/CFDP/app/models/cfdp_model.rb +25 -0
  15. data/microservices/CFDP/app/models/cfdp_null_checksum.rb +29 -0
  16. data/microservices/CFDP/app/models/cfdp_pdu.rb +202 -0
  17. data/microservices/CFDP/app/models/cfdp_receive_transaction.rb +590 -0
  18. data/microservices/CFDP/app/models/cfdp_source_transaction.rb +449 -0
  19. data/microservices/CFDP/app/models/cfdp_topic.rb +58 -0
  20. data/microservices/CFDP/app/models/cfdp_transaction.rb +188 -0
  21. data/microservices/CFDP/app/models/cfdp_user.rb +601 -0
  22. data/microservices/CFDP/bin/rails +4 -0
  23. data/microservices/CFDP/bin/rake +4 -0
  24. data/microservices/CFDP/bin/setup +25 -0
  25. data/microservices/CFDP/config/application.rb +55 -0
  26. data/microservices/CFDP/config/boot.rb +4 -0
  27. data/microservices/CFDP/config/credentials.yml.enc +1 -0
  28. data/microservices/CFDP/config/environment.rb +5 -0
  29. data/microservices/CFDP/config/environments/development.rb +53 -0
  30. data/microservices/CFDP/config/environments/production.rb +75 -0
  31. data/microservices/CFDP/config/environments/test.rb +50 -0
  32. data/microservices/CFDP/config/initializers/application_controller_renderer.rb +8 -0
  33. data/microservices/CFDP/config/initializers/backtrace_silencers.rb +7 -0
  34. data/microservices/CFDP/config/initializers/cfdp_initializer.rb +26 -0
  35. data/microservices/CFDP/config/initializers/cors.rb +16 -0
  36. data/microservices/CFDP/config/initializers/filter_parameter_logging.rb +8 -0
  37. data/microservices/CFDP/config/initializers/inflections.rb +16 -0
  38. data/microservices/CFDP/config/initializers/mime_types.rb +4 -0
  39. data/microservices/CFDP/config/initializers/wrap_parameters.rb +9 -0
  40. data/microservices/CFDP/config/locales/en.yml +29 -0
  41. data/microservices/CFDP/config/puma.rb +38 -0
  42. data/microservices/CFDP/config/routes.rb +16 -0
  43. data/microservices/CFDP/config.ru +5 -0
  44. data/microservices/CFDP/init.sh +9 -0
  45. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_ack.rb +82 -0
  46. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_enum.rb +237 -0
  47. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_eof.rb +87 -0
  48. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_file_data.rb +98 -0
  49. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_finished.rb +114 -0
  50. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_keep_alive.rb +65 -0
  51. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_metadata.rb +116 -0
  52. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_nak.rb +91 -0
  53. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_prompt.rb +60 -0
  54. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_tlv.rb +291 -0
  55. data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_user_ops.rb +749 -0
  56. data/microservices/CFDP/public/robots.txt +1 -0
  57. data/microservices/CFDP/spec/models/cfdp_pdu_ack_spec.rb +114 -0
  58. data/microservices/CFDP/spec/models/cfdp_pdu_eof_spec.rb +159 -0
  59. data/microservices/CFDP/spec/models/cfdp_pdu_file_data_spec.rb +76 -0
  60. data/microservices/CFDP/spec/models/cfdp_pdu_finished_spec.rb +192 -0
  61. data/microservices/CFDP/spec/models/cfdp_pdu_keep_alive_spec.rb +69 -0
  62. data/microservices/CFDP/spec/models/cfdp_pdu_metadata_spec.rb +346 -0
  63. data/microservices/CFDP/spec/models/cfdp_pdu_nak_spec.rb +126 -0
  64. data/microservices/CFDP/spec/models/cfdp_pdu_prompt_spec.rb +94 -0
  65. data/microservices/CFDP/spec/models/cfdp_pdu_spec.rb +111 -0
  66. data/microservices/CFDP/spec/rails_helper.rb +71 -0
  67. data/microservices/CFDP/spec/requests/cfdp_spec.rb +1965 -0
  68. data/microservices/CFDP/spec/spec_helper.rb +200 -0
  69. data/plugin.txt +67 -0
  70. data/targets/CFDPTEST/cmd_tlm/cmd.txt +5 -0
  71. data/targets/CFDPTEST/cmd_tlm/tlm.txt +4 -0
  72. data/targets/CFDPTEST/procedures/cfdp_test_suite.rb +130 -0
  73. data/targets/CFDPTEST/target.txt +4 -0
  74. metadata +118 -0
@@ -0,0 +1,202 @@
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 'openc3/packets/packet'
18
+ require 'openc3/utilities/crc'
19
+
20
+ require 'cfdp_pdu/cfdp_pdu_enum'
21
+ require 'cfdp_pdu/cfdp_pdu_tlv'
22
+ require 'cfdp_pdu/cfdp_pdu_eof'
23
+ require 'cfdp_pdu/cfdp_pdu_finished'
24
+ require 'cfdp_pdu/cfdp_pdu_ack'
25
+ require 'cfdp_pdu/cfdp_pdu_metadata'
26
+ require 'cfdp_pdu/cfdp_pdu_nak'
27
+ require 'cfdp_pdu/cfdp_pdu_prompt'
28
+ require 'cfdp_pdu/cfdp_pdu_keep_alive'
29
+ require 'cfdp_pdu/cfdp_pdu_file_data'
30
+ require 'cfdp_pdu/cfdp_pdu_user_ops'
31
+
32
+ class CfdpPdu < OpenC3::Packet
33
+ def initialize(crcs_required:)
34
+ super()
35
+ append_item("VERSION", 3, :UINT)
36
+ item = append_item("TYPE", 1, :UINT)
37
+ item.states = {"FILE_DIRECTIVE" => 0, "FILE_DATA" => 1}
38
+ item = append_item("DIRECTION", 1, :UINT)
39
+ item.states = {"TOWARD_FILE_RECEIVER" => 0, "TOWARD_FILE_SENDER" => 1}
40
+ item = append_item("TRANSMISSION_MODE", 1, :UINT)
41
+ item.states = TRANSMISSION_MODES
42
+ item = append_item("CRC_FLAG", 1, :UINT)
43
+ item.states = {"CRC_NOT_PRESENT" => 0, "CRC_PRESENT" => 1}
44
+ item = append_item("LARGE_FILE_FLAG", 1, :UINT)
45
+ item.states = {"SMALL_FILE" => 0, "LARGE_FILE" => 1}
46
+ item = append_item("PDU_DATA_LENGTH", 16, :UINT)
47
+ item = append_item("SEGMENTATION_CONTROL", 1, :UINT)
48
+ item.states = SEGMENTATION_MODES
49
+ item = append_item("ENTITY_ID_LENGTH", 3, :UINT)
50
+ item = append_item("SEGMENT_METADATA_FLAG", 1, :UINT)
51
+ item.states = {"NOT_PRESENT" => 0, "PRESENT" => 1}
52
+ item = append_item("SEQUENCE_NUMBER_LENGTH", 3, :UINT)
53
+ if crcs_required
54
+ item = append_item("VARIABLE_DATA", -16, :BLOCK)
55
+ item = define_item("CRC", -16, 16, :UINT)
56
+ else
57
+ item = append_item("VARIABLE_DATA", 0, :BLOCK)
58
+ end
59
+ end
60
+
61
+ def self.decom(pdu_data)
62
+ pdu_hash = {}
63
+ source_entity = CfdpMib.source_entity
64
+ crcs_required = source_entity['crcs_required']
65
+ pdu = new(crcs_required: crcs_required)
66
+ pdu.buffer = pdu_data
67
+
68
+ # Handle CRC
69
+ pdu_hash["CRC_FLAG"] = pdu.read("CRC_FLAG")
70
+ if pdu_hash["CRC_FLAG"] == "CRC_PRESENT"
71
+ unless crcs_required
72
+ # Recreate with CRC
73
+ pdu = new(crcs_required: true)
74
+ pdu.buffer = pdu_data
75
+ end
76
+ pdu_hash["CRC"] = pdu.read("CRC")
77
+ crc16 = OpenC3::Crc16.new
78
+ calculated = crc16.calc(pdu.buffer(false)[0..-3])
79
+ if pdu_hash["CRC"] != calculated
80
+ raise "PDU with invalid CRC received: Received: #{sprintf("0x%04X", pdu_hash["CRC"])}, Calculated: #{sprintf("0x%04X", calculated)}"
81
+ end
82
+ elsif crcs_required
83
+ raise "PDU without required CRC received"
84
+ end
85
+
86
+ # Static header
87
+ keys = [
88
+ "VERSION",
89
+ "TYPE",
90
+ "DIRECTION",
91
+ "TRANSMISSION_MODE",
92
+ "LARGE_FILE_FLAG",
93
+ "PDU_DATA_LENGTH",
94
+ "SEGMENTATION_CONTROL",
95
+ "ENTITY_ID_LENGTH",
96
+ "SEGMENT_METADATA_FLAG",
97
+ "SEQUENCE_NUMBER_LENGTH",
98
+ "VARIABLE_DATA"
99
+ ]
100
+ keys.each do |key|
101
+ pdu_hash[key] = pdu.read(key)
102
+ end
103
+
104
+ # Variable Header
105
+ s = pdu.define_variable_header
106
+ variable_header = pdu_hash['VARIABLE_DATA'][0..(s.defined_length - 1)]
107
+ s.buffer = variable_header
108
+ variable_header_keys = [
109
+ "SOURCE_ENTITY_ID",
110
+ "SEQUENCE_NUMBER",
111
+ "DESTINATION_ENTITY_ID"
112
+ ]
113
+ variable_header_keys << "DIRECTIVE_CODE" if pdu_hash['TYPE'] == "FILE_DIRECTIVE"
114
+ variable_header_keys.each do |key|
115
+ pdu_hash[key] = s.read(key)
116
+ end
117
+
118
+ variable_data = pdu_hash['VARIABLE_DATA'][(s.defined_length)..-1]
119
+
120
+ # PDU Specific Data
121
+ case pdu_hash["DIRECTIVE_CODE"]
122
+ when "EOF"
123
+ decom_eof_pdu_contents(pdu, pdu_hash, variable_data)
124
+ when "FINISHED"
125
+ decom_finished_pdu_contents(pdu, pdu_hash, variable_data)
126
+ when "ACK"
127
+ decom_ack_pdu_contents(pdu, pdu_hash, variable_data)
128
+ when "METADATA"
129
+ decom_metadata_pdu_contents(pdu, pdu_hash, variable_data)
130
+ when "NAK"
131
+ decom_nak_pdu_contents(pdu, pdu_hash, variable_data)
132
+ when "PROMPT"
133
+ decom_prompt_pdu_contents(pdu, pdu_hash, variable_data)
134
+ when "KEEP_ALIVE"
135
+ decom_keep_alive_pdu_contents(pdu, pdu_hash, variable_data)
136
+ else # File Data
137
+ decom_file_data_pdu_contents(pdu, pdu_hash, variable_data)
138
+ end
139
+
140
+ return pdu_hash
141
+ end
142
+
143
+ def self.build_initial_pdu(type:, destination_entity:, file_size:, segmentation_control: "NOT_PRESERVED", transmission_mode: nil)
144
+ pdu = self.new(crcs_required: destination_entity['crcs_required'])
145
+ pdu.write("VERSION", destination_entity['protocol_version_number'])
146
+ pdu.write("TYPE", type)
147
+ pdu.write("DIRECTION", "TOWARD_FILE_RECEIVER")
148
+ if transmission_mode
149
+ transmission_mode = transmission_mode.upcase
150
+ pdu.write("TRANSMISSION_MODE", transmission_mode)
151
+ else
152
+ pdu.write("TRANSMISSION_MODE", destination_entity['default_transmission_mode'].upcase)
153
+ end
154
+ if destination_entity['crcs_required']
155
+ pdu.write("CRC_FLAG", "CRC_PRESENT")
156
+ else
157
+ pdu.write("CRC_FLAG", "CRC_NOT_PRESENT")
158
+ end
159
+ if file_size >= 4_294_967_296
160
+ pdu.write("LARGE_FILE_FLAG", "LARGE_FILE")
161
+ else
162
+ pdu.write("LARGE_FILE_FLAG", "SMALL_FILE")
163
+ end
164
+ pdu.write("SEGMENTATION_CONTROL", segmentation_control)
165
+ pdu.write("ENTITY_ID_LENGTH", destination_entity['entity_id_length'])
166
+ pdu.write("SEGMENT_METADATA_FLAG", "NOT_PRESENT") # Not implemented
167
+ pdu.write("SEQUENCE_NUMBER_LENGTH", destination_entity['sequence_number_length'])
168
+ return pdu
169
+ end
170
+
171
+ def define_variable_header
172
+ id_length = read("ENTITY_ID_LENGTH") + 1
173
+ seq_num_length = read("SEQUENCE_NUMBER_LENGTH") + 1
174
+ type = read("TYPE")
175
+ s = OpenC3::Packet.new(nil, nil, :BIG_ENDIAN)
176
+ s.append_item("SOURCE_ENTITY_ID", id_length * 8, :UINT)
177
+ s.append_item("SEQUENCE_NUMBER", seq_num_length * 8, :UINT, nil, :BIG_ENDIAN, :TRUNCATE)
178
+ s.append_item("DESTINATION_ENTITY_ID", id_length * 8, :UINT)
179
+ if type == "FILE_DIRECTIVE"
180
+ item = s.append_item("DIRECTIVE_CODE", 8, :UINT)
181
+ item.states = DIRECTIVE_CODES
182
+ end
183
+ return s
184
+ end
185
+
186
+ def build_variable_header(source_entity_id:, transaction_seq_num:, destination_entity_id:, directive_code: nil)
187
+ s = define_variable_header()
188
+ s.write("SOURCE_ENTITY_ID", source_entity_id)
189
+ s.write("SEQUENCE_NUMBER", transaction_seq_num)
190
+ s.write("DESTINATION_ENTITY_ID", destination_entity_id)
191
+ s.write("DIRECTIVE_CODE", directive_code) if directive_code
192
+ return s.buffer(false)
193
+ end
194
+
195
+ def self.checksum_type_implemented(checksum_type)
196
+ if [0,1,2,3,15].include?(checksum_type)
197
+ return true
198
+ else
199
+ return false
200
+ end
201
+ end
202
+ end