cosmos 3.8.0 → 3.8.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/autohotkey/tools/packet_viewer.ahk +4 -0
  3. data/cosmos.gemspec +1 -1
  4. data/data/crc.txt +277 -277
  5. data/demo/Gemfile +2 -2
  6. data/demo/config/data/crc.txt +176 -176
  7. data/demo/config/targets/INST/cmd_tlm/_ccsds_cmd.txt +2 -2
  8. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +4 -4
  9. data/demo/procedures/example_test.rb +4 -0
  10. data/install/Gemfile +1 -1
  11. data/install/config/data/crc.txt +112 -112
  12. data/lib/cosmos/config/config_parser.rb +35 -1
  13. data/lib/cosmos/core_ext/string.rb +21 -17
  14. data/lib/cosmos/core_ext/time.rb +6 -2
  15. data/lib/cosmos/gui/opengl/gl_viewer.rb +4 -4
  16. data/lib/cosmos/gui/opengl/stl_shape.rb +5 -1
  17. data/lib/cosmos/gui/qt.rb +0 -26
  18. data/lib/cosmos/io/io_multiplexer.rb +27 -45
  19. data/lib/cosmos/packets/packet.rb +64 -24
  20. data/lib/cosmos/packets/packet_config.rb +254 -54
  21. data/lib/cosmos/packets/packet_item.rb +39 -10
  22. data/lib/cosmos/packets/parsers/packet_item_parser.rb +7 -2
  23. data/lib/cosmos/script/commands.rb +5 -0
  24. data/lib/cosmos/script/scripting.rb +5 -5
  25. data/lib/cosmos/script/telemetry.rb +5 -0
  26. data/lib/cosmos/tools/cmd_tlm_server/api.rb +22 -0
  27. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +38 -10
  28. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +48 -9
  29. data/lib/cosmos/tools/test_runner/test_runner.rb +76 -14
  30. data/lib/cosmos/tools/tlm_viewer/widgets/linegraph_widget.rb +11 -2
  31. data/lib/cosmos/tools/tlm_viewer/widgets/timegraph_widget.rb +15 -12
  32. data/lib/cosmos/top_level.rb +29 -32
  33. data/lib/cosmos/version.rb +4 -4
  34. data/spec/config/config_parser_spec.rb +8 -15
  35. data/spec/core_ext/socket_spec.rb +2 -2
  36. data/spec/core_ext/string_spec.rb +10 -0
  37. data/spec/core_ext/time_spec.rb +12 -4
  38. data/spec/io/io_multiplexer_spec.rb +11 -3
  39. data/spec/packets/packet_spec.rb +30 -0
  40. data/spec/script/commands_spec.rb +2 -1
  41. data/spec/script/scripting_spec.rb +22 -0
  42. data/spec/script/telemetry_spec.rb +2 -1
  43. data/spec/spec_helper.rb +2 -2
  44. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +2 -2
  45. data/spec/top_level/top_level_spec.rb +4 -2
  46. metadata +5 -5
@@ -19,53 +19,35 @@ module Cosmos
19
19
  @streams = []
20
20
  end
21
21
 
22
- # @param args [Array<String>] Argument to send to the print method of each
23
- # stream
24
- def print(*args)
25
- @streams.each {|stream| stream.print(*args)}
26
- nil
22
+ def write(*args)
23
+ first = true
24
+ result = nil
25
+ @streams.each do |stream|
26
+ if first
27
+ result = stream.write(*args)
28
+ result = self if result == stream
29
+ first = false
30
+ else
31
+ stream.write(*args)
32
+ end
33
+ end
34
+ result
27
35
  end
28
36
 
