openc3 5.18.0 → 5.19.0

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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -4
  3. data/bin/cstol_converter +14 -14
  4. data/bin/openc3cli +189 -7
  5. data/data/config/_interfaces.yaml +1 -1
  6. data/data/config/command_modifiers.yaml +55 -0
  7. data/data/config/interface_modifiers.yaml +1 -1
  8. data/data/config/param_item_modifiers.yaml +1 -1
  9. data/data/config/parameter_modifiers.yaml +1 -1
  10. data/data/config/plugins.yaml +6 -2
  11. data/data/config/screen.yaml +2 -2
  12. data/data/config/table_manager.yaml +2 -2
  13. data/data/config/tool.yaml +4 -1
  14. data/data/config/widgets.yaml +3 -3
  15. data/ext/openc3/ext/config_parser/config_parser.c +1 -1
  16. data/ext/openc3/ext/packet/packet.c +1 -1
  17. data/ext/openc3/ext/platform/platform.c +3 -3
  18. data/ext/openc3/ext/structure/structure.c +56 -76
  19. data/lib/openc3/accessors/binary_accessor.rb +4 -4
  20. data/lib/openc3/accessors/form_accessor.rb +2 -2
  21. data/lib/openc3/accessors/http_accessor.rb +1 -1
  22. data/lib/openc3/accessors/json_accessor.rb +6 -4
  23. data/lib/openc3/accessors/template_accessor.rb +6 -9
  24. data/lib/openc3/accessors/xml_accessor.rb +1 -1
  25. data/lib/openc3/api/cmd_api.rb +35 -11
  26. data/lib/openc3/api/limits_api.rb +1 -1
  27. data/lib/openc3/config/config_parser.rb +1 -1
  28. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +7 -7
  29. data/lib/openc3/core_ext/array.rb +5 -5
  30. data/lib/openc3/core_ext/exception.rb +9 -2
  31. data/lib/openc3/core_ext/string.rb +2 -2
  32. data/lib/openc3/interfaces/http_server_interface.rb +1 -0
  33. data/lib/openc3/interfaces/interface.rb +1 -1
  34. data/lib/openc3/interfaces/linc_interface.rb +3 -3
  35. data/lib/openc3/io/json_api.rb +11 -6
  36. data/lib/openc3/io/json_rpc.rb +1 -1
  37. data/lib/openc3/logs/buffered_packet_log_writer.rb +3 -3
  38. data/lib/openc3/logs/log_writer.rb +7 -8
  39. data/lib/openc3/logs/packet_log_writer.rb +7 -7
  40. data/lib/openc3/logs/text_log_writer.rb +4 -4
  41. data/lib/openc3/microservices/decom_microservice.rb +19 -4
  42. data/lib/openc3/microservices/interface_microservice.rb +41 -3
  43. data/lib/openc3/microservices/reaction_microservice.rb +2 -2
  44. data/lib/openc3/microservices/trigger_group_microservice.rb +3 -3
  45. data/lib/openc3/migrations/20240915000000_activity_uuid.rb +28 -0
  46. data/lib/openc3/models/activity_model.rb +109 -80
  47. data/lib/openc3/models/auth_model.rb +31 -2
  48. data/lib/openc3/models/cvt_model.rb +11 -5
  49. data/lib/openc3/models/gem_model.rb +8 -8
  50. data/lib/openc3/models/plugin_model.rb +3 -3
  51. data/lib/openc3/models/reducer_model.rb +2 -2
  52. data/lib/openc3/models/scope_model.rb +1 -1
  53. data/lib/openc3/models/sorted_model.rb +4 -4
  54. data/lib/openc3/models/target_model.rb +3 -3
  55. data/lib/openc3/models/tool_config_model.rb +1 -1
  56. data/lib/openc3/models/tool_model.rb +4 -4
  57. data/lib/openc3/models/widget_model.rb +11 -5
  58. data/lib/openc3/operators/operator.rb +5 -3
  59. data/lib/openc3/packets/command_validator.rb +48 -0
  60. data/lib/openc3/packets/commands.rb +6 -14
  61. data/lib/openc3/packets/packet.rb +31 -15
  62. data/lib/openc3/packets/packet_config.rb +10 -9
  63. data/lib/openc3/packets/parsers/packet_parser.rb +3 -3
  64. data/lib/openc3/packets/structure.rb +21 -13
  65. data/lib/openc3/packets/structure_item.rb +33 -47
  66. data/lib/openc3/packets/telemetry.rb +6 -27
  67. data/lib/openc3/script/api_shared.rb +7 -5
  68. data/lib/openc3/script/calendar.rb +2 -2
  69. data/lib/openc3/script/commands.rb +6 -4
  70. data/lib/openc3/script/metadata.rb +2 -2
  71. data/lib/openc3/script/suite.rb +17 -17
  72. data/lib/openc3/streams/serial_stream.rb +2 -3
  73. data/lib/openc3/streams/stream.rb +2 -2
  74. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +10 -10
  75. data/lib/openc3/tools/table_manager/table_manager_core.rb +11 -11
  76. data/lib/openc3/tools/table_manager/table_parser.rb +2 -3
  77. data/lib/openc3/topics/command_decom_topic.rb +2 -1
  78. data/lib/openc3/topics/command_topic.rb +3 -3
  79. data/lib/openc3/topics/decom_interface_topic.rb +2 -2
  80. data/lib/openc3/topics/telemetry_decom_topic.rb +1 -1
  81. data/lib/openc3/utilities/authorization.rb +2 -1
  82. data/lib/openc3/utilities/cli_generator.rb +15 -8
  83. data/lib/openc3/utilities/cosmos_rails_formatter.rb +60 -0
  84. data/lib/openc3/utilities/crc.rb +6 -6
  85. data/lib/openc3/utilities/local_mode.rb +2 -1
  86. data/lib/openc3/utilities/logger.rb +44 -34
  87. data/lib/openc3/utilities/metric.rb +1 -2
  88. data/lib/openc3/utilities/quaternion.rb +18 -18
  89. data/lib/openc3/utilities/target_file.rb +4 -4
  90. data/lib/openc3/version.rb +5 -5
  91. data/lib/openc3/win32/win32_main.rb +2 -2
  92. data/templates/tool_angular/package.json +21 -21
  93. data/templates/tool_react/package.json +10 -10
  94. data/templates/tool_svelte/package.json +11 -11
  95. data/templates/tool_svelte/src/services/openc3-api.js +17 -17
  96. data/templates/tool_vue/package.json +9 -9
  97. data/templates/widget/package.json +6 -7
  98. metadata +5 -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");
