openc3 5.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. metadata +849 -0
@@ -0,0 +1,722 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
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. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'nokogiri'
21
+ require 'ostruct'
22
+
23
+ module OpenC3
24
+ class XtceParser
25
+ attr_accessor :current_target_name
26
+
27
+ # Processes a XTCE formatted OpenC3 configuration file
28
+ #
29
+ # @param commands [Hash<String=>Packet>] Hash of all the command packets
30
+ # keyed by the packet name.
31
+ # @param telemetry [Hash<String=>Packet>] Hash of all the telemetry packets
32
+ # keyed by the packet name.
33
+ # @param warnings [Array<String>] Array of strings listing all the warnings
34
+ # that were created while parsing the configuration
35
+ # @param filename [String] The name of the configuration file
36
+ # @param target_name [String] Override the target name found in the XTCE file
37
+ def self.process(commands, telemetry, warnings, filename, target_name = nil)
38
+ XtceParser.new(commands, telemetry, warnings, filename, target_name)
39
+ end
40
+
41
+ def self.reverse_packet_order(target_name, cmd_or_tlm_hash)
42
+ if cmd_or_tlm_hash[target_name]
43
+ packets = []
44
+ names_to_remove = []
45
+ cmd_or_tlm_hash[target_name].each do |packet_name, packet|
46
+ packets << packet
47
+ names_to_remove << packet_name
48
+ end
49
+ cmd_or_tlm_hash[target_name].length.times do |i|
50
+ cmd_or_tlm_hash[target_name].delete(names_to_remove[i])
51
+ end
52
+ packets.reverse_each do |packet|
53
+ cmd_or_tlm_hash[target_name][packet.packet_name] = packet
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def initialize(commands, telemetry, warnings, filename, target_name = nil)
61
+ reset_processing_variables()
62
+ @commands = commands
63
+ @telemetry = telemetry
64
+ @warnings = warnings
65
+ @current_packet = nil
66
+ parse(filename, target_name)
67
+ end
68
+
69
+ def parse(filename, target_name)
70
+ # Fortify complains about Path Manipulation here
71
+ # We have previously validated the file is a .xtce file in packet_config
72
+ # The file is opened read-only and then immediately parsed by Nokogiri
73
+ doc = File.open(filename) { |f| Nokogiri::XML(f, nil, nil, Nokogiri::XML::ParseOptions::STRICT | Nokogiri::XML::ParseOptions::NOBLANKS) }
74
+ # Determine the @current_target_name
75
+ xtce_process_element(doc.root)
76
+ @current_target_name = target_name if target_name
77
+ doc.root.children.each do |child|
78
+ xtce_recurse_element(child) do |element|
79
+ xtce_process_element(element)
80
+ end
81
+ end
82
+ finish_packet()
83
+
84
+ # Remove abstract
85
+ if @commands[@current_target_name]
86
+ @commands[@current_target_name].delete_if { |packet_name, packet| packet.abstract }
87
+ end
88
+ if @telemetry[@current_target_name]
89
+ @telemetry[@current_target_name].delete_if { |packet_name, packet| packet.abstract }
90
+ end
91
+
92
+ # Reverse order of packets for the target so ids work correctly
93
+ XtceParser.reverse_packet_order(@current_target_name, @commands)
94
+ XtceParser.reverse_packet_order(@current_target_name, @telemetry)
95
+
96
+ reset_processing_variables()
97
+ end
98
+
99
+ # Add current packet into hash if it exists
100
+ def finish_packet
101
+ if @current_packet
102
+ @warnings += @current_packet.check_bit_offsets
103
+ set_packet_endianness()
104
+ if @current_cmd_or_tlm == PacketConfig::COMMAND
105
+ PacketParser.check_item_data_types(@current_packet)
106
+ @commands[@current_packet.target_name][@current_packet.packet_name] = @current_packet
107
+ else
108
+ @telemetry[@current_packet.target_name][@current_packet.packet_name] = @current_packet
109
+ end
110
+ @current_packet = nil
111
+ end
112
+ end
113
+
114
+ def set_packet_endianness
115
+ item_endianness = @current_packet.sorted_items.collect do |item|
116
+ # Ignore OpenC3 reserved items
117
+ next if Packet::RESERVED_ITEM_NAMES.include?(item.name)
118
+
119
+ # Strings and Blocks endianness don't matter so ignore them
120
+ item.endianness if item.data_type != :STRING && item.data_type != :BLOCK
121
+ end
122
+ # Compact to get rid of nils from skipping Strings and Blocks
123
+ # Uniq to get rid of duplicates which results in an array of 1 or 2 items
124
+ item_endianness = item_endianness.compact.uniq
125
+ if item_endianness.length == 1 # All items have the same endianness
126
+ # default_endianness is read_only since it affects how items are added
127
+ # thus we have to use instance_variable_set here to override it
128
+ @current_packet.instance_variable_set(:@default_endianness, item_endianness[0])
129
+ end
130
+ end
131
+
132
+ def reset_processing_variables
133
+ @current_target_name = nil
134
+ @current_cmd_or_tlm = nil
135
+ @current_type = nil
136
+ @current_meta_command = nil
137
+ @current_parameter = nil
138
+ @current_argument = nil
139
+ @parameter_types = {}
140
+ @argument_types = {}
141
+ @parameters = {}
142
+ @arguments = {}
143
+ @containers = {}
144
+ end
145
+
146
+ def create_new_type(element)
147
+ current_type = OpenStruct.new
148
+ element.attributes.each do |att_name, att|
149
+ current_type[att.name] = att.value
150
+ end
151
+ if /Argument/.match?(element.name)
152
+ @argument_types[element["name"]] = current_type
153
+ else
154
+ @parameter_types[element["name"]] = current_type
155
+ end
156
+ current_type
157
+ end
158
+
159
+ XTCE_IGNORED_ELEMENTS = ['text', 'AliasSet', 'Alias', 'Header']
160
+
161
+ def xtce_process_element(element)
162
+ if XTCE_IGNORED_ELEMENTS.include?(element.name)
163
+ return false
164
+ end
165
+
166
+ case element.name
167
+ when 'SpaceSystem'
168
+ @current_target_name = element["name"].to_s.upcase
169
+
170
+ when 'TelemetryMetaData'
171
+ finish_packet()
172
+ @current_cmd_or_tlm = PacketConfig::TELEMETRY
173
+
174
+ when 'CommandMetaData'
175
+ finish_packet()
176
+ @current_cmd_or_tlm = PacketConfig::COMMAND
177
+
178
+ when 'ParameterTypeSet', 'EnumerationList', 'ParameterSet', 'ContainerSet',
179
+ 'EntryList', 'DefaultCalibrator', 'DefaultAlarm', 'RestrictionCriteria',
180
+ 'ComparisonList', 'MetaCommandSet', 'ArgumentTypeSet', 'ArgumentList',
181
+ 'ArgumentAssignmentList', 'LocationInContainerInBits'
182
+ # Do Nothing
183
+
184
+ when 'EnumeratedParameterType', 'EnumeratedArgumentType',
185
+ 'IntegerParameterType', 'IntegerArgumentType',
186
+ 'FloatParameterType', 'FloatArgumentType',
187
+ 'StringParameterType', 'StringArgumentType',
188
+ 'BinaryParameterType', 'BinaryArgumentType'
189
+ @current_type = create_new_type(element)
190
+ @current_type.endianness = :BIG_ENDIAN
191
+
192
+ case element.name
193
+ when 'EnumeratedParameterType', 'EnumeratedArgumentType'
194
+ @current_type.xtce_encoding = 'IntegerDataEncoding'
195
+ @current_type.sizeInBits = 8 # This is undocumented but appears to be the design
196
+ when 'IntegerParameterType', 'IntegerArgumentType'
197
+ @current_type.xtce_encoding = 'IntegerDataEncoding'
198
+ @current_type.sizeInBits = 32
199
+ when 'FloatParameterType', 'FloatArgumentType'
200
+ @current_type.xtce_encoding = 'FloatDataEncoding'
201
+ @current_type.sizeInBits = 32
202
+ when 'StringParameterType', 'StringArgumentType'
203
+ @current_type.xtce_encoding = 'StringDataEncoding'
204
+ when 'BinaryParameterType', 'BinaryArgumentType'
205
+ @current_type.xtce_encoding = 'BinaryDataEncoding'
206
+ @current_type.sizeInBits = 8 # This is undocumented but appears to be the design
207
+ end
208
+
209
+ when 'ArrayParameterType', 'ArrayArgumentType'
210
+ @current_type = create_new_type(element)
211
+
212
+ when 'ByteOrderList'
213
+ byte_list = []
214
+ xtce_recurse_element(element) do |block_element|
215
+ if block_element.name == 'Byte'
216
+ if block_element['byteSignificance']
217
+ byte_list << block_element['byteSignificance'].to_i
218
+ end
219
+ end
220
+ true
221
+ end
222
+ if byte_list[0] == 0
223
+ # Little endian will always start with 0 - Its ok if a single byte item is marked little endian
224
+ @current_type.endianness = :LITTLE_ENDIAN
225
+ end
226
+
227
+ # Verify ordering of byte list is supported
228
+ if byte_list[0] >= byte_list[-1]
229
+ ordered_byte_list = byte_list.reverse
230
+ else
231
+ ordered_byte_list = byte_list.clone
232
+ end
233
+ if ordered_byte_list[0] != 0
234
+ msg = "Invalid ByteOrderList detected: #{byte_list.join(", ")}"
235
+ Logger.instance.warn msg
236
+ @warnings << msg
237
+ else
238
+ previous_byte = nil
239
+ ordered_byte_list.each do |byte|
240
+ if previous_byte
241
+ if byte - previous_byte != 1
242
+ msg = "Invalid ByteOrderList detected: #{byte_list.join(", ")}"
243
+ Logger.instance.warn msg
244
+ @warnings << msg
245
+ break
246
+ end
247
+ end
248
+ previous_byte = byte
249
+ end
250
+ end
251
+
252
+ return false # Already recursed
253
+
254
+ when "SizeInBits"
255
+ xtce_recurse_element(element) do |block_element|
256
+ if block_element.name == 'FixedValue'
257
+ @current_type.sizeInBits = Integer(block_element.text)
258
+ false
259
+ else
260
+ true
261
+ end
262
+ end
263
+ return false # Already recursed
264
+
265
+ when 'UnitSet'
266
+ xtce_recurse_element(element) do |block_element|
267
+ if block_element.name == 'Unit'
268
+ units = block_element.text.to_s
269
+ description = block_element['description'].to_s
270
+ description = units if description.empty?
271
+ units = description if units.empty?
272
+
273
+ @current_type.units ||= ''
274
+ if @current_type.units.empty?
275
+ @current_type.units << units
276
+ else
277
+ @current_type.units << ('/' + units)
278
+ end
279
+ @current_type.units << "^#{block_element['power']}" if block_element['power']
280
+
281
+ @current_type.units_full ||= ''
282
+ if @current_type.units_full.empty?
283
+ @current_type.units_full << description
284
+ else
285
+ @current_type.units_full << ('/' + description)
286
+ end
287
+ end
288
+ true
289
+ end
290
+ return false # Already recursed
291
+
292
+ when 'PolynomialCalibrator'
293
+ xtce_recurse_element(element) do |block_element|
294
+ if block_element.name == 'Term'
295
+ exponent = Float(block_element['exponent']).to_i
296
+ @current_type.conversion ||= PolynomialConversion.new()
297
+ @current_type.conversion.coeffs[exponent] = Float(block_element['coefficient'])
298
+ @current_type.conversion.coeffs.each_with_index do |value, index|
299
+ @current_type.conversion.coeffs[index] = 0.0 if value.nil?
300
+ end
301
+ end
302
+ true
303
+ end
304
+ return false # Already recursed
305
+
306
+ when 'StaticAlarmRanges'
307
+ xtce_recurse_element(element) do |block_element|
308
+ if block_element.name == 'WarningRange'
309
+ @current_type.limits ||= [0.0, 0.0, 0.0, 0.0]
310
+ @current_type.limits[1] = Float(block_element['minInclusive']) if block_element['minInclusive']
311
+ @current_type.limits[2] = Float(block_element['maxInclusive']) if block_element['maxInclusive']
312
+ elsif block_element.name == 'CriticalRange'
313
+ @current_type.limits ||= [0.0, 0.0, 0.0, 0.0]
314
+ @current_type.limits[0] = Float(block_element['minInclusive']) if block_element['minInclusive']
315
+ @current_type.limits[3] = Float(block_element['maxInclusive']) if block_element['maxInclusive']
316
+ end
317
+ true
318
+ end
319
+ return false # Already recursed
320
+
321
+ when "ValidRange"
322
+ @current_type.minInclusive = element['minInclusive']
323
+ @current_type.maxInclusive = element['maxInclusive']
324
+
325
+ when 'Enumeration'
326
+ @current_type.states ||= {}
327
+ @current_type.states[element['label']] = Integer(element['value'])
328
+
329
+ when 'IntegerDataEncoding', 'FloatDataEncoding', 'StringDataEncoding', 'BinaryDataEncoding'
330
+ @current_type.xtce_encoding = element.name
331
+ element.attributes.each do |att_name, att|
332
+ @current_type[att.name] = att.value
333
+ end
334
+ @current_type.sizeInBits = 8 unless element.attributes['sizeInBits']
335
+
336
+ case element.attributes['byteOrder'].to_s
337
+ when 'mostSignificantByteFirst'
338
+ @current_type.endianness = :BIG_ENDIAN
339
+ when 'leastSignificantByteFirst'
340
+ @current_type.endianness = :LITTLE_ENDIAN
341
+ end
342
+
343
+ when 'Parameter'
344
+ @current_parameter = OpenStruct.new
345
+ element.attributes.each do |att_name, att|
346
+ @current_parameter[att.name] = att.value
347
+ end
348
+ @parameters[element["name"]] = @current_parameter
349
+
350
+ when 'Argument'
351
+ @current_argument = OpenStruct.new
352
+ element.attributes.each do |att_name, att|
353
+ @current_argument[att.name] = att.value
354
+ end
355
+ @arguments[element["name"]] = @current_argument
356
+
357
+ when 'ParameterProperties'
358
+ element.attributes.each do |att_name, att|
359
+ @current_parameter[att.name] = att.value
360
+ end
361
+
362
+ when "SequenceContainer"
363
+ finish_packet()
364
+ @current_packet = Packet.new(@current_target_name, element['name'], :BIG_ENDIAN, element['shortDescription'])
365
+ @current_packet.abstract = ConfigParser.handle_true_false_nil(element['abstract'])
366
+ @containers[element['name']] = @current_packet
367
+ PacketParser.finish_create_telemetry(@current_packet, @telemetry, {}, @warnings)
368
+
369
+ # Need to check for a BaseContainer now because if we hit it later it will be too late
370
+ xtce_handle_base_container('BaseContainer', element)
371
+
372
+ when 'LongDescription'
373
+ if @current_packet && !@current_packet.description
374
+ @current_packet.description = element.text
375
+ end
376
+
377
+ when 'ParameterRefEntry', 'ArgumentRefEntry', 'ArrayParameterRefEntry', 'ArrayArgumentRefEntry'
378
+ process_ref_entry(element)
379
+ return false # Already recursed
380
+
381
+ when 'BaseContainer'
382
+ # Handled in SequenceContainer/CommandContainer
383
+
384
+ when 'BaseMetaCommand'
385
+ # Handled in MetaCommand
386
+
387
+ when 'Comparison'
388
+ # Need to set ID value for item
389
+ item = @current_packet.get_item(element['parameterRef'])
390
+ item.id_value = Integer(element['value'])
391
+ if @current_cmd_or_tlm == PacketConfig::COMMAND
392
+ item.default = item.id_value
393
+ end
394
+ @current_packet.update_id_items(item)
395
+
396
+ when 'MetaCommand'
397
+ finish_packet()
398
+ @current_packet = Packet.new(@current_target_name, element['name'], :BIG_ENDIAN, element['shortDescription'])
399
+ @current_packet.abstract = ConfigParser.handle_true_false_nil(element['abstract'])
400
+ PacketParser.finish_create_command(@current_packet, @commands, @warnings)
401
+
402
+ # Need to check for a BaseContainer now because if we hit it later it will be too late
403
+ xtce_handle_base_container('BaseMetaCommand', element)
404
+
405
+ when 'CommandContainer'
406
+ @containers[element['name']] = @current_packet
407
+
408
+ # Need to check for a BaseContainer now because if we hit it later it will be too late
409
+ xtce_handle_base_container('BaseContainer', element)
410
+
411
+ when 'ArgumentAssignment'
412
+ # Need to set ID value for item
413
+ item = @current_packet.get_item(element['argumentName'])
414
+ value = element['argumentValue']
415
+ if item.states && item.states[value.to_s.upcase]
416
+ item.id_value = item.states[value.to_s.upcase]
417
+ item.default = item.id_value
418
+ else
419
+ item.id_value = Integer(value)
420
+ item.default = item.id_value
421
+ end
422
+ @current_packet.update_id_items(item)
423
+
424
+ else
425
+ puts " Ignoring Unknown: <#{element.name}>"
426
+
427
+ end # case element.name
428
+
429
+ return true # Recurse further
430
+ end
431
+
432
+ def process_ref_entry(element)
433
+ reference_location, bit_offset = xtce_handle_location_in_container_in_bits(element)
434
+ object, type, data_type, array_type = get_object_types(element)
435
+ bit_size = Integer(type.sizeInBits)
436
+ if array_type
437
+ array_bit_size = process_array_type(element, bit_size)
438
+ else
439
+ array_bit_size = nil # in define_item, nil indicates the item is not an array
440
+ end
441
+
442
+ if bit_offset
443
+ case reference_location
444
+ when 'containerStart'
445
+ item = @current_packet.define_item(object.name, bit_offset, bit_size, data_type, array_bit_size, type.endianness) # overflow = :ERROR, format_string = nil, read_conversion = nil, write_conversion = nil, id_value = nil)
446
+ when 'containerEnd'
447
+ item = @current_packet.define_item(object.name, -bit_offset, bit_size, data_type, array_bit_size, type.endianness) # overflow = :ERROR, format_string = nil, read_conversion = nil, write_conversion = nil, id_value = nil)
448
+ when 'previousEntry', nil
449
+ item = @current_packet.define_item(object.name, @current_packet.length + bit_offset, bit_size, data_type, array_bit_size, type.endianness) # overflow = :ERROR, format_string = nil, read_conversion = nil, write_conversion = nil, id_value = nil)
450
+ when 'nextEntry'
451
+ raise 'nextEntry is not supported'
452
+ end
453
+ else
454
+ item = @current_packet.append_item(object.name, bit_size, data_type, array_bit_size, type.endianness) # overflow = :ERROR, format_string = nil, read_conversion = nil, write_conversion = nil, id_value = nil)
455
+ end
456
+
457
+ item.description = type.shortDescription if type.shortDescription
458
+ item.states = type.states if type.states
459
+ set_units(item, type)
460
+ set_conversion(item, type, data_type)
461
+ set_min_max_default(item, type, data_type)
462
+ set_limits(item, type)
463
+ end
464
+
465
+ def get_object_types(element)
466
+ array_type = nil
467
+ if /Parameter/.match?(element.name)
468
+ # Look up the parameter and parameter type
469
+ parameter = @parameters[element['parameterRef']]
470
+ raise "parameterRef #{element['parameterRef']} not found" unless parameter
471
+
472
+ parameter_type = @parameter_types[parameter.parameterTypeRef]
473
+ raise "parameterTypeRef #{parameter.parameterTypeRef} not found" unless parameter_type
474
+
475
+ if element.name == 'ArrayParameterRefEntry'
476
+ array_type = parameter_type
477
+ parameter_type = @parameter_types[array_type.arrayTypeRef]
478
+ raise "arrayTypeRef #{parameter.arrayTypeRef} not found" unless parameter_type
479
+ end
480
+ refName = 'parameterRef'
481
+ object = parameter
482
+ type = parameter_type
483
+ else
484
+ # Look up the argument and argument type
485
+ if element.name == 'ArrayArgumentRefEntry'
486
+ # Requiring parameterRef for argument arrays appears to be a defect in the schema
487
+ argument = @arguments[element['parameterRef']]
488
+ raise "parameterRef #{element['parameterRef']} not found" unless argument
489
+
490
+ argument_type = @argument_types[argument.argumentTypeRef]
491
+ raise "argumentTypeRef #{argument.argumentTypeRef} not found" unless argument_type
492
+
493
+ array_type = argument_type
494
+ argument_type = @argument_types[array_type.arrayTypeRef]
495
+ raise "arrayTypeRef #{array_type.arrayTypeRef} not found" unless argument_type
496
+
497
+ refName = 'parameterRef'
498
+ else
499
+ argument = @arguments[element['argumentRef']]
500
+ raise "argumentRef #{element['argumentRef']} not found" unless argument
501
+
502
+ argument_type = @argument_types[argument.argumentTypeRef]
503
+ raise "argumentTypeRef #{argument.argumentTypeRef} not found" unless argument_type
504
+
505
+ refName = 'argumentRef'
506
+ end
507
+ object = argument
508
+ type = argument_type
509
+ end
510
+
511
+ data_type = get_data_type(type)
512
+ raise "Referenced Parameter/Argument has no xtce_encoding: #{element[refName]}" unless data_type
513
+
514
+ return [object, type, data_type, array_type]
515
+ end
516
+
517
+ def process_array_type(element, bit_size)
518
+ array_num_items = 1
519
+ # Need to determine dimensions
520
+ xtce_recurse_element(element) do |block_element|
521
+ if block_element.name == 'Dimension'
522
+ starting_index = 0
523
+ ending_index = 0
524
+ block_element.children.each do |child_element|
525
+ if child_element.name == 'StartingIndex'
526
+ child_element.children.each do |child_element2|
527
+ if child_element2.name == 'FixedValue'
528
+ starting_index = child_element2.text.to_i
529
+ end
530
+ end
531
+ elsif child_element.name == 'EndingIndex'
532
+ child_element.children.each do |child_element2|
533
+ if child_element2.name == 'FixedValue'
534
+ ending_index = child_element2.text.to_i
535
+ end
536
+ end
537
+ array_num_items *= ((ending_index - starting_index).abs + 1)
538
+ end
539
+ false # Don't recurse again
540
+ end
541
+ false # Don't recurse again
542
+ else
543
+ true # Keep recursing
544
+ end
545
+ end
546
+ array_num_items * bit_size
547
+ end
548
+
549
+ def get_data_type(type)
550
+ data_type = nil
551
+ case type.xtce_encoding
552
+ when 'IntegerDataEncoding'
553
+ if type.signed == 'false' || type.encoding == 'unsigned'
554
+ data_type = :UINT
555
+ else
556
+ data_type = :INT
557
+ end
558
+ when 'FloatDataEncoding'
559
+ data_type = :FLOAT
560
+ when 'StringDataEncoding'
561
+ data_type = :STRING
562
+ when 'BinaryDataEncoding'
563
+ data_type = :BLOCK
564
+ end
565
+ data_type
566
+ end
567
+
568
+ def set_units(item, type)
569
+ if type.units && type.units_full
570
+ item.units = type.units
571
+ item.units_full = type.units_full
572
+ end
573
+ end
574
+
575
+ def set_conversion(item, type, data_type)
576
+ if type.conversion && type.conversion.class == PolynomialConversion
577
+ if @current_cmd_or_tlm == PacketConfig::COMMAND
578
+ item.write_conversion = type.conversion
579
+ else
580
+ item.read_conversion = type.conversion
581
+ end
582
+ end
583
+ end
584
+
585
+ def set_min_max_default(item, type, data_type)
586
+ return unless @current_cmd_or_tlm == PacketConfig::COMMAND
587
+
588
+ # Need to set min, max, and default
589
+ if data_type == :INT || data_type == :UINT
590
+ if data_type == :INT
591
+ item.range = (-(2**(Integer(type.sizeInBits) - 1)))..((2**(Integer(type.sizeInBits) - 1)) - 1)
592
+ else
593
+ item.range = 0..((2**Integer(type.sizeInBits)) - 1)
594
+ end
595
+ if type.minInclusive && type.maxInclusive
596
+ item.range = Integer(type.minInclusive)..Integer(type.maxInclusive)
597
+ end
598
+ if item.array_size
599
+ item.default = []
600
+ else
601
+ item.default = 0
602
+ if item.states && item.states[type.initialValue.to_s.upcase]
603
+ item.default = Integer(item.states[type.initialValue.to_s.upcase])
604
+ else
605
+ item.default = Integer(type.initialValue) if type.initialValue
606
+ end
607
+ end
608
+ elsif data_type == :FLOAT
609
+ if Integer(type.sizeInBits) == 32
610
+ item.range = -3.402823e38..3.402823e38
611
+ else
612
+ item.range = -Float::MAX..Float::MAX
613
+ end
614
+ if type.minInclusive && type.maxInclusive
615
+ item.range = Float(type.minInclusive)..Float(type.maxInclusive)
616
+ end
617
+ if item.array_size
618
+ item.default = []
619
+ else
620
+ item.default = 0.0
621
+ item.default = Float(type.initialValue) if type.initialValue
622
+ end
623
+ elsif data_type == :STRING || data_type == :BLOCK
624
+ if item.array_size
625
+ item.default = []
626
+ else
627
+ if type.initialValue
628
+ if type.initialValue.upcase.start_with?("0X")
629
+ item.default = type.initialValue.hex_to_byte_string
630
+ else
631
+ # Strip quotes from strings
632
+ if type.initialValue[0] == '"' && type.initialValue[-1] == '"'
633
+ item.default = type.initialValue[1..-2]
634
+ end
635
+ end
636
+ else
637
+ item.default = ''
638
+ end
639
+ end
640
+ end
641
+ end
642
+
643
+ def set_limits(item, type)
644
+ return unless @current_cmd_or_tlm == PacketConfig::TELEMETRY
645
+
646
+ if type.limits
647
+ item.limits.enabled = true
648
+ values = {}
649
+ values[:DEFAULT] = type.limits
650
+ item.limits.values = values
651
+ end
652
+ end
653
+
654
+ def xtce_format_attributes(element)
655
+ string = ''
656
+ element.attributes.each do |att_name, att|
657
+ string << "#{att.name}:#{att.value} "
658
+ end
659
+ if string.length > 0
660
+ string = '( ' + string + ')'
661
+ end
662
+ return string
663
+ end
664
+
665
+ def xtce_recurse_element(element, &block)
666
+ return unless yield(element)
667
+
668
+ element.children.each do |child_element|
669
+ xtce_recurse_element(child_element, &block)
670
+ end
671
+ end
672
+
673
+ def xtce_handle_base_container(base_name, element)
674
+ if element.name == base_name
675
+ # Need to add BaseContainer items to current_packet
676
+ # Lookup the base packet
677
+ if base_name == 'BaseMetaCommand'
678
+ base_packet = @commands[@current_packet.target_name][element['metaCommandRef'].to_s.upcase]
679
+ else
680
+ base_packet = @containers[element['containerRef']]
681
+ end
682
+ if base_packet
683
+ count = 0
684
+ base_packet.sorted_items.each do |item|
685
+ unless ['PACKET_TIMESECONDS', 'PACKET_TIMEFORMATTED', 'RECEIVED_TIMESECONDS', 'RECEIVED_TIMEFORMATTED', 'RECEIVED_COUNT'].include?(item.name)
686
+ begin
687
+ @current_packet.get_item(item.name)
688
+ rescue
689
+ # Item hasn't already been added so define it
690
+ @current_packet.define(item.clone)
691
+ count += 1
692
+ end
693
+ end
694
+ end
695
+ return
696
+ else
697
+ if base_name == 'BaseMetaCommand'
698
+ raise "Unknown #{base_name}: #{element['metaCommandRef']}"
699
+ else
700
+ raise "Unknown #{base_name}: #{element['containerRef']}"
701
+ end
702
+ end
703
+ end
704
+ element.children.each do |child_element|
705
+ xtce_handle_base_container(base_name, child_element)
706
+ end
707
+ end
708
+
709
+ def xtce_handle_location_in_container_in_bits(element)
710
+ element.children.each do |child_element|
711
+ if child_element.name == 'LocationInContainerInBits'
712
+ child_element.children.each do |child_element2|
713
+ if child_element2.name == 'FixedValue'
714
+ return [child_element['referenceLocation'], Integer(child_element2.text)]
715
+ end
716
+ end
717
+ end
718
+ end
719
+ return [nil, nil]
720
+ end
721
+ end
722
+ end