29
- # @param args [Array<String>] Argument to send to the printf method of each
30
- # stream
31
- def printf(*args)
32
- @streams.each {|stream| stream.printf(*args)}
33
- nil
34
- end
35
-
36
- # @param object [Object] Argument to send to the putc method of each
37
- # stream
38
- def putc(object)
39
- @streams.each {|stream| stream.putc(object)}
40
- object
41
- end
42
-
43
- # @param args [Array<String>] Argument to send to the puts method of each
44
- # stream
45
- def puts(*args)
46
- @streams.each {|stream| stream.puts(*args)}
47
- nil
48
- end
49
-
50
- # Calls flush on each stream
51
- def flush
52
- @streams.each {|stream| stream.flush}
53
- end
54
-
55
- # @param string [String] Argument to send to the write method of each
56
- # stream
57
- # @return [Integer] The length of the string argument
58
- def write(string)
59
- @streams.each {|stream| stream.write(string)}
60
- string.length
61
- end
62
-
63
- # @param string [String] Argument to send to the write_nonblock method of each
64
- # stream
65
- # @return [Integer] The length of the string argument
66
- def write_nonblock(string)
67
- @streams.each {|stream| stream.write_nonblock(string)}
68
- string.length
37
+ # Forwards IO methods to all streams
38
+ def method_missing(method_name, *args)
39
+ first = true
40
+ result = nil
41
+ @streams.each do |stream|
42
+ if first
43
+ result = stream.send(method_name, *args)
44
+ result = self if result == stream
45
+ first = false
46
+ else
47
+ stream.send(method_name, *args)
48
+ end
49
+ end
50
+ result
69
51
  end
70
52
 
71
53
  # Removes STDOUT and STDERR from the array of streams
@@ -185,36 +185,59 @@ module Cosmos
185
185
  Logger.instance.warn(msg)
186
186
  warnings << msg
187
187
  end
188
- if item.array_size
189
- if item.array_size > 0
190
- expected_next_offset = item.bit_offset + item.array_size
191
- else
192
- expected_next_offset = item.array_size
193
- end
188
+ expected_next_offset = Packet.next_bit_offset(item)
189
+ previous_item = item
190
+ end
191
+ warnings
192
+ end
193
+
194
+ # Checks if the packet has any gaps or overlapped items
195
+ #
196
+ # @return [Boolean] true if the packet has no gaps or overlapped items
197
+ def packed?
198
+ expected_next_offset = nil
199
+ @sorted_items.each do |item|
200
+ if expected_next_offset and item.bit_offset != expected_next_offset
201
+ return false
202
+ end
203
+ expected_next_offset = Packet.next_bit_offset(item)
204
+ end
205
+ true
206
+ end
207
+
208
+ # Returns the bit offset of the next item after the current item if items are packed
209
+ #
210
+ # @param item [PacketItem] The item to calculate the next offset for
211
+ # @return [Integer] Bit Offset of Next Item if Packed
212
+ def self.next_bit_offset(item)
213
+ if item.array_size
214
+ if item.array_size > 0
215
+ next_offset = item.bit_offset + item.array_size
194
216
  else
195
- expected_next_offset = nil
196
- if item.bit_offset > 0
197
- # Handle little-endian bit fields
198
- byte_aligned = ((item.bit_offset % 8) == 0)
199
- if item.endianness == :LITTLE_ENDIAN and (item.data_type == :INT or item.data_type == :UINT) and !(byte_aligned and (item.bit_size == 8 or item.bit_size == 16 or item.bit_size == 32 or item.bit_size == 64))
200
- # Bit offset always refers to the most significant bit of a bitfield
201
- bits_remaining_in_last_byte = 8 - (item.bit_offset % 8)
202
- if item.bit_size > bits_remaining_in_last_byte
203
- expected_next_offset = item.bit_offset + bits_remaining_in_last_byte
204
- end
217
+ next_offset = item.array_size
218
+ end
219
+ else
220
+ next_offset = nil
221
+ if item.bit_offset > 0
222
+ # Handle little-endian bit fields
223
+ byte_aligned = ((item.bit_offset % 8) == 0)
224
+ if item.endianness == :LITTLE_ENDIAN and (item.data_type == :INT or item.data_type == :UINT) and !(byte_aligned and (item.bit_size == 8 or item.bit_size == 16 or item.bit_size == 32 or item.bit_size == 64))
225
+ # Bit offset always refers to the most significant bit of a bitfield
226
+ bits_remaining_in_last_byte = 8 - (item.bit_offset % 8)
227
+ if item.bit_size > bits_remaining_in_last_byte
228
+ next_offset = item.bit_offset + bits_remaining_in_last_byte
205
229
  end
206
230
  end
207
- unless expected_next_offset
208
- if item.bit_size > 0
209
- expected_next_offset = item.bit_offset + item.bit_size
210
- else
211
- expected_next_offset = item.bit_size
212
- end
231
+ end
232
+ unless next_offset
233
+ if item.bit_size > 0
234
+ next_offset = item.bit_offset + item.bit_size
235
+ else
236
+ next_offset = item.bit_size
213
237
  end
