openc3 5.17.1 → 5.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -4
  3. data/bin/cstol_converter +14 -14
  4. data/bin/openc3cli +190 -8
  5. data/data/config/_interfaces.yaml +5 -5
  6. data/data/config/command_modifiers.yaml +59 -0
  7. data/data/config/interface_modifiers.yaml +19 -9
  8. data/data/config/item_modifiers.yaml +34 -26
  9. data/data/config/microservice.yaml +4 -1
  10. data/data/config/param_item_modifiers.yaml +17 -1
  11. data/data/config/parameter_modifiers.yaml +30 -13
  12. data/data/config/plugins.yaml +9 -5
  13. data/data/config/screen.yaml +9 -9
  14. data/data/config/table_manager.yaml +2 -2
  15. data/data/config/telemetry_modifiers.yaml +9 -4
  16. data/data/config/tool.yaml +4 -1
  17. data/data/config/widgets.yaml +44 -17
  18. data/ext/openc3/ext/config_parser/config_parser.c +1 -1
  19. data/ext/openc3/ext/packet/packet.c +7 -1
  20. data/ext/openc3/ext/platform/platform.c +3 -3
  21. data/ext/openc3/ext/structure/structure.c +56 -76
  22. data/lib/openc3/accessors/accessor.rb +1 -0
  23. data/lib/openc3/accessors/binary_accessor.rb +174 -15
  24. data/lib/openc3/accessors/form_accessor.rb +2 -2
  25. data/lib/openc3/accessors/http_accessor.rb +1 -1
  26. data/lib/openc3/accessors/json_accessor.rb +6 -4
  27. data/lib/openc3/accessors/template_accessor.rb +6 -9
  28. data/lib/openc3/accessors/xml_accessor.rb +1 -1
  29. data/lib/openc3/api/cmd_api.rb +72 -44
  30. data/lib/openc3/api/config_api.rb +10 -10
  31. data/lib/openc3/api/interface_api.rb +28 -21
  32. data/lib/openc3/api/limits_api.rb +30 -30
  33. data/lib/openc3/api/metrics_api.rb +3 -3
  34. data/lib/openc3/api/offline_access_api.rb +5 -5
  35. data/lib/openc3/api/router_api.rb +25 -19
  36. data/lib/openc3/api/settings_api.rb +10 -10
  37. data/lib/openc3/api/stash_api.rb +10 -10
  38. data/lib/openc3/api/target_api.rb +10 -10
  39. data/lib/openc3/api/tlm_api.rb +44 -44
  40. data/lib/openc3/config/config_parser.rb +1 -1
  41. data/lib/openc3/conversions/bit_reverse_conversion.rb +60 -0
  42. data/lib/openc3/conversions/ip_read_conversion.rb +59 -0
  43. data/lib/openc3/conversions/ip_write_conversion.rb +61 -0
  44. data/lib/openc3/conversions/object_read_conversion.rb +88 -0
  45. data/lib/openc3/conversions/object_write_conversion.rb +38 -0
  46. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +7 -7
  47. data/lib/openc3/conversions.rb +6 -1
  48. data/lib/openc3/core_ext/array.rb +5 -5
  49. data/lib/openc3/core_ext/exception.rb +9 -2
  50. data/lib/openc3/core_ext/string.rb +2 -2
  51. data/lib/openc3/interfaces/http_server_interface.rb +1 -0
  52. data/lib/openc3/interfaces/interface.rb +1 -1
  53. data/lib/openc3/interfaces/linc_interface.rb +3 -3
  54. data/lib/openc3/io/json_api.rb +11 -6
  55. data/lib/openc3/io/json_drb.rb +19 -21
  56. data/lib/openc3/io/json_rpc.rb +15 -14
  57. data/lib/openc3/logs/buffered_packet_log_writer.rb +3 -3
  58. data/lib/openc3/logs/log_writer.rb +7 -8
  59. data/lib/openc3/logs/packet_log_writer.rb +7 -7
  60. data/lib/openc3/logs/text_log_writer.rb +4 -4
  61. data/lib/openc3/microservices/decom_microservice.rb +19 -4
  62. data/lib/openc3/microservices/interface_microservice.rb +41 -3
  63. data/lib/openc3/microservices/microservice.rb +11 -11
  64. data/lib/openc3/microservices/reaction_microservice.rb +2 -2
  65. data/lib/openc3/microservices/scope_cleanup_microservice.rb +1 -1
  66. data/lib/openc3/microservices/timeline_microservice.rb +70 -45
  67. data/lib/openc3/microservices/trigger_group_microservice.rb +3 -3
  68. data/lib/openc3/migrations/20240915000000_activity_uuid.rb +28 -0
  69. data/lib/openc3/models/activity_model.rb +124 -92
  70. data/lib/openc3/models/auth_model.rb +31 -2
  71. data/lib/openc3/models/cvt_model.rb +11 -5
  72. data/lib/openc3/models/gem_model.rb +8 -8
  73. data/lib/openc3/models/plugin_model.rb +3 -3
  74. data/lib/openc3/models/reducer_model.rb +2 -2
  75. data/lib/openc3/models/scope_model.rb +45 -14
  76. data/lib/openc3/models/sorted_model.rb +5 -5
  77. data/lib/openc3/models/target_model.rb +7 -4
  78. data/lib/openc3/models/tool_config_model.rb +1 -1
  79. data/lib/openc3/models/tool_model.rb +4 -4
  80. data/lib/openc3/models/widget_model.rb +11 -5
  81. data/lib/openc3/operators/microservice_operator.rb +2 -2
  82. data/lib/openc3/operators/operator.rb +14 -12
  83. data/lib/openc3/packets/command_validator.rb +48 -0
  84. data/lib/openc3/packets/commands.rb +6 -14
  85. data/lib/openc3/packets/packet.rb +49 -16
  86. data/lib/openc3/packets/packet_config.rb +47 -25
  87. data/lib/openc3/packets/packet_item.rb +5 -0
  88. data/lib/openc3/packets/parsers/packet_parser.rb +3 -3
  89. data/lib/openc3/packets/structure.rb +87 -15
  90. data/lib/openc3/packets/structure_item.rb +76 -53
  91. data/lib/openc3/packets/telemetry.rb +6 -27
  92. data/lib/openc3/script/api_shared.rb +7 -5
  93. data/lib/openc3/script/calendar.rb +2 -2
  94. data/lib/openc3/script/commands.rb +6 -4
  95. data/lib/openc3/script/extract.rb +5 -3
  96. data/lib/openc3/script/metadata.rb +2 -2
  97. data/lib/openc3/script/suite.rb +17 -17
  98. data/lib/openc3/script/web_socket_api.rb +11 -0
  99. data/lib/openc3/streams/serial_stream.rb +2 -3
  100. data/lib/openc3/streams/stream.rb +2 -2
  101. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +10 -10
  102. data/lib/openc3/tools/table_manager/table_manager_core.rb +11 -11
  103. data/lib/openc3/tools/table_manager/table_parser.rb +2 -3
  104. data/lib/openc3/topics/command_decom_topic.rb +2 -1
  105. data/lib/openc3/topics/command_topic.rb +3 -3
  106. data/lib/openc3/topics/decom_interface_topic.rb +4 -3
  107. data/lib/openc3/topics/system_events_topic.rb +40 -0
  108. data/lib/openc3/topics/telemetry_decom_topic.rb +1 -1
  109. data/lib/openc3/utilities/authentication.rb +2 -1
  110. data/lib/openc3/utilities/authorization.rb +4 -3
  111. data/lib/openc3/utilities/cli_generator.rb +15 -8
  112. data/lib/openc3/utilities/cosmos_rails_formatter.rb +60 -0
  113. data/lib/openc3/utilities/crc.rb +6 -6
  114. data/lib/openc3/utilities/local_mode.rb +2 -1
  115. data/lib/openc3/utilities/logger.rb +44 -34
  116. data/lib/openc3/utilities/metric.rb +1 -2
  117. data/lib/openc3/utilities/quaternion.rb +18 -18
  118. data/lib/openc3/utilities/target_file.rb +4 -4
  119. data/lib/openc3/version.rb +6 -6
  120. data/lib/openc3/win32/win32_main.rb +2 -2
  121. data/templates/tool_angular/package.json +22 -22
  122. data/templates/tool_react/package.json +13 -13
  123. data/templates/tool_svelte/package.json +14 -14
  124. data/templates/tool_svelte/src/services/openc3-api.js +17 -17
  125. data/templates/tool_vue/package.json +13 -13
  126. data/templates/widget/package.json +11 -12
  127. data/templates/widget/src/Widget.vue +0 -1
  128. metadata +25 -2