@@ -108,7 +108,7 @@ module OpenC3
108
108
 
109
109
  # Store the host endianness so that it only has to be determined once
110
110
  HOST_ENDIANNESS = get_host_endianness()
111
- # Valid endianess
111
+ # Valid endianness
112
112
  ENDIANNESS = [:BIG_ENDIAN, :LITTLE_ENDIAN]
113
113
 
114
114
  def handle_read_variable_bit_size(item, _buffer)
@@ -749,7 +749,7 @@ module OpenC3
749
749
  end
750
750
 
751
751
 
752
- # 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
753
753
  # and return back through the passed in pointer.
754
754
  def self.check_bit_offset_and_size(read_or_write, given_bit_offset, given_bit_size, data_type, buffer)
755
755
  bit_offset = given_bit_offset
@@ -1104,7 +1104,7 @@ module OpenC3
1104
1104
  # Remove extra bytes from old buffer
1105
1105
  buffer[(upper_bound + 1)..old_upper_bound] = ''
1106
1106
  elsif upper_bound > old_upper_bound
1107
- # Grow buffer and preserve bytes at end of buffer if necesssary
1107
+ # Grow buffer and preserve bytes at end of buffer if necessary
1108
1108
  buffer_length = buffer.length
1109
1109
  diff = upper_bound - old_upper_bound
1110
1110
  buffer << (ZERO_STRING * diff)
@@ -1408,7 +1408,7 @@ module OpenC3
1408
1408
  return false
1409
1409
  end
1410
1410
 
1411
- # 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
1412
1412
  # write_conversion to be written
1413
1413
  def enforce_derived_write_conversion(_item)
1414
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
@@ -452,7 +452,8 @@ module OpenC3
452
452
  return [target_name, command_name, parameter_name]
453
453
  end
454
454
 