214
238
  end
215
- previous_item = item
216
239
  end
217
- warnings
240
+ next_offset
218
241
  end
219
242
 
220
243
  # Id items are used by the identify? method to determine if a raw buffer of
@@ -338,6 +361,15 @@ module Cosmos
338
361
  synchronize_allow_reads() do
339
362
  if @read_conversion_cache[item]
340
363
  value = @read_conversion_cache[item]
364
+
365
+ # Make sure cached value is not modified by anyone by creating
366
+ # a deep copy
367
+ if String === value
368
+ value = value.clone
369
+ elsif Array === value
370
+ value = Marshal.load(Marshal.dump(value))
371
+ end
372
+
341
373
  using_cached_value = true
342
374
  end
343
375
  end
@@ -355,6 +387,14 @@ module Cosmos
355
387
  synchronize_allow_reads() do
356
388
  @read_conversion_cache ||= {}
357
389
  @read_conversion_cache[item] = value
390
+
391
+ # Make sure cached value is not modified by anyone by creating
392
+ # a deep copy
393
+ if String === value
394
+ value = value.clone
395
+ elsif Array === value
396
+ value = Marshal.load(Marshal.dump(value))
397
+ end
358
398
  end
359
399
  end
360
400
  end
@@ -370,10 +370,51 @@ module Cosmos
370
370
  attrs = { :name => (packet_name + '_Base'), :abstract => "true" }
371
371
  xml['xtce'].SequenceContainer(attrs) do
372
372
  xml['xtce'].EntryList do
373
+ packed = packet.packed?
373
374
  packet.sorted_items.each do |item|
374
375
  next if item.data_type == :DERIVED
375
- # TODO: Handle explicit bit offset in packet and nonunique item names
376
- xml['xtce'].ParameterRefEntry(:parameterRef => item.name)
376
+ # TODO: Handle nonunique item names
377
+ if item.array_size
378
+ xml['xtce'].ArrayParameterRefEntry(:parameterRef => item.name) do
379
+ if !packed
380
+ if item.bit_offset >= 0
381
+ xml['xtce'].LocationInContainerInBits(:referenceLocation => 'containerStart') do
382
+ xml['xtce'].FixedValue(item.bit_offset)
383
+ end
384
+ else
385
+ xml['xtce'].LocationInContainerInBits(:referenceLocation => 'containerEnd') do
386
+ xml['xtce'].FixedValue(-item.bit_offset)
387
+ end
388
+ end
389
+ end
390
+ xml['xtce'].DimensionList do
391
+ xml['xtce'].Dimension do
392
+ xml['xtce'].StartingIndex do
393
+ xml['xtce'].FixedValue(0)
394
+ end
395
+ xml['xtce'].EndingIndex do
396
+ xml['xtce'].FixedValue((item.array_size / item.bit_size) - 1)
397
+ end
398
+ end
399
+ end
400
+ end
401
+ else
402
+ if packed
403
+ xml['xtce'].ParameterRefEntry(:parameterRef => item.name)
404
+ else
405
+ xml['xtce'].ParameterRefEntry(:parameterRef => item.name) do
406
+ if item.bit_offset >= 0
407
+ xml['xtce'].LocationInContainerInBits(:referenceLocation => 'containerStart') do
408
+ xml['xtce'].FixedValue(item.bit_offset)
409
+ end
410
+ else
411
+ xml['xtce'].LocationInContainerInBits(:referenceLocation => 'containerEnd') do
412
+ xml['xtce'].FixedValue(-item.bit_offset)
413
+ end
414
+ end
415
+ end
416
+ end
417
+ end
377
418
  end
378
419
  end
379
420
  end # Abstract SequenceContainer
@@ -417,9 +458,50 @@ module Cosmos
417
458
  end # ArgumentList
418
459
  xml['xtce'].CommandContainer(:name => "#{target_name}_#{packet_name}_CommandContainer") do
419
460
  xml['xtce'].EntryList do
461
+ packed = packet.packed?
420
462
  packet.sorted_items.each do |item|
421
463
  next if item.data_type == :DERIVED