@@ -15,7 +15,7 @@
15
15
 
16
16
  /*
17
17
  # Modified by OpenC3, Inc.
18
- # All changes Copyright 2022, OpenC3, Inc.
18
+ # All changes Copyright 2024, OpenC3, Inc.
19
19
  # All Rights Reserved
20
20
  #
21
21
  # This file may also be used under the terms of a commercial license
@@ -69,7 +69,9 @@ static ID id_method_class2 = 0;
69
69
 
70
70
  static ID id_ivar_buffer = 0;
71
71
  static ID id_ivar_bit_offset = 0;
72
+ static ID id_ivar_original_bit_offset = 0;
72
73
  static ID id_ivar_bit_size = 0;
74
+ static ID id_ivar_variable_bit_size = 0;
73
75
  static ID id_ivar_array_size = 0;
74
76
  static ID id_ivar_endianness = 0;
75
77
  static ID id_ivar_data_type = 0;
@@ -384,7 +386,7 @@ static void write_bitfield(int lower_bound, int upper_bound, int bit_offset, int
384
386
  memcpy(&buffer[lower_bound], write_value, num_bytes);
385
387
  }
386
388
 
387
- /* Check the bit size and bit offset for problems. Recalulate the bit offset
389
+ /* Check the bit size and bit offset for problems. Recalculate the bit offset
388
390
  * and return back through the passed in pointer. */