455
- def _cmd_implementation(method_name, *args, range_check:, hazardous_check:, raw:, timeout: nil, log_message: nil, manual: false,
455
+ # NOTE: When adding new keywords to this method, make sure to update script/commands.rb
456
+ def _cmd_implementation(method_name, *args, range_check:, hazardous_check:, raw:, timeout: nil, log_message: nil, manual: false, validate: true,
456
457
  scope: $openc3_scope, token: $openc3_token, **kwargs)
457
458
  extract_string_kwargs_to_args(args, kwargs)
458
459
  unless [nil, true, false].include?(log_message)
@@ -484,7 +485,24 @@ module OpenC3
484
485
  target_name = target_name.upcase
485
486
  cmd_name = cmd_name.upcase
486
487
  cmd_params = cmd_params.transform_keys(&:upcase)
487
- authorize(permission: 'cmd', target_name: target_name, packet_name: cmd_name, manual: manual, scope: scope, token: token)
488
+ user = authorize(permission: 'cmd', target_name: target_name, packet_name: cmd_name, manual: manual, scope: scope, token: token)
489
+ if user.nil?
490
+ user = {}
491
+ user['username'] = ENV['OPENC3_MICROSERVICE_NAME']
492
+
493
+ # Get the caller stack trace to determine the point in the code where the command was called
494
+ # This code works but ultimately we didn't want to overload 'username' and take a performance hit
495
+ # caller.each do |frame|
496
+ # # Look for the following line in the stack trace which indicates custom code
497
+ # # /tmp/d20240827-62-8e57pf/targets/INST/lib/example_limits_response.rb:31:in `call'
498
+ # if frame.include?("/targets/#{target_name}")
499
+ # user = {}
500
+ # # username is the name of the custom code file
501
+ # user['username'] = frame.split("/targets/")[-1].split(':')[0]
502
+ # break
503
+ # end
504
+ # end
505
+ end
488
506
  packet = TargetModel.packet(target_name, cmd_name, type: :CMD, scope: scope)
489
507
  if packet['disabled']
490
508
  error = DisabledError.new
@@ -493,14 +511,6 @@ module OpenC3
493
511
  raise error
494
512
  end
495
513
 
496
- command = {
497
- 'target_name' => target_name,
498
- 'cmd_name' => cmd_name,
499
- 'cmd_params' => cmd_params,
500
- 'range_check' => range_check.to_s,
501
- 'hazardous_check' => hazardous_check.to_s,
502
- 'raw' => raw.to_s
503
- }
504
514
  if log_message.nil? # This means the default was used, no argument was passed
505
515
  log_message = true # Default is true
506
516
  # If the packet has the DISABLE_MESSAGES keyword then no messages by default
@@ -513,9 +523,23 @@ module OpenC3
513
523
  end
514
524
  end
515
525
  end
526
+ cmd_string = _build_cmd_output_string(method_name, target_name, cmd_name, cmd_params, packet)
516
527
  if log_message
517
- Logger.info(_build_cmd_output_string(method_name, target_name, cmd_name, cmd_params, packet), scope: scope)
528
+ Logger.info(cmd_string, scope: scope)
518
529
  end
530
+
531
+ username = user && user['username'] ? user['username'] : 'anonymous'
532
+ command = {
533
+ 'target_name' => target_name,
534
+ 'cmd_name' => cmd_name,
535
+ 'cmd_params' => cmd_params,
536
+ 'range_check' => range_check.to_s,
537
+ 'hazardous_check' => hazardous_check.to_s,
538
+ 'raw' => raw.to_s,
539
+ 'cmd_string' => cmd_string,
540
+ 'username' => username,
541
+ 'validate' => validate.to_s
542
+ }
519
543
  CommandTopic.send_command(command, timeout: timeout, scope: scope)
520
544
  end
521
545
 
@@ -107,7 +107,7 @@ module OpenC3
107
107
  # Favor the first syntax where possible as it is more succinct.
108
108
  #
109
109
  # @param args [String|Array<String>] See the description for calling style
110
- # @return [Boolean] Whether limits are enable for the itme
110
+ # @return [Boolean] Whether limits are enable for the item
111
111
  def limits_enabled?(*args, manual: false, scope: $openc3_scope, token: $openc3_token)
112
112
  target_name, packet_name, item_name = _tlm_process_args(args, 'limits_enabled?', scope: scope)
113
113
  authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, manual: manual, scope: scope, token: token)
@@ -190,7 +190,7 @@ module OpenC3
190
190
  # @param remove_quotes [Boolean] Whether to remove beginning and ending single
191
191
  # or double quote characters from parameters.
192
192
  # @param run_erb [Boolean] Whether or not to run ERB on the file
193
- # @param variables [Hash] variables to pash to ERB context
193
+ # @param variables [Hash] variables to push to ERB context
194
194
  # @param block [Block] The block to yield to