422
- xml['xtce'].ArgumentRefEntry(:argumentRef => item.name)
464
+ if item.array_size
465
+ xml['xtce'].ArrayArgumentRefEntry(:parameterRef => item.name) do
466
+ if !packed
467
+ if item.bit_offset >= 0
468
+ xml['xtce'].LocationInContainerInBits(:referenceLocation => 'containerStart') do
469
+ xml['xtce'].FixedValue(item.bit_offset)
470
+ end
471
+ else
472
+ xml['xtce'].LocationInContainerInBits(:referenceLocation => 'containerEnd') do
473
+ xml['xtce'].FixedValue(-item.bit_offset)
474
+ end
475
+ end
476
+ end
477
+ xml['xtce'].DimensionList do
478
+ xml['xtce'].Dimension do
479
+ xml['xtce'].StartingIndex do
480
+ xml['xtce'].FixedValue(0)
481
+ end
482
+ xml['xtce'].EndingIndex do
483
+ xml['xtce'].FixedValue((item.array_size / item.bit_size) - 1)
484
+ end
485
+ end
486
+ end
487
+ end
488
+ else
489
+ if packed
490
+ xml['xtce'].ArgumentRefEntry(:argumentRef => item.name)
491
+ else
492
+ xml['xtce'].ArgumentRefEntry(:argumentRef => item.name) do
493
+ if item.bit_offset >= 0
494
+ xml['xtce'].LocationInContainerInBits(:referenceLocation => 'containerStart') do
495
+ xml['xtce'].FixedValue(item.bit_offset)
496
+ end
497
+ else
498
+ xml['xtce'].LocationInContainerInBits(:referenceLocation => 'containerEnd') do
499
+ xml['xtce'].FixedValue(-item.bit_offset)
500
+ end
501
+ end
502
+ end
503
+ end
504
+ end
423
505
  end
424
506
  end
425
507
  end
@@ -492,11 +574,6 @@ module Cosmos
492
574
  if XTCE_IGNORED_ELEMENTS.include?(element.name)
493
575
  return false
494
576
  end
495
- #~ if element.name == 'LongDescription'
496
- #~ puts "#{' ' * depth}<#{element.name}> #{xtce_format_attributes(element)} #{element.text}"
497
- #~ else
498
- #~ puts "#{' ' * depth}<#{element.name}> #{xtce_format_attributes(element)}"
499
- #~ end
500
577
 
501
578
  case element.name
502
579
  when 'SpaceSystem'
@@ -510,11 +587,17 @@ module Cosmos
510
587
  finish_packet()
511
588
  @current_cmd_or_tlm = COMMAND
512
589
 
513
- when 'ParameterTypeSet', 'EnumerationList', 'ParameterSet', 'ContainerSet', 'EntryList', 'DefaultCalibrator', 'DefaultAlarm', 'RestrictionCriteria', 'ComparisonList', 'MetaCommandSet', 'DefaultCalibrator', 'ArgumentTypeSet', 'ArgumentList', 'ArgumentAssignmentList'
590
+ when 'ParameterTypeSet', 'EnumerationList', 'ParameterSet', 'ContainerSet', 'EntryList', 'DefaultCalibrator', 'DefaultAlarm',
591
+ 'RestrictionCriteria', 'ComparisonList', 'MetaCommandSet', 'DefaultCalibrator', 'ArgumentTypeSet', 'ArgumentList', 'ArgumentAssignmentList',
592
+ 'LocationInContainerInBits'
593
+
514
594
  # Do Nothing
515
595
 
516
- when 'EnumeratedParameterType', 'EnumeratedArgumentType', 'IntegerParameterType', 'IntegerArgumentType', 'FloatParameterType', 'FloatArgumentType', 'StringParameterType', 'StringArgumentType', 'BinaryParameterType', 'BinaryArgumentType'
596
+ when 'EnumeratedParameterType', 'EnumeratedArgumentType', 'IntegerParameterType', 'IntegerArgumentType', 'FloatParameterType', 'FloatArgumentType',
597
+ 'StringParameterType', 'StringArgumentType', 'BinaryParameterType', 'BinaryArgumentType'
598
+
517
599
  @current_type = OpenStruct.new
600
+ @current_type.endianness = :BIG_ENDIAN
518
601
  element.attributes.each do |att_name, att|
519
602
  @current_type[att.name] = att.value
520
603
  end
@@ -541,6 +624,30 @@ module Cosmos
541
624
  @current_type.sizeInBits = 8 # This is undocumented but appears to be the design
542
625
  end
543
626
 
