openc3 5.0.6

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.
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