389
391
  static void check_bit_offset_and_size(VALUE self, VALUE type_param, VALUE bit_offset_param, VALUE bit_size_param, VALUE data_type_param, VALUE buffer_param, int *new_bit_offset)
390
392
  {
@@ -1140,7 +1142,7 @@ static VALUE binary_accessor_write(VALUE self, VALUE value, VALUE param_bit_offs
1140
1142
  c_value = NUM2ULL(value);
1141
1143
  break;
1142
1144
  }
1143
- /* If the passed endianess doesn't match the host we reverse the bytes.
1145
+ /* If the passed endianness doesn't match the host we reverse the bytes.
1144
1146
  * Then shift the result over so it's at the bottom of the long long value. */
1145
1147
  if (param_endianness != HOST_ENDIANNESS)
1146
1148
  {
@@ -1360,92 +1362,86 @@ static VALUE read_item(int argc, VALUE *argv, VALUE self)
1360
1362
  */
1361
1363
  static VALUE structure_item_spaceship(VALUE self, VALUE other_item)
1362
1364
  {
1363
- int bit_offset = 0;
1364
- int other_bit_offset = 0;
1365
- int bit_size = 0;
1366
- int other_bit_size = 0;
1365
+ int original_bit_offset = 0;
1366
+ int other_original_bit_offset = 0;
1367
1367
  int create_index = 0;
1368
1368
  int other_create_index = 0;
1369
- int have_create_index = 0;
1370
- volatile VALUE v_create_index = Qnil;
1371
- volatile VALUE v_other_create_index = Qnil;
1369
+ volatile VALUE data_type = Qnil;
1370
+ volatile VALUE other_data_type = Qnil;
1371
+ volatile VALUE variable_bit_size = Qnil;
1372
+ volatile VALUE other_variable_bit_size = Qnil;
1372
1373
 
1373
1374
  if (!RTEST(rb_funcall(other_item, id_method_kind_of, 1, cStructureItem)))
1374
1375
  {
1375
1376
  return Qnil;
1376
1377
  }
1377
1378
 
1378
- bit_offset = FIX2INT(rb_ivar_get(self, id_ivar_bit_offset));
1379
- other_bit_offset = FIX2INT(rb_ivar_get(other_item, id_ivar_bit_offset));
1379
+ original_bit_offset = FIX2INT(rb_ivar_get(self, id_ivar_original_bit_offset));
1380
+ other_original_bit_offset = FIX2INT(rb_ivar_get(other_item, id_ivar_original_bit_offset));
1380
1381
 
1381
- v_create_index = rb_ivar_get(self, id_ivar_create_index);
1382
- v_other_create_index = rb_ivar_get(other_item, id_ivar_create_index);
1383
- if (RTEST(v_create_index) && RTEST(v_other_create_index))
1384
- {
1385
- create_index = FIX2INT(v_create_index);
1386
- other_create_index = FIX2INT(v_other_create_index);
1387
- have_create_index = 1;
1388
- }
1382
+ create_index = FIX2INT(rb_ivar_get(self, id_ivar_create_index));
1383
+ other_create_index = FIX2INT(rb_ivar_get(other_item, id_ivar_create_index));
1384
+
1385
+ data_type = rb_ivar_get(self, id_ivar_data_type);
1386
+ other_data_type = rb_ivar_get(other_item, id_ivar_data_type);
1389
1387
 
1390
- /* Handle same bit offset case */
1391
- if ((bit_offset == 0) && (other_bit_offset == 0))
1388
+ variable_bit_size = rb_ivar_get(self, id_ivar_variable_bit_size);
1389
+ other_variable_bit_size = rb_ivar_get(other_item, id_ivar_variable_bit_size);
1390
+
1391
+ /* Derived items should be first in the list with multiple derived sorted
1392
+ * by create_index */
1393
+ if (data_type == symbol_DERIVED)
1392
1394
  {
1393
- /* Both bit_offsets are 0 so sort by bit_size
1394
- * This allows derived items with bit_size of 0 to be listed first
1395
- * Compare based on bit size */
1396
- bit_size = FIX2INT(rb_ivar_get(self, id_ivar_bit_size));
1397
- other_bit_size = FIX2INT(rb_ivar_get(other_item, id_ivar_bit_size));
1398
- if (bit_size == other_bit_size)
1395
+ if (other_data_type != symbol_DERIVED)
1399
1396
  {
1400
- if (have_create_index)
1397
+ return INT2FIX(-1);
1398
+ }
1399
+ else
1400
+ {
1401
+ if (create_index <= other_create_index)
1401
1402
  {
1402
- if (create_index <= other_create_index)
1403
- {
1404
- return INT2FIX(-1);
1405
- }
1406
- else
1407
- {
1408
- return INT2FIX(1);
1409
- }
1403
+ return INT2FIX(-1);
1410
1404
  }
1411
1405
  else
1412
1406
  {
1413
- return INT2FIX(0);
1407
+ return INT2FIX(1);
1414
1408
  }
1415
1409
  }
1416
- if (bit_size < other_bit_size)
1417
- {
1418
- return INT2FIX(-1);
1419
- }
1420
- else
1421
- {
1422
- return INT2FIX(1);
1423
- }
1410
+ }
1411
+ else if (other_data_type == symbol_DERIVED)
1412
+ {
1413
+ return INT2FIX(1);
1424
1414
  }
1425
1415
 
1426
- /* Handle different bit offsets */
1427
- if (((bit_offset >= 0) && (other_bit_offset >= 0)) || ((bit_offset < 0) && (other_bit_offset < 0)))
1416
+ /* Handle non-derived items */
1417
+ if (((original_bit_offset >= 0) && (other_original_bit_offset >= 0)) || ((original_bit_offset < 0) && (other_original_bit_offset < 0)))
1428
1418
  {
1429
1419
  /* Both Have Same Sign */
1430
- if (bit_offset == other_bit_offset)
1420
+ if (original_bit_offset == other_original_bit_offset)
1431
1421
  {
1432
- if (have_create_index)
1422
+ if (RTEST(variable_bit_size))
1433
1423
  {
1434
- if (create_index <= other_create_index)
1424
+ if (!RTEST(other_variable_bit_size))
1435
1425
  {
1436
1426
  return INT2FIX(-1);
1437
1427
  }
1438
- else
1439
- {
1440
- return INT2FIX(1);
1441
- }
1428
+ /* If both variable_bit_size use create index */
1429
+ }
1430
+ else if (RTEST(other_variable_bit_size))
1431
+ {
1432
+ return INT2FIX(1);
1433
+ }
1434
+
1435
+ if (create_index <= other_create_index)
1436
+ {
1437
+ return INT2FIX(-1);
1442
1438
  }
1443
1439
  else
1444
1440
  {
1445
- return INT2FIX(0);
1441
+ return INT2FIX(1);
1446
1442
  }
1447
1443
  }
1448
- else if (bit_offset < other_bit_offset)
1444
+ else if (original_bit_offset <= other_original_bit_offset)
1449
1445
  {
1450
1446
  return INT2FIX(-1);
1451
1447
  }
@@ -1457,25 +1453,7 @@ static VALUE structure_item_spaceship(VALUE self, VALUE other_item)
1457
1453
  else
1458
1454
  {
1459
1455
  /* Different Signs */
1460
- if (bit_offset == other_bit_offset)
1461
- {
1462
- if (have_create_index)
1463
- {
1464
- if (create_index <= other_create_index)
1465
- {
1466
- return INT2FIX(-1);
1467
- }
1468
- else
1469
- {
1470
- return INT2FIX(1);
1471
- }
1472
- }
1473
- else
1474
- {
1475
- return INT2FIX(0);
1476
- }
1477
- }
1478
- else if (bit_offset < other_bit_offset)
1456
+ if (original_bit_offset < other_original_bit_offset)
1479
1457
  {
1480
1458
  return INT2FIX(1);
1481
1459
  }
@@ -1649,7 +1627,9 @@ void Init_structure(void)
1649
1627
 
1650
1628
  id_ivar_buffer = rb_intern("@buffer");
1651
1629
  id_ivar_bit_offset = rb_intern("@bit_offset");
1630
+ id_ivar_original_bit_offset = rb_intern("@original_bit_offset");
1652
1631
  id_ivar_bit_size = rb_intern("@bit_size");
1632
+ id_ivar_variable_bit_size = rb_intern("@variable_bit_size");
1653
1633
  id_ivar_array_size = rb_intern("@array_size");
1654
1634
  id_ivar_endianness = rb_intern("@endianness");
1655
1635
  id_ivar_data_type = rb_intern("@data_type");
@@ -104,6 +104,7 @@ module OpenC3
104
104
  end
105
105
 
106
106
  def self.convert_to_type(value, item)
107
+ return value if value.nil?
107
108
  case item.data_type
108
109
  when :OBJECT, :ARRAY
109
110
  # Do nothing for complex object types
@@ -14,7 +14,7 @@
14
14
  # GNU Affero General Public License for more details.
15
15
 
16
16
  # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
17
+ # All changes Copyright 2024, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -85,8 +85,6 @@ module OpenC3
85
85
  # Valid overflow types
86
86
  OVERFLOW_TYPES = [:TRUNCATE, :SATURATE, :ERROR, :ERROR_ALLOW_HEX]
87
87
 
88
- protected
89
-
90
88
  # Determines the endianness of the host running this code
91
89
  #
92
90
  # This method is protected to force the use of the constant
@@ -108,13 +106,175 @@ module OpenC3
108
106
  raise ArgumentError, "#{buffer.length} byte buffer insufficient to #{read_write} #{data_type} at bit_offset #{given_bit_offset} with bit_size #{given_bit_size}"
109
107
  end
110
108
 
111
- public
112
-
113
109
  # Store the host endianness so that it only has to be determined once
114
110
  HOST_ENDIANNESS = get_host_endianness()
115
- # Valid endianess
111
+ # Valid endianness
116
112
  ENDIANNESS = [:BIG_ENDIAN, :LITTLE_ENDIAN]
117
113
 
114
+ def handle_read_variable_bit_size(item, _buffer)
115
+ length_value = @packet.read(item.variable_bit_size['length_item_name'], :CONVERTED)
116
+ if item.array_size
117
+ item.array_size = (length_value * item.variable_bit_size['length_bits_per_count']) + item.variable_bit_size['length_value_bit_offset']
118
+ else
119
+ if item.data_type == :INT or item.data_type == :UINT
120
+ # QUIC encoding is currently assumed for individual variable sized integers
121
+ # see https://datatracker.ietf.org/doc/html/rfc9000#name-variable-length-integer-enc
122
+ case length_value
123
+ when 0
124
+ item.bit_size = 6
125
+ when 1
126
+ item.bit_size = 14
127
+ when 2
128
+ item.bit_size = 30
129
+ else
130
+ item.bit_size = 62
131
+ end
132
+ else
133
+ item.bit_size = (length_value * item.variable_bit_size['length_bits_per_count']) + item.variable_bit_size['length_value_bit_offset']
134
+ end
135
+ end
136
+ end
137
+
138
+ def read_item(item, buffer)
139
+ return nil if item.data_type == :DERIVED
140
+ handle_read_variable_bit_size(item, buffer) if item.variable_bit_size
141
+ self.class.read_item(item, buffer)
142
+ end
143
+
144
+ def handle_write_variable_bit_size(item, value, buffer)
145
+ # Update length field to new size
146
+ if (item.data_type == :INT or item.data_type == :UINT) and not item.original_array_size
147
+ # QUIC encoding is currently assumed for individual variable sized integers
148
+ # see https://datatracker.ietf.org/doc/html/rfc9000#name-variable-length-integer-enc
149
+
150
+ # Calculate current bit size so we can preserve bytes after the item
151
+ length_item_value = @packet.read(item.variable_bit_size['length_item_name'], :CONVERTED)
152
+ case length_item_value
153
+ when 0
154
+ current_bit_size = 6
155
+ when 1
156
+ current_bit_size = 14
157
+ when 2
158
+ current_bit_size = 30
159
+ when 3
160
+ current_bit_size = 62
161
+ else
162
+ raise "Value #{item.variable_bit_size['length_item_name']} has unknown QUIC bit size encoding: #{length_item_value}"
163
+ end
164
+
165
+ if item.data_type == :UINT
166
+ if value <= 63
167
+ # Length = 0, value up to 6-bits
168
+ new_bit_size = 6
169
+ item.bit_size = new_bit_size
170
+ @packet.write(item.variable_bit_size['length_item_name'], 0)
171
+ elsif value <= 16383
172
+ # Length = 1, value up to 14-bits
173
+ new_bit_size = 14
174
+ item.bit_size = new_bit_size
175
+ @packet.write(item.variable_bit_size['length_item_name'], 1)
176
+ elsif value <= 1073741823
177
+ # Length = 2, value up to 30-bits
178
+ new_bit_size = 30
179
+ item.bit_size = new_bit_size
180
+ @packet.write(item.variable_bit_size['length_item_name'], 2)
181
+ else
182
+ # Length = 3, value up to 62-bits
183
+ new_bit_size = 62
184
+ item.bit_size = new_bit_size
185
+ @packet.write(item.variable_bit_size['length_item_name'], 3)
186
+ end
187
+ else
188
+ if value <= 31 and value >= -32
189
+ # Length = 0, value up to 6-bits
190
+ new_bit_size = 6
191
+ item.bit_size = new_bit_size
192
+ @packet.write(item.variable_bit_size['length_item_name'], 0)
193
+ elsif value <= 8191 and value >= -8192
194
+ # Length = 1, value up to 14-bits
195
+ new_bit_size = 14
196
+ item.bit_size = new_bit_size
197
+ @packet.write(item.variable_bit_size['length_item_name'], 1)
198
+ elsif value <= 536870911 and value >= -536870912
199
+ # Length = 2, value up to 30-bits
200
+ new_bit_size = 30
201
+ item.bit_size = new_bit_size
202
+ @packet.write(item.variable_bit_size['length_item_name'], 2)
203
+ else
204
+ # Length = 3, value up to 62-bits
205
+ new_bit_size = 62
206
+ item.bit_size = new_bit_size
207
+ @packet.write(item.variable_bit_size['length_item_name'], 3)
208
+ end
209
+ end
210
+
211
+ # Later items need their bit_offset adjusted by the change in this item
212
+ adjustment = new_bit_size - current_bit_size
213
+ bytes = (adjustment / 8)
214
+ item_offset = item.bit_offset / 8
215
+ if bytes > 0
216
+ original_length = buffer.length
217
+ # Add extra bytes because we're adjusting larger
218
+ buffer << ("\000" * bytes)
219
+ # We added bytes to the end so now we have to shift the buffer over
220
+ # NOTE: buffer[offset, length]
221
+ # We copy to the shifted offset location with the remaining buffer length
222
+ buffer[item_offset + bytes, buffer.length - (item_offset + bytes)] =
223
+ # We copy from the original offset location with the original length minus the offset
224
+ buffer[item_offset, original_length - item_offset]
225
+ elsif bytes < 0
226
+ # Remove extra bytes because we're adjusting smaller
227
+ buffer[item_offset + 1, -bytes] = ''
228
+ end
229
+ # Probably not possible to get this condition because we don't allow 0 sized floats
230
+ # but check for it just to cover all the possible data_types
231
+ elsif item.data_type == :FLOAT
232
+ raise "Variable bit size not currently supported for FLOAT data type"
233
+ else
234
+ # STRING, BLOCK, or array types
235
+
236
+ # Calculate current bit size so we can preserve bytes after the item
237
+ length_item_value = @packet.read(item.variable_bit_size['length_item_name'], :CONVERTED)
238
+ current_bit_size = (length_item_value * item.variable_bit_size['length_bits_per_count']) + item.variable_bit_size['length_value_bit_offset']
239
+
240
+ # Calculate bits after this item
241
+ bits_with_item = item.bit_offset + current_bit_size
242
+ bits_after_item = (buffer.length * 8) - bits_with_item
243
+ if item.original_array_size
244
+ item.array_size = -bits_after_item
245
+ else
246
+ item.bit_size = -bits_after_item
247
+ end
248
+
249
+ new_bit_size = value.length * 8
250
+ length_value = (new_bit_size - item.variable_bit_size['length_value_bit_offset']) / item.variable_bit_size['length_bits_per_count']
251
+ @packet.write(item.variable_bit_size['length_item_name'], length_value)
252
+
253
+ # Later items need their bit_offset adjusted by the change in this item
254
+ adjustment = new_bit_size - current_bit_size
255
+ end
256
+
257
+ # Recalculate bit offsets after this item
258
+ if adjustment != 0 and item.bit_offset >= 0
259
+ @packet.sorted_items.each do |sitem|
260
+ if sitem.data_type == :DERIVED or sitem.bit_offset < item.bit_offset
261
+ # Skip items before this item and derived items and items with negative bit offsets
262
+ next
263
+ end
264
+ if sitem != item
265
+ sitem.bit_offset += adjustment
266
+ end
267
+ end
268
+ end
269
+ end
270
+
271
+ def write_item(item, value, buffer)
272
+ return nil if item.data_type == :DERIVED
273
+ handle_write_variable_bit_size(item, value, buffer) if item.variable_bit_size
274
+ self.class.write_item(item, value, buffer)
275
+ end
276
+
277
+ # Note: do not use directly - use instance read_item
118
278
  def self.read_item(item, buffer)
119
279
  return nil if item.data_type == :DERIVED
120
280
  if item.array_size
@@ -124,6 +284,7 @@ module OpenC3
124
284
  end
125
285
  end
126
286
 
287
+ # Note: do not use directly - use instance write_item
127
288
  def self.write_item(item, value, buffer)
128
289
  return nil if item.data_type == :DERIVED
129
290
  if item.array_size
@@ -388,7 +549,7 @@ module OpenC3
388
549
  # String was completely empty
389
550
  if end_bytes > 0
390
551
  # Preserve bytes at end of buffer
391
- buffer << "\000" * value.length
552
+ buffer << ("\000" * value.length)
392
553
  buffer[lower_bound + value.length, end_bytes] = buffer[lower_bound, end_bytes]
393
554
  end
394
555
  elsif bit_size == 0
@@ -400,7 +561,7 @@ module OpenC3
400
561
  elsif (upper_bound > old_upper_bound) && (end_bytes > 0)
401
562
  # Preserve bytes at end of buffer
402
563
  diff = upper_bound - old_upper_bound
403
- buffer << "\000" * diff
564
+ buffer << ("\000" * diff)
404
565
  buffer[upper_bound + 1, end_bytes] = buffer[old_upper_bound + 1, end_bytes]
405
566
  end
406
567
  else # given_bit_size > 0
@@ -587,9 +748,8 @@ module OpenC3
587
748
  return value
588
749
  end
589
750
 
590
- protected
591
751
 
592
- # Check the bit size and bit offset for problems. Recalulate the bit offset
752
+ # Check the bit size and bit offset for problems. Recalculate the bit offset
593
753
  # and return back through the passed in pointer.
594
754
  def self.check_bit_offset_and_size(read_or_write, given_bit_offset, given_bit_size, data_type, buffer)
595
755
  bit_offset = given_bit_offset
@@ -705,7 +865,6 @@ module OpenC3
705
865
  (bit_size == 8) || (bit_size == 16) || (bit_size == 32) || (bit_size == 64)
706
866
  end
707
867
 
708
- public
709
868
 
710
869
  end
711
870
 
@@ -945,10 +1104,10 @@ module OpenC3
945
1104
  # Remove extra bytes from old buffer
946
1105
  buffer[(upper_bound + 1)..old_upper_bound] = ''
947
1106
  elsif upper_bound > old_upper_bound
948
- # Grow buffer and preserve bytes at end of buffer if necesssary
1107
+ # Grow buffer and preserve bytes at end of buffer if necessary
949
1108
  buffer_length = buffer.length
950
1109
  diff = upper_bound - old_upper_bound
951
- buffer << ZERO_STRING * diff
1110
+ buffer << (ZERO_STRING * diff)
952
1111
  if end_bytes > 0
953
1112
  buffer[(upper_bound + 1)..(buffer.length - 1)] = buffer[(old_upper_bound + 1)..(buffer_length - 1)]
954
1113
  end
@@ -975,7 +1134,7 @@ module OpenC3
975
1134
  end
976
1135
 
977
1136
  # Ensure the buffer has enough room
978
- if bit_offset + num_writes * bit_size > buffer.length * 8
1137
+ if bit_offset + (num_writes * bit_size) > buffer.length * 8
979
1138
  raise_buffer_error(:write, buffer, data_type, given_bit_offset, given_bit_size)
980
1139
  end
981
1140
 
@@ -1249,7 +1408,7 @@ module OpenC3
1249
1408
  return false
1250
1409
  end
1251
1410
 
1252
- # If this is true it will enfore that COSMOS DERIVED items must have a
1411
+ # If this is true it will enforce that COSMOS DERIVED items must have a
1253
1412
  # write_conversion to be written
1254
1413
  def enforce_derived_write_conversion(_item)
1255
1414
  return true
@@ -45,7 +45,7 @@ module OpenC3
45
45
  ary = URI.decode_www_form(buffer)
46
46
 
47
47
  # Remove existing item and bad keys from array
48
- ary.reject! {|key, ary_value| (key == item.key) or (key.to_s[0] == "\u0000")}
48
+ ary.reject! {|key, _ary_value| (key == item.key) or (key.to_s[0] == "\u0000")}
49
49
 
50
50
  if Array === value
51
51
  value.each do |value_value|
@@ -79,7 +79,7 @@ module OpenC3
79
79
  return true
80
80
  end
81
81
 
82
- # If this is true it will enfore that COSMOS DERIVED items must have a
82
+ # If this is true it will enforce that COSMOS DERIVED items must have a
83
83
  # write_conversion to be written
84
84
  def enforce_derived_write_conversion(_item)
85
85
  return true
@@ -169,7 +169,7 @@ module OpenC3
169
169
  return @body_accessor.enforce_short_buffer_allowed
170
170
  end
171
171
 
172
- # If this is true it will enfore that COSMOS DERIVED items must have a
172
+ # If this is true it will enforce that COSMOS DERIVED items must have a
173
173
  # write_conversion to be written
174
174
  def enforce_derived_write_conversion(item)
175
175
  case item.name
@@ -22,9 +22,11 @@ require 'openc3/io/json_rpc'
22
22
  require 'openc3/accessors/accessor'
23
23
 
24
24
  # Monkey patch JsonPath to enable create_additions and allow_nan to support binary strings, and NaN, Infinity, -Infinity
25
- class JsonPath
26
- def self.process_object(obj_or_str, opts = {})
27
- obj_or_str.is_a?(String) ? MultiJson.decode(obj_or_str, max_nesting: opts[:max_nesting], create_additions: true, allow_nan: true) : obj_or_str
25
+ OpenC3.disable_warnings do
26
+ class JsonPath
27
+ def self.process_object(obj_or_str, opts = {})
28
+ obj_or_str.is_a?(String) ? MultiJson.decode(obj_or_str, max_nesting: opts[:max_nesting], create_additions: true, allow_nan: true) : obj_or_str
29
+ end
28
30
  end
29
31
  end
30
32
 
@@ -161,7 +163,7 @@ module OpenC3
161
163
  return true
162
164
  end
163
165
 
164
- # If this is true it will enfore that COSMOS DERIVED items must have a
166
+ # If this is true it will enforce that COSMOS DERIVED items must have a
165
167
  # write_conversion to be written
166
168
  def enforce_derived_write_conversion(_item)
167
169
  return true
@@ -38,21 +38,18 @@ module OpenC3
38
38
  # Convert the template into a Regexp for reading each item
39
39
  template = @packet.template.dup
40
40
  template_items = template.scan(Regexp.new("#{escaped_left_char}.*?#{escaped_right_char}"))
41
- escaped_read_template = template
42
- if @left_char != '('
43
- escaped_read_template = escaped_read_template.gsub('(', '\(')
44
- end
45
- if @right_char != ')'
46
- escaped_read_template = escaped_read_template.gsub(')', '\)')
47
- end
41
+ escaped_read_template = Regexp.escape(template)
48
42
 
49
43
  @item_keys = []
50
44
  template_items.each do |item|
51
45
  @item_keys << item[1..-2]
46
+ # If they're using parens we have to escape them
47
+ # since we're working with the already escaped template
48
+ item = "\\#{item}" if @left_char == '('
49
+ item = "#{item[0..-2]}\\)" if @right_char == ')'
52
50
  escaped_read_template.gsub!(item, "(.*)")
53
51
  end
54
52
  @read_regexp = Regexp.new(escaped_read_template)
55
-
56
53
  @configured = true
57
54
  end
58
55
 
@@ -141,7 +138,7 @@ module OpenC3
141
138
  return true
142
139
  end
143
140
 
144
- # If this is true it will enfore that COSMOS DERIVED items must have a
141
+ # If this is true it will enforce that COSMOS DERIVED items must have a
145
142
  # write_conversion to be written
146
143
  def enforce_derived_write_conversion(_item)
147
144
  return true
@@ -88,7 +88,7 @@ module OpenC3
88
88
  return true
89
89
  end
90
90
 
91
- # If this is true it will enfore that COSMOS DERIVED items must have a
91
+ # If this is true it will enforce that COSMOS DERIVED items must have a
92
92
  # write_conversion to be written
93
93
  def enforce_derived_write_conversion(_item)
94
94
  return true