627
+ when 'ArrayParameterType', 'ArrayArgumentType'
628
+ @current_type = OpenStruct.new
629
+ element.attributes.each do |att_name, att|
630
+ @current_type[att.name] = att.value
631
+ end
632
+ if element.name =~ /Argument/
633
+ @argument_types[element["name"]] = @current_type
634
+ else
635
+ @parameter_types[element["name"]] = @current_type
636
+ end
637
+
638
+ when 'ByteOrderList'
639
+ xtce_recurse_element(element, depth + 1) do |element, depth|
640
+ if element.name == 'Byte'
641
+ if element['byteSignificance'] and element['byteSignificance'].to_i == 0
642
+ @current_type.endianness = :LITTLE_ENDIAN
643
+ end
644
+ false
645
+ else
646
+ true
647
+ end
648
+ end
649
+ return false # Already recursed
650
+
544
651
  when "SizeInBits"
545
652
  xtce_recurse_element(element, depth + 1) do |element, depth|
546
653
  if element.name == 'FixedValue'
@@ -581,7 +688,7 @@ module Cosmos
581
688
  when 'PolynomialCalibrator'
582
689
  xtce_recurse_element(element, depth + 1) do |element, depth|
583
690
  if element.name == 'Term'
584
- index = Integer(element['exponent'])
691
+ index = Float(element['exponent']).to_i
585
692
  coeff = Float(element['coefficient'])
586
693
  @current_type.conversion ||= PolynomialConversion.new([])
587
694
  @current_type.conversion.coeffs[index] = coeff
@@ -657,25 +764,80 @@ module Cosmos
657
764
  @current_packet.description = element.text
658
765
  end
659
766
 
660
- when 'ParameterRefEntry', 'ArgumentRefEntry'
661
- if element.name =~ /Argument/
662
- # Look up the argument and argument type
663
- argument = @arguments[element['argumentRef']]
664
- raise "argumentRef #{element['argumentRef']} not found" unless argument
665
- argument_type = @argument_types[argument.argumentTypeRef]
666
- raise "argumentTypeRef #{argument.argumentTypeRef} not found" unless argument_type
667
- refName = 'argumentRef'
668
- object = argument
669
- type = argument_type
670
- else
767
+ when 'ParameterRefEntry', 'ArgumentRefEntry', 'ArrayParameterRefEntry', 'ArrayArgumentRefEntry'
768
+ reference_location, bit_offset = xtce_handle_location_in_container_in_bits(element)
769
+
770
+ array_type = nil
771
+ array_bit_size = nil
772
+ if element.name =~ /Parameter/
671
773
  # Look up the parameter and parameter type
672
774
  parameter = @parameters[element['parameterRef']]
673
775
  raise "parameterRef #{element['parameterRef']} not found" unless parameter
674
776
  parameter_type = @parameter_types[parameter.parameterTypeRef]
675
777
  raise "parameterTypeRef #{parameter.parameterTypeRef} not found" unless parameter_type
778
+ if element.name == 'ArrayParameterRefEntry'
779
+ array_type = parameter_type
780
+ parameter_type = @parameter_types[array_type.arrayTypeRef]
781
+ raise "arrayTypeRef #{parameter.arrayTypeRef} not found" unless parameter_type
782
+ end
676
783
  refName = 'parameterRef'
677
784
  object = parameter
678
785
  type = parameter_type