195
195
  # @yieldparam keyword [String] The keyword in the current parsed line
196
196
  # @yieldparam parameters [Array<String>] The parameters in the current parsed line
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/conversions/conversion'
@@ -42,7 +42,7 @@ module OpenC3
42
42
  attr_reader :coeffs
43
43
 
44
44
  # Creates a polynomial conversion segment. Multiple Segments are used to
45
- # implemnt a {SegmentedPolynomialConversion}.
45
+ # implement a {SegmentedPolynomialConversion}.
46
46
  #
47
47
  # @param lower_bound [Integer] The value at which point this polynomial conversion
48
48
  # should apply. All values >= to this value will be converted using the
@@ -60,16 +60,16 @@ module OpenC3
60
60
  # @param other_segment [Segment] The segment to compare
61
61
  # @return [Integer] 1 if self.lower_bound > other_segment.lower_bound, 0
62
62
  # if they are equal, -1 if self.lower_bound < other_segment.lower_bound
63
- def <=>(other_segment)
64
- return other_segment.lower_bound <=> @lower_bound
63
+ def <=>(other)
64
+ return other.lower_bound <=> @lower_bound
65
65
  end
66
66
 
67
67
  # Implement equality operator primarily for ease of testing
68
68
  #
69
69
  # @param segment [Segment] Other segment
70
- def ==(other_segment)
71
- @lower_bound == other_segment.lower_bound &&
72
- @coeffs == other_segment.coeffs
70
+ def ==(other)
71
+ @lower_bound == other.lower_bound &&
72
+ @coeffs == other.coeffs
73
73
  end
74
74
 
75
75
  # Perform the polynomial conversion
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/ext/array' if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
@@ -306,10 +306,10 @@ class Array
306
306
  # which are arrays containing the first value that is found in the bucket,
307
307
  # the last value found in the bucket, and the total number of values in the
308
308
  # bucket.
309
- def histogram(num_buckets = nil, numeric = false, &block)
309
+ def histogram(num_buckets = nil, numeric = false, &)
310
310
  buckets = {}
311
311
 
312
- # Count the occurance of each value
312
+ # Count the occurrence of each value
313
313
  self.each do |value|
314
314
  buckets[value] ||= 0
315
315
  buckets[value] += 1
@@ -338,7 +338,7 @@ class Array
338
338
  integers = true if first_value.kind_of?(Integer) and last_value.kind_of?(Integer)
339
339
  if integers
340
340
  bucket_size = bucket_size.ceil
341
- last_value = first_value + bucket_size * num_buckets - 1
341
+ last_value = first_value + (bucket_size * num_buckets) - 1
342
342
  delta = last_value - first_value
343
343
  (delta + 1).times do |index|
344
344
  buckets[first_value + index] ||= 0
@@ -406,7 +406,7 @@ class Array
406
406
  last_index = sorted_buckets.length - 1 if last_index > (sorted_buckets.length - 1)
407
407
  end
408
408
  sum = 0
409
- sorted_buckets[first_index..last_index].each { |key, value| sum += value }
409
+ sorted_buckets[first_index..last_index].each { |_key, value| sum += value }
410
410
  reduced_buckets[bucket_index] = [sorted_buckets[first_index][0], sorted_buckets[last_index][0], sum]
411
411
  first_index = first_index + bucket_sizes[bucket_index]
412
412
  end
@@ -14,14 +14,21 @@
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
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  # OpenC3 specific additions to the Ruby Exception class
24
24
  class Exception
25
+ def filtered
26
+ backtrace = self.backtrace.select do |line|
27
+ !line.include?('lib/ruby/gems')
28
+ end
29
+ return "#{self.message}\n#{backtrace.join("\n")}"
30
+ end
31
+
25
32
  # @param hide_runtime_error_class [Boolean] Whether to hide the Exception
26
33
  # error class if the class is RuntimeError. Other classes will continue to
27
34
  # be printed.
@@ -63,7 +63,7 @@ class String
63
63
  # @param unprintable_character [String] The string to output when data in the
64
64
  # binary String does not result in a printable ASCII character. Only used if
65
65
  # show_ascii is true.