786
+ else
787
+ # Look up the argument and argument type
788
+ if element.name == 'ArrayArgumentRefEntry'
789
+ # Requiring parameterRef for argument arrays appears to be a defect in the schema
790
+ argument = @arguments[element['parameterRef']]
791
+ raise "parameterRef #{element['parameterRef']} not found" unless argument
792
+ argument_type = @argument_types[argument.argumentTypeRef]
793
+ raise "argumentTypeRef #{argument.argumentTypeRef} not found" unless argument_type
794
+ array_type = argument_type
795
+ argument_type = @argument_types[array_type.arrayTypeRef]
796
+ raise "arrayTypeRef #{array_type.arrayTypeRef} not found" unless argument_type
797
+ refName = 'parameterRef'
798
+ else
799
+ argument = @arguments[element['argumentRef']]
800
+ raise "argumentRef #{element['argumentRef']} not found" unless argument
801
+ argument_type = @argument_types[argument.argumentTypeRef]
802
+ raise "argumentTypeRef #{argument.argumentTypeRef} not found" unless argument_type
803
+ refName = 'argumentRef'
804
+ end
805
+ object = argument
806
+ type = argument_type
807
+ end
808
+
809
+ bit_size = Integer(type.sizeInBits)
810
+
811
+ if array_type
812
+ array_num_items = 1
813
+ # Need to determine dimensions
814
+ xtce_recurse_element(element, depth + 1) do |element, depth|
815
+ if element.name == 'Dimension'
816
+ starting_index = 0
817
+ ending_index = 0
818
+ element.children.each do |child_element|
819
+ if child_element.name == 'StartingIndex'
820
+ child_element.children.each do |child_element2|
821
+ if child_element2.name == 'FixedValue'
822
+ starting_index = child_element2.text.to_i
823
+ end
824
+ end
825
+ elsif child_element.name == 'EndingIndex'
826
+ child_element.children.each do |child_element2|
827
+ if child_element2.name == 'FixedValue'
828
+ ending_index = child_element2.text.to_i
829
+ end
830
+ end
831
+ array_num_items *= ((ending_index - starting_index).abs + 1)
832
+ end
833
+ false # Don't recurse again
834
+ end
835
+ false # Don't recurse again
836
+ else
837
+ true # Keep recursing
838
+ end
839
+ end
840
+ array_bit_size = array_num_items * bit_size
679
841
  end
680
842
 
681
843
  # Add item to packet
@@ -697,7 +859,21 @@ module Cosmos
697
859
  raise "Referenced Parameter/Argument has no xtce_encoding: #{element[refName]}"
698
860
  end
699
861
 
700
- item = @current_packet.append_item(object.name, Integer(type.sizeInBits), data_type) #, array_size = nil, endianness = @default_endianness, overflow = :ERROR, format_string = nil, read_conversion = nil, write_conversion = nil, id_value = nil)
862
+ if bit_offset
863
+ case reference_location
864
+ when 'containerStart'
865
+ 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)
866
+ when 'containerEnd'
867
+ 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)
868
+ when 'previousEntry', nil
869
+ 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)
870
+ when 'nextEntry'
871
+ raise 'nextEntry is not supported'
872
+ end
873
+ else
874
+ 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)
875
+ end
876
+
701
877
  item.description = type.shortDescription if type.shortDescription
702
878
  if type.states
703
879
  item.states = type.states
@@ -713,27 +889,24 @@ module Cosmos
713
889
  end
714
890
 
715
891
  # Need to set min, max, and default
716
- if data_type == :INT
717
- item.range = (-(2 ** (Integer(type.sizeInBits) - 1)))..((2 ** (Integer(type.sizeInBits) - 1)) - 1)
718
- if type.minInclusive and type.maxInclusive
719
- item.range = Integer(type.minInclusive)..Integer(type.maxInclusive)
720
- end
721
- item.default = 0
722
- if item.states and item.states[type.initialValue.to_s.upcase]
723
- item.default = Integer(item.states[type.initialvalue.to_s.upcase])
892
+ if data_type == :INT or data_type == :UINT
893
+ if data_type == :INT
894
+ item.range = (-(2 ** (Integer(type.sizeInBits) - 1)))..((2 ** (Integer(type.sizeInBits) - 1)) - 1)
724
895
  else
725
- item.default = Integer(type.initialValue) if type.initialValue
896
+ item.range = 0..((2 ** Integer(type.sizeInBits)) - 1)
726
897
  end
727
- elsif data_type == :UINT
728
- item.range = 0..((2 ** Integer(type.sizeInBits)) - 1)
729
898
  if type.minInclusive and type.maxInclusive
730
899
  item.range = Integer(type.minInclusive)..Integer(type.maxInclusive)
731
900
  end
732
- item.default = 0
733
- if item.states and item.states[type.initialValue.to_s.upcase]
734
- item.default = Integer(item.states[type.initialValue.to_s.upcase])
901
+ if item.array_size
902
+ item.default = []
735
903
  else
736
- item.default = Integer(type.initialValue) if type.initialValue
904
+ item.default = 0
905
+ if item.states and item.states[type.initialValue.to_s.upcase]
906
+ item.default = Integer(item.states[type.initialValue.to_s.upcase])
907
+ else
908
+ item.default = Integer(type.initialValue) if type.initialValue
909
+ end
737
910
  end
738
911
  elsif data_type == :FLOAT
739
912
  if Integer(type.sizeInBits) == 32
@@ -744,19 +917,31 @@ module Cosmos
744
917
  if type.minInclusive and type.maxInclusive
745
918
  item.range = Float(type.minInclusive)..Float(type.maxInclusive)
746
919
  end
747
- item.default = 0.0
748
- item.default = Float(type.initialValue) if type.initialValue
920
+ if item.array_size
921
+ item.default = []
922
+ else
923
+ item.default = 0.0
924
+ item.default = Float(type.initialValue) if type.initialValue
925
+ end
749
926
  elsif data_type == :STRING
750
- if type.initialValue
751
- item.default = type.initialValue
927
+ if item.array_size
928
+ item.default = []
752
929
  else
753
- item.default = ''
930
+ if type.initialValue
931
+ item.default = type.initialValue
932
+ else
933
+ item.default = ''
934
+ end
754
935
  end
755
936
  elsif data_type == :BLOCK
756
- if type.initialValue
757
- item.default = type.initialValue
937
+ if item.array_size
938
+ item.default = []
758
939
  else
759
- item.default = ''
940
+ if type.initialValue
941
+ item.default = type.initialValue
942
+ else
943
+ item.default = ''
944
+ end
760
945
  end
761
946
  end
762
947
  else
@@ -774,6 +959,8 @@ module Cosmos
774
959
  end
775
960
  end
776
961
 
962
+ return false # Already recursed
963
+
777
964
  when 'BaseContainer'
778
965
  # Handled in SequenceContainer/CommandContainer
779
966
 
@@ -879,6 +1066,19 @@ module Cosmos
879
1066
  end
880
1067
  end
881
1068
 
1069
+ def xtce_handle_location_in_container_in_bits(element)
1070
+ element.children.each do |child_element|
1071
+ if child_element.name == 'LocationInContainerInBits'
1072
+ child_element.children.each do |child_element2|
1073
+ if child_element2.name == 'FixedValue'
1074
+ return [child_element['referenceLocation'], Integer(child_element2.text)]
1075
+ end
1076
+ end
1077
+ end
1078
+ end
1079
+ return [nil, nil]
1080
+ end
1081
+
882
1082
  def process_current_packet(parser, keyword, params)
883
1083
  case keyword
884
1084
 
@@ -1079,9 +1279,9 @@ module Cosmos
1079
1279
  end
1080
1280
  usage = "MINIMUM_VALUE <MINIMUM VALUE>"
1081
1281
  parser.verify_num_parameters(1, 1, usage)
1082
- @current_item.range =
1083
- Range.new(ConfigParser.handle_defined_constants(
1084
- params[0].convert_to_value), @current_item.range.end)
1282
+ min = ConfigParser.handle_defined_constants(
1283
+ params[0].convert_to_value, @current_item.data_type, @current_item.bit_size)
1284
+ @current_item.range = Range.new(min, @current_item.range.end)
1085
1285
 
1086
1286
  # Update the maximum value for the current command parameter
1087
1287
  when 'MAXIMUM_VALUE'
@@ -1090,9 +1290,9 @@ module Cosmos
1090
1290
  end
1091
1291
  usage = "MAXIMUM_VALUE <MAXIMUM VALUE>"
1092
1292
  parser.verify_num_parameters(1, 1, usage)
1093
- @current_item.range =
1094
- Range.new(@current_item.range.begin,
1095
- ConfigParser.handle_defined_constants(params[0].convert_to_value))
1293
+ max = ConfigParser.handle_defined_constants(
1294
+ params[0].convert_to_value, @current_item.data_type, @current_item.bit_size)
1295
+ @current_item.range = Range.new(@current_item.range.begin, max)
1096
1296
 
1097
1297
  # Update the default value for the current command parameter
1098
1298
  when 'DEFAULT_VALUE'
@@ -1105,8 +1305,8 @@ module Cosmos
1105
1305
  (@current_item.data_type == :BLOCK))
1106
1306
  @current_item.default = params[0]
1107
1307
  else
1108
- @current_item.default =
1109
- ConfigParser.handle_defined_constants(params[0].convert_to_value)
1308
+ @current_item.default = ConfigParser.handle_defined_constants(
1309
+ params[0].convert_to_value, @current_item.data_type, @current_item.bit_size)
1110
1310
  end
1111
1311
 
1112
1312
  # Update the overflow type for the current command parameter