66
- # @param line_separator [String] The string used to end a line. Normaly newline.
66
+ # @param line_separator [String] The string used to end a line. Normally newline.
67
67
  def formatted(
68
68
  word_size = 1,
69
69
  words_per_line = 16,
@@ -149,7 +149,7 @@ class String
149
149
  string
150
150
  end
151
151
 
152
- # Uses the String each_line method to interate through the lines and removes
152
+ # Uses the String each_line method to iterate through the lines and removes
153
153
  # the line specified.
154
154
  #
155
155
  # @param line_number [Integer] The line to remove from the string (1 based)
@@ -75,6 +75,7 @@ module OpenC3
75
75
  # No HTTP_STATUS - Leave at default
76
76
  end
77
77
 
78
+ # http_accessor stores all the pseudo-derived HTTP configuration in extra
78
79
  if packet.extra
79
80
  headers = packet.extra['HTTP_HEADERS']
80
81
  if headers
@@ -258,7 +258,7 @@ module OpenC3
258
258
  first = true
259
259
  loop do
260
260
  # Protocols may have cached data for a packet, so initially just inject a blank string
261
- # Otherwise we can hold off outputing other packets where all the data has already
261
+ # Otherwise we can hold off outputting other packets where all the data has already
262
262
  # been received
263
263
  extra = nil
264
264
  if !first or @read_protocols.length <= 0
@@ -128,11 +128,11 @@ module OpenC3
128
128
  raise "Interface not connected" unless connected?()
129
129
 
130
130
  # Add a GUID to the GUID field if its defined
131
- # A GUID means it's an asychronous packet type.
131
+ # A GUID means it's an asynchronous packet type.
132
132
  if @fieldname_guid
133
133
  guid = get_guid(packet)
134
134
  else
135
- # If @fieldname_guid is not defined (syncronous) we don't care what the
135
+ # If @fieldname_guid is not defined (synchronous) we don't care what the
136
136
  # GUID is because we're not trying to match it up with anything.
137
137
  # As soon as we get a response we free the command.
138
138
  guid = 0
@@ -323,7 +323,7 @@ module OpenC3
323
323
  # first looks up the handshake before removing it.
324
324
  @handshakes_mutex.synchronize do
325
325
  if @fieldname_guid
326
- # A GUID means it's an asychronous packet type.
326
+ # A GUID means it's an asynchronous packet type.
327
327
  # So look at the list of incoming handshakes and pick off (deleting)
328
328
  # the handshake from the list if it's for this command.
329
329
  #
@@ -40,13 +40,18 @@ module OpenC3
40
40
  # pull openc3-cosmos-script-runner-api url from environment variables
41
41
  def _generate_url(microservice_name:, prefix:, schema: 'http', hostname: nil, port:, scope: $openc3_scope)
42
42
  prefix = '/' + prefix unless prefix[0] == '/'
43
- if ENV['KUBERNETES_SERVICE_HOST']
44
- hostname = "#{scope}__USER__#{microservice_name}" unless hostname
45
- hostname = hostname.downcase.gsub("__", "-").gsub("_", "-")
46
- return "#{schema}://#{hostname}-service:#{port.to_i}#{prefix}"
47
- else
48
- hostname = 'openc3-operator' unless hostname
43
+ if ENV['OPENC3_OPERATOR_HOSTNAME']
44
+ hostname = ENV['OPENC3_OPERATOR_HOSTNAME'] unless hostname
49
45
  return "#{schema}://#{hostname}:#{port.to_i}#{prefix}"
46
+ else
47
+ if ENV['KUBERNETES_SERVICE_HOST']
48
+ hostname = "#{scope}__USER__#{microservice_name}" unless hostname
49
+ hostname = hostname.downcase.gsub("__", "-").gsub("_", "-")
50
+ return "#{schema}://#{hostname}-service:#{port.to_i}#{prefix}"
51
+ else
52
+ hostname = 'openc3-operator' unless hostname
53
+ return "#{schema}://#{hostname}:#{port.to_i}#{prefix}"
54
+ end
50
55
  end
51
56
  end
52
57
 
@@ -214,7 +214,7 @@ module OpenC3
214
214
 
215
215
  # Represents a JSON Remote Procedure Call Request
216
216
  class JsonRpcRequest < JsonRpc
217
- DANGEROUS_METHODS = ['__send__', 'send', 'instance_eval', 'instance_exec']
217
+ DANGEROUS_METHODS = Set['__send__', 'send', 'instance_eval', 'instance_exec']
218
218
 
219
219
  # @param method_name [String] The name of the method to call
220
220
  # @param method_params [Array<String>] Array of strings which represent the