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.
- checksums.yaml +4 -4
- data/Gemfile +7 -4
- data/bin/cstol_converter +14 -14
- data/bin/openc3cli +189 -7
- data/data/config/_interfaces.yaml +1 -1
- data/data/config/command_modifiers.yaml +55 -0
- data/data/config/interface_modifiers.yaml +1 -1
- data/data/config/param_item_modifiers.yaml +1 -1
- data/data/config/parameter_modifiers.yaml +1 -1
- data/data/config/plugins.yaml +6 -2
- data/data/config/screen.yaml +2 -2
- data/data/config/table_manager.yaml +2 -2
- data/data/config/tool.yaml +4 -1
- data/data/config/widgets.yaml +3 -3
- data/ext/openc3/ext/config_parser/config_parser.c +1 -1
- data/ext/openc3/ext/packet/packet.c +1 -1
- data/ext/openc3/ext/platform/platform.c +3 -3
- data/ext/openc3/ext/structure/structure.c +56 -76
- data/lib/openc3/accessors/binary_accessor.rb +4 -4
- data/lib/openc3/accessors/form_accessor.rb +2 -2
- data/lib/openc3/accessors/http_accessor.rb +1 -1
- data/lib/openc3/accessors/json_accessor.rb +6 -4
- data/lib/openc3/accessors/template_accessor.rb +6 -9
- data/lib/openc3/accessors/xml_accessor.rb +1 -1
- data/lib/openc3/api/cmd_api.rb +35 -11
- data/lib/openc3/api/limits_api.rb +1 -1
- data/lib/openc3/config/config_parser.rb +1 -1
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +7 -7
- data/lib/openc3/core_ext/array.rb +5 -5
- data/lib/openc3/core_ext/exception.rb +9 -2
- data/lib/openc3/core_ext/string.rb +2 -2
- data/lib/openc3/interfaces/http_server_interface.rb +1 -0
- data/lib/openc3/interfaces/interface.rb +1 -1
- data/lib/openc3/interfaces/linc_interface.rb +3 -3
- data/lib/openc3/io/json_api.rb +11 -6
- data/lib/openc3/io/json_rpc.rb +1 -1
- data/lib/openc3/logs/buffered_packet_log_writer.rb +3 -3
- data/lib/openc3/logs/log_writer.rb +7 -8
- data/lib/openc3/logs/packet_log_writer.rb +7 -7
- data/lib/openc3/logs/text_log_writer.rb +4 -4
- data/lib/openc3/microservices/decom_microservice.rb +19 -4
- data/lib/openc3/microservices/interface_microservice.rb +41 -3
- data/lib/openc3/microservices/reaction_microservice.rb +2 -2
- data/lib/openc3/microservices/trigger_group_microservice.rb +3 -3
- data/lib/openc3/migrations/20240915000000_activity_uuid.rb +28 -0
- data/lib/openc3/models/activity_model.rb +109 -80
- data/lib/openc3/models/auth_model.rb +31 -2
- data/lib/openc3/models/cvt_model.rb +11 -5
- data/lib/openc3/models/gem_model.rb +8 -8
- data/lib/openc3/models/plugin_model.rb +3 -3
- data/lib/openc3/models/reducer_model.rb +2 -2
- data/lib/openc3/models/scope_model.rb +1 -1
- data/lib/openc3/models/sorted_model.rb +4 -4
- data/lib/openc3/models/target_model.rb +3 -3
- data/lib/openc3/models/tool_config_model.rb +1 -1
- data/lib/openc3/models/tool_model.rb +4 -4
- data/lib/openc3/models/widget_model.rb +11 -5
- data/lib/openc3/operators/operator.rb +5 -3
- data/lib/openc3/packets/command_validator.rb +48 -0
- data/lib/openc3/packets/commands.rb +6 -14
- data/lib/openc3/packets/packet.rb +31 -15
- data/lib/openc3/packets/packet_config.rb +10 -9
- data/lib/openc3/packets/parsers/packet_parser.rb +3 -3
- data/lib/openc3/packets/structure.rb +21 -13
- data/lib/openc3/packets/structure_item.rb +33 -47
- data/lib/openc3/packets/telemetry.rb +6 -27
- data/lib/openc3/script/api_shared.rb +7 -5
- data/lib/openc3/script/calendar.rb +2 -2
- data/lib/openc3/script/commands.rb +6 -4
- data/lib/openc3/script/metadata.rb +2 -2
- data/lib/openc3/script/suite.rb +17 -17
- data/lib/openc3/streams/serial_stream.rb +2 -3
- data/lib/openc3/streams/stream.rb +2 -2
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +10 -10
- data/lib/openc3/tools/table_manager/table_manager_core.rb +11 -11
- data/lib/openc3/tools/table_manager/table_parser.rb +2 -3
- data/lib/openc3/topics/command_decom_topic.rb +2 -1
- data/lib/openc3/topics/command_topic.rb +3 -3
- data/lib/openc3/topics/decom_interface_topic.rb +2 -2
- data/lib/openc3/topics/telemetry_decom_topic.rb +1 -1
- data/lib/openc3/utilities/authorization.rb +2 -1
- data/lib/openc3/utilities/cli_generator.rb +15 -8
- data/lib/openc3/utilities/cosmos_rails_formatter.rb +60 -0
- data/lib/openc3/utilities/crc.rb +6 -6
- data/lib/openc3/utilities/local_mode.rb +2 -1
- data/lib/openc3/utilities/logger.rb +44 -34
- data/lib/openc3/utilities/metric.rb +1 -2
- data/lib/openc3/utilities/quaternion.rb +18 -18
- data/lib/openc3/utilities/target_file.rb +4 -4
- data/lib/openc3/version.rb +5 -5
- data/lib/openc3/win32/win32_main.rb +2 -2
- data/templates/tool_angular/package.json +21 -21
- data/templates/tool_react/package.json +10 -10
- data/templates/tool_svelte/package.json +11 -11
- data/templates/tool_svelte/src/services/openc3-api.js +17 -17
- data/templates/tool_vue/package.json +9 -9
- data/templates/widget/package.json +6 -7
- metadata +5 -2
|
@@ -73,9 +73,11 @@ module OpenC3
|
|
|
73
73
|
def self.handle_config(parser, keyword, parameters, plugin: nil, needs_dependencies: false, scope:)
|
|
74
74
|
case keyword
|
|
75
75
|
when 'WIDGET'
|
|
76
|
-
parser.verify_num_parameters(1,
|
|
76
|
+
parser.verify_num_parameters(1, 3, "WIDGET <Name> <Label> <Select Items (true/false)>")
|
|
77
77
|
# Label is optional and if it doesn't exist nil is fine
|
|
78
|
-
|
|
78
|
+
# Select Items is optional and if it doesn't exist nil is fine
|
|
79
|
+
items = ConfigParser.handle_true_false_nil(parameters[2])
|
|
80
|
+
return self.new(name: parameters[0], plugin: plugin, label: parameters[1], items: items, needs_dependencies: needs_dependencies, scope: scope)
|
|
79
81
|
else
|
|
80
82
|
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Widget: #{keyword} #{parameters.join(" ")}")
|
|
81
83
|
end
|
|
@@ -87,6 +89,7 @@ module OpenC3
|
|
|
87
89
|
updated_at: nil,
|
|
88
90
|
plugin: nil,
|
|
89
91
|
label: nil,
|
|
92
|
+
items: false,
|
|
90
93
|
needs_dependencies: false,
|
|
91
94
|
disable_erb: nil,
|
|
92
95
|
scope:
|
|
@@ -96,6 +99,8 @@ module OpenC3
|
|
|
96
99
|
@filename = @full_name + '.umd.min.js'
|
|
97
100
|
@bucket_key = 'widgets/' + @full_name + '/' + @filename
|
|
98
101
|
@label = label
|
|
102
|
+
# Ensure items is a boolean because it could be nil
|
|
103
|
+
@items = items ? true : false
|
|
99
104
|
@needs_dependencies = needs_dependencies
|
|
100
105
|
@disable_erb = disable_erb
|
|
101
106
|
end
|
|
@@ -106,8 +111,9 @@ module OpenC3
|
|
|
106
111
|
'updated_at' => @updated_at,
|
|
107
112
|
'plugin' => @plugin,
|
|
108
113
|
'label' => @label,
|
|
114
|
+
'items' => @items,
|
|
109
115
|
'needs_dependencies' => @needs_dependencies,
|
|
110
|
-
'disable_erb' => @disable_erb
|
|
116
|
+
'disable_erb' => @disable_erb,
|
|
111
117
|
}
|
|
112
118
|
end
|
|
113
119
|
|
|
@@ -155,8 +161,8 @@ module OpenC3
|
|
|
155
161
|
bucket = Bucket.getClient()
|
|
156
162
|
bucket.delete_object(bucket: ENV['OPENC3_TOOLS_BUCKET'], key: @bucket_key)
|
|
157
163
|
bucket.delete_object(bucket: ENV['OPENC3_TOOLS_BUCKET'], key: @bucket_key + '.map')
|
|
158
|
-
rescue Exception =>
|
|
159
|
-
Logger.error("Error undeploying widget model #{@name} in scope #{@scope} due to #{
|
|
164
|
+
rescue Exception => e
|
|
165
|
+
Logger.error("Error undeploying widget model #{@name} in scope #{@scope} due to #{e}")
|
|
160
166
|
end
|
|
161
167
|
end
|
|
162
168
|
end
|
|
@@ -105,7 +105,7 @@ module OpenC3
|
|
|
105
105
|
def cmd_line
|
|
106
106
|
# In ProcessManager processes, the process_definition is the actual thing run
|
|
107
107
|
# e.g. OpenC3::ProcessManager.instance.spawn(["ruby", "/openc3/bin/openc3cli", "load", ...])
|
|
108
|
-
# However, if the MicroserviceOperator is spawning the
|
|
108
|
+
# However, if the MicroserviceOperator is spawning the processes it sets
|
|
109
109
|
# process_definition = ["ruby", "plugin_microservice.rb"]
|
|
110
110
|
# which then calls exec(*@config["cmd"]) to actually run
|
|
111
111
|
# So check if the @config['cmd'] is defined to give the user more info in the log
|
|
@@ -195,12 +195,14 @@ module OpenC3
|
|
|
195
195
|
if @process
|
|
196
196
|
stdout = @process.io.stdout.extract
|
|
197
197
|
if stdout.length > 0
|
|
198
|
-
|
|
198
|
+
message = "STDOUT #{stdout.length} bytes from #{cmd_line()}:"
|
|
199
|
+
STDOUT.puts Logger.build_log_data(Logger::INFO_LEVEL, message, user: nil, type: OpenC3::Logger::LOG, url: nil).as_json(:allow_nan => true).to_json(:allow_nan => true)
|
|
199
200
|
STDOUT.puts stdout
|
|
200
201
|
end
|
|
201
202
|
stderr = @process.io.stderr.extract
|
|
202
203
|
if stderr.length > 0
|
|
203
|
-
|
|
204
|
+
message = "STDERR #{stderr.length} bytes from #{cmd_line()}:"
|
|
205
|
+
STDERR.puts Logger.build_log_data(Logger::ERROR_LEVEL, message, user: nil, type: OpenC3::Logger::LOG, url: nil).as_json(:allow_nan => true).to_json(:allow_nan => true)
|
|
204
206
|
STDERR.puts stderr
|
|
205
207
|
end
|
|
206
208
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2024 OpenC3, Inc.
|
|
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
|
+
# This file may also be used under the terms of a commercial license
|
|
17
|
+
# if purchased from OpenC3, Inc.
|
|
18
|
+
|
|
19
|
+
# This file implements a class to handle command validation
|
|
20
|
+
|
|
21
|
+
require 'openc3/api/api'
|
|
22
|
+
|
|
23
|
+
module OpenC3
|
|
24
|
+
# This class defines methods which are called when a command is sent.
|
|
25
|
+
# This class must be subclassed and the pre_check or
|
|
26
|
+
# post_check methods implemented. Do NOT use this class directly.
|
|
27
|
+
class CommandValidator
|
|
28
|
+
attr_reader :args
|
|
29
|
+
include Api
|
|
30
|
+
|
|
31
|
+
def initialize(command = nil)
|
|
32
|
+
@command = command
|
|
33
|
+
@args = []
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def pre_check(command)
|
|
37
|
+
# Return true to indicate Success, false to indicate Failure,
|
|
38
|
+
# and nil to indicate Unknown. The second value is the optional message.
|
|
39
|
+
return [true, nil]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def post_check(command)
|
|
43
|
+
# Return true to indicate Success, false to indicate Failure,
|
|
44
|
+
# and nil to indicate Unknown. The second value is the optional message.
|
|
45
|
+
return [true, nil]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -30,7 +30,7 @@ module OpenC3
|
|
|
30
30
|
#
|
|
31
31
|
# This should not be confused with the Api module which implements the JSON
|
|
32
32
|
# API that is used by tools when accessing the Server. The Api module always
|
|
33
|
-
# provides Ruby
|
|
33
|
+
# provides Ruby primitives where the PacketConfig class can return actual
|
|
34
34
|
# Packet or PacketItem objects. While there are some overlapping methods between
|
|
35
35
|
# the two, these are separate interfaces into the system.
|
|
36
36
|
class Commands
|
|
@@ -115,7 +115,7 @@ module OpenC3
|
|
|
115
115
|
target = System.targets[target_name]
|
|
116
116
|
if target and target.cmd_unique_id_mode
|
|
117
117
|
# Iterate through the packets and see if any represent the buffer
|
|
118
|
-
target_packets.each do |
|
|
118
|
+
target_packets.each do |_packet_name, packet|
|
|
119
119
|
if packet.identify?(packet_data)
|
|
120
120
|
identified_packet = packet
|
|
121
121
|
break
|
|
@@ -147,7 +147,7 @@ module OpenC3
|
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
# Returns a copy of the specified command packet with the parameters
|
|
150
|
-
#
|
|
150
|
+
# initialized to the given params values.
|
|
151
151
|
#
|
|
152
152
|
# @param target_name (see #packet)
|
|
153
153
|
# @param packet_name (see #packet)
|
|
@@ -195,7 +195,7 @@ module OpenC3
|
|
|
195
195
|
items = packet.read_all(:FORMATTED)
|
|
196
196
|
raw = false
|
|
197
197
|
end
|
|
198
|
-
items.delete_if { |item_name,
|
|
198
|
+
items.delete_if { |item_name, _item_value| ignored_parameters.include?(item_name) }
|
|
199
199
|
return build_cmd_output_string(packet.target_name, packet.packet_name, items, raw)
|
|
200
200
|
end
|
|
201
201
|
|
|
@@ -207,7 +207,7 @@ module OpenC3
|
|
|
207
207
|
end
|
|
208
208
|
target_name = 'UNKNOWN' unless target_name
|
|
209
209
|
cmd_name = 'UNKNOWN' unless cmd_name
|
|
210
|
-
output_string << target_name + ' ' + cmd_name
|
|
210
|
+
output_string << (target_name + ' ' + cmd_name)
|
|
211
211
|
if cmd_params.nil? or cmd_params.empty?
|
|
212
212
|
output_string << '")'
|
|
213
213
|
else
|
|
@@ -247,7 +247,7 @@ module OpenC3
|
|
|
247
247
|
params << "#{key} #{value}"
|
|
248
248
|
end
|
|
249
249
|
params = params.join(", ")
|
|
250
|
-
output_string << ' with ' + params + '")'
|
|
250
|
+
output_string << (' with ' + params + '")')
|
|
251
251
|
end
|
|
252
252
|
return output_string
|
|
253
253
|
end
|
|
@@ -291,14 +291,6 @@ module OpenC3
|
|
|
291
291
|
cmd_pkt_hazardous?(build_cmd(target_name, packet_name, params, false, false, false))
|
|
292
292
|
end
|
|
293
293
|
|
|
294
|
-
def clear_counters
|
|
295
|
-
@config.commands.each do |target_name, target_packets|
|
|
296
|
-
target_packets.each do |packet_name, packet|
|
|
297
|
-
packet.received_count = 0
|
|
298
|
-
end
|
|
299
|
-
end
|
|
300
|
-
end
|
|
301
|
-
|
|
302
294
|
def all
|
|
303
295
|
@config.commands
|
|
304
296
|
end
|
|
@@ -104,6 +104,9 @@ module OpenC3
|
|
|
104
104
|
# @return [Boolean] Whether to ignore overlapping items
|
|
105
105
|
attr_accessor :ignore_overlap
|
|
106
106
|
|
|
107
|
+
# @return [Validator] Instance of class used to validate commands
|
|
108
|
+
attr_accessor :validator
|
|
109
|
+
|
|
107
110
|
# @return [Boolean] If this packet should be used for identification
|
|
108
111
|
attr_reader :virtual
|
|
109
112
|
|
|
@@ -111,7 +114,7 @@ module OpenC3
|
|
|
111
114
|
VALUE_TYPES = [:RAW, :CONVERTED, :FORMATTED, :WITH_UNITS]
|
|
112
115
|
|
|
113
116
|
if RUBY_ENGINE != 'ruby' or ENV['OPENC3_NO_EXT']
|
|
114
|
-
# Creates a new packet by
|
|
117
|
+
# Creates a new packet by initializing the attributes.
|
|
115
118
|
#
|
|
116
119
|
# @param target_name [String] Name of the target this packet is associated with
|
|
117
120
|
# @param packet_name [String] Name of the packet
|
|
@@ -122,7 +125,7 @@ module OpenC3
|
|
|
122
125
|
# subclass of PacketItem)
|
|
123
126
|
def initialize(target_name = nil, packet_name = nil, default_endianness = :BIG_ENDIAN, description = nil, buffer = nil, item_class = PacketItem)
|
|
124
127
|
super(default_endianness, buffer, item_class)
|
|
125
|
-
#
|
|
128
|
+
# Explicitly call the defined setter methods
|
|
126
129
|
self.target_name = target_name
|
|
127
130
|
self.packet_name = packet_name
|
|
128
131
|
self.description = description
|
|
@@ -148,6 +151,7 @@ module OpenC3
|
|
|
148
151
|
@packet_time = nil
|
|
149
152
|
@ignore_overlap = false
|
|
150
153
|
@virtual = false
|
|
154
|
+
@validator = nil
|
|
151
155
|
end
|
|
152
156
|
|
|
153
157
|
# Sets the target name this packet is associated with. Unidentified packets
|
|
@@ -325,7 +329,7 @@ module OpenC3
|
|
|
325
329
|
synchronize() do
|
|
326
330
|
begin
|
|
327
331
|
internal_buffer_equals(buffer)
|
|
328
|
-
rescue RuntimeError
|
|
332
|
+
rescue RuntimeError => e
|
|
329
333
|
Logger.instance.error "#{@target_name} #{@packet_name} received with actual packet length of #{buffer.length} but defined length of #{@defined_length}"
|
|
330
334
|
end
|
|
331
335
|
@read_conversion_cache.clear if @read_conversion_cache
|
|
@@ -511,20 +515,20 @@ module OpenC3
|
|
|
511
515
|
|
|
512
516
|
# Define an item in the packet. This creates a new instance of the
|
|
513
517
|
# item_class as given in the constructor and adds it to the items hash. It
|
|
514
|
-
# also resizes the buffer to
|
|
518
|
+
# also resizes the buffer to accommodate the new item.
|
|
515
519
|
#
|
|
516
520
|
# @param name [String] Name of the item. Used by the items hash to retrieve
|
|
517
521
|
# the item.
|
|
518
522
|
# @param bit_offset [Integer] Bit offset of the item in the raw buffer
|
|
519
523
|
# @param bit_size [Integer] Bit size of the item in the raw buffer
|
|
520
524
|
# @param data_type [Symbol] Type of data contained by the item. This is
|
|
521
|
-
#
|
|
525
|
+
# dependent on the item_class but by default see StructureItem.
|
|
522
526
|
# @param array_size [Integer] Set to a non nil value if the item is to
|
|
523
527
|
# represented as an array.
|
|
524
528
|
# @param endianness [Symbol] Endianness of this item. By default the
|
|
525
|
-
# endianness as set in the
|
|
529
|
+
# endianness as set in the constructor is used.
|
|
526
530
|
# @param overflow [Symbol] How to handle value overflows. This is
|
|
527
|
-
#
|
|
531
|
+
# dependent on the item_class but by default see StructureItem.
|
|
528
532
|
# @param format_string [String] String to pass to Kernel#sprintf
|
|
529
533
|
# @param read_conversion [Conversion] Conversion to apply when reading the
|
|
530
534
|
# item from the packet buffer
|
|
@@ -540,7 +544,7 @@ module OpenC3
|
|
|
540
544
|
end
|
|
541
545
|
|
|
542
546
|
# Add an item to the packet by adding it to the items hash. It also
|
|
543
|
-
# resizes the buffer to
|
|
547
|
+
# resizes the buffer to accommodate the new item.
|
|
544
548
|
#
|
|
545
549
|
# @param item [PacketItem] Item to add to the packet
|
|
546
550
|
# @return [PacketItem] The same packet item
|
|
@@ -553,7 +557,7 @@ module OpenC3
|
|
|
553
557
|
|
|
554
558
|
# Define an item at the end of the packet. This creates a new instance of the
|
|
555
559
|
# item_class as given in the constructor and adds it to the items hash. It
|
|
556
|
-
# also resizes the buffer to
|
|
560
|
+
# also resizes the buffer to accommodate the new item.
|
|
557
561
|
#
|
|
558
562
|
# @param name (see #define_item)
|
|
559
563
|
# @param bit_size (see #define_item)
|
|
@@ -1064,9 +1068,12 @@ module OpenC3
|
|
|
1064
1068
|
if @accessor.class.to_s != 'OpenC3::BinaryAccessor'
|
|
1065
1069
|
config << " ACCESSOR #{@accessor.class} #{@accessor.args.map { |a| a.to_s.quote_if_necessary }.join(" ")}\n"
|
|
1066
1070
|
end
|
|
1071
|
+
if @validator
|
|
1072
|
+
config << " VALIDATOR #{@validator.class} #{@validator.args.map { |a| a.to_s.quote_if_necessary }.join(" ")}\n"
|
|
1073
|
+
end
|
|
1067
1074
|
# TODO: Add TEMPLATE_ENCODED so this can always be done inline regardless of content
|
|
1068
1075
|
if @template
|
|
1069
|
-
config << " TEMPLATE '#{@template}'"
|
|
1076
|
+
config << " TEMPLATE '#{@template}'\n"
|
|
1070
1077
|
end
|
|
1071
1078
|
config << " ALLOW_SHORT\n" if @short_buffer_allowed
|
|
1072
1079
|
config << " HAZARDOUS #{@hazardous_description.to_s.quote_if_necessary}\n" if @hazardous
|
|
@@ -1106,21 +1113,21 @@ module OpenC3
|
|
|
1106
1113
|
end
|
|
1107
1114
|
|
|
1108
1115
|
if @response
|
|
1109
|
-
config << " RESPONSE #{@response[0].to_s.quote_if_necessary} #{@response[1].to_s.quote_if_necessary}"
|
|
1116
|
+
config << " RESPONSE #{@response[0].to_s.quote_if_necessary} #{@response[1].to_s.quote_if_necessary}\n"
|
|
1110
1117
|
end
|
|
1111
1118
|
if @error_response
|
|
1112
|
-
config << " ERROR_RESPONSE #{@error_response[0].to_s.quote_if_necessary} #{@error_response[1].to_s.quote_if_necessary}"
|
|
1119
|
+
config << " ERROR_RESPONSE #{@error_response[0].to_s.quote_if_necessary} #{@error_response[1].to_s.quote_if_necessary}\n"
|
|
1113
1120
|
end
|
|
1114
1121
|
if @screen
|
|
1115
|
-
config << " SCREEN #{@screen[0].to_s.quote_if_necessary} #{@screen[1].to_s.quote_if_necessary}"
|
|
1122
|
+
config << " SCREEN #{@screen[0].to_s.quote_if_necessary} #{@screen[1].to_s.quote_if_necessary}\n"
|
|
1116
1123
|
end
|
|
1117
1124
|
if @related_items
|
|
1118
1125
|
@related_items.each do |target_name, packet_name, item_name|
|
|
1119
|
-
config << " RELATED_ITEM #{target_name.to_s.quote_if_necessary} #{packet_name.to_s.quote_if_necessary} #{item_name.to_s.quote_if_necessary}"
|
|
1126
|
+
config << " RELATED_ITEM #{target_name.to_s.quote_if_necessary} #{packet_name.to_s.quote_if_necessary} #{item_name.to_s.quote_if_necessary}\n"
|
|
1120
1127
|
end
|
|
1121
1128
|
end
|
|
1122
1129
|
if @ignore_overlap
|
|
1123
|
-
config << " IGNORE_OVERLAP"
|
|
1130
|
+
config << " IGNORE_OVERLAP\n"
|
|
1124
1131
|
end
|
|
1125
1132
|
config
|
|
1126
1133
|
end
|
|
@@ -1140,6 +1147,7 @@ module OpenC3
|
|
|
1140
1147
|
config['virtual'] = true if @virtual
|
|
1141
1148
|
config['accessor'] = @accessor.class.to_s
|
|
1142
1149
|
config['accessor_args'] = @accessor.args
|
|
1150
|
+
config['validator'] = @validator.class.to_s if @validator
|
|
1143
1151
|
config['template'] = Base64.encode64(@template) if @template
|
|
1144
1152
|
config['config_name'] = self.config_name
|
|
1145
1153
|
|
|
@@ -1205,6 +1213,14 @@ module OpenC3
|
|
|
1205
1213
|
Logger.instance.error "#{packet.target_name} #{packet.packet_name} accessor of #{hash['accessor']} could not be found due to #{e}"
|
|
1206
1214
|
end
|
|
1207
1215
|
end
|
|
1216
|
+
if hash['validator']
|
|
1217
|
+
begin
|
|
1218
|
+
validator = OpenC3::const_get(hash['validator'])
|
|
1219
|
+
packet.validator = validator.new(packet)
|
|
1220
|
+
rescue => e
|
|
1221
|
+
Logger.instance.error "#{packet.target_name} #{packet.packet_name} validator of #{hash['validator']} could not be found due to #{e}"
|
|
1222
|
+
end
|
|
1223
|
+
end
|
|
1208
1224
|
packet.template = Base64.decode64(hash['template']) if hash['template']
|
|
1209
1225
|
packet.meta = hash['meta']
|
|
1210
1226
|
# Can't convert processors
|
|
@@ -220,7 +220,7 @@ module OpenC3
|
|
|
220
220
|
'APPEND_PARAMETER', 'APPEND_ID_ITEM', 'APPEND_ID_PARAMETER', 'APPEND_ARRAY_ITEM',\
|
|
221
221
|
'APPEND_ARRAY_PARAMETER', 'ALLOW_SHORT', 'HAZARDOUS', 'PROCESSOR', 'META',\
|
|
222
222
|
'DISABLE_MESSAGES', 'HIDDEN', 'DISABLED', 'VIRTUAL', 'ACCESSOR', 'TEMPLATE', 'TEMPLATE_FILE',\
|
|
223
|
-
'RESPONSE', 'ERROR_RESPONSE', 'SCREEN', 'RELATED_ITEM', 'IGNORE_OVERLAP'
|
|
223
|
+
'RESPONSE', 'ERROR_RESPONSE', 'SCREEN', 'RELATED_ITEM', 'IGNORE_OVERLAP', 'VALIDATOR'
|
|
224
224
|
raise parser.error("No current packet for #{keyword}") unless @current_packet
|
|
225
225
|
|
|
226
226
|
process_current_packet(parser, keyword, params)
|
|
@@ -409,7 +409,7 @@ module OpenC3
|
|
|
409
409
|
else # DELETE
|
|
410
410
|
@current_packet.delete_item(params[0])
|
|
411
411
|
end
|
|
412
|
-
rescue # Rescue the default
|
|
412
|
+
rescue # Rescue the default exception to provide a nicer error message
|
|
413
413
|
raise parser.error("#{params[0]} not found in #{@current_cmd_or_tlm.downcase} packet #{@current_packet.target_name} #{@current_packet.packet_name}", usage)
|
|
414
414
|
end
|
|
415
415
|
|
|
@@ -480,22 +480,23 @@ module OpenC3
|
|
|
480
480
|
@current_packet.disabled = true
|
|
481
481
|
@current_packet.virtual = true
|
|
482
482
|
|
|
483
|
-
when 'ACCESSOR'
|
|
484
|
-
usage = "#{keyword} <
|
|
483
|
+
when 'ACCESSOR', 'VALIDATOR'
|
|
484
|
+
usage = "#{keyword} <Class name> <Optional parameters> ..."
|
|
485
485
|
parser.verify_num_parameters(1, nil, usage)
|
|
486
486
|
begin
|
|
487
|
+
keyword_equals = "#{keyword.downcase}=".to_sym
|
|
487
488
|
if @language == 'ruby'
|
|
488
489
|
klass = OpenC3.require_class(params[0])
|
|
489
490
|
if params.length > 1
|
|
490
|
-
@current_packet.
|
|
491
|
+
@current_packet.public_send(keyword_equals, klass.new(@current_packet, *params[1..-1]))
|
|
491
492
|
else
|
|
492
|
-
@current_packet.
|
|
493
|
+
@current_packet.public_send(keyword_equals, klass.new(@current_packet))
|
|
493
494
|
end
|
|
494
495
|
else
|
|
495
496
|
if params.length > 1
|
|
496
|
-
@current_packet.
|
|
497
|
+
@current_packet.public_send(keyword_equals, PythonProxy.new(keyword.capitalize, params[0], @current_packet, *params[1..-1]))
|
|
497
498
|
else
|
|
498
|
-
@current_packet.
|
|
499
|
+
@current_packet.public_send(keyword_equals, PythonProxy.new(keyword.capitalize, params[0], @current_packet))
|
|
499
500
|
end
|
|
500
501
|
end
|
|
501
502
|
rescue Exception => e
|
|
@@ -675,7 +676,7 @@ module OpenC3
|
|
|
675
676
|
raise parser.error("#{keyword} only applies to command parameters")
|
|
676
677
|
end
|
|
677
678
|
|
|
678
|
-
# Update the
|
|
679
|
+
# Update the minimum value for the current command parameter
|
|
679
680
|
when 'MINIMUM_VALUE'
|
|
680
681
|
if @current_cmd_or_tlm == TELEMETRY
|
|
681
682
|
raise parser.error("#{keyword} only applies to command parameters")
|
|
@@ -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/packets/packet'
|
|
@@ -30,7 +30,7 @@ module OpenC3
|
|
|
30
30
|
# used instead of this parameter.
|
|
31
31
|
# @param commands [Hash] Hash of the currently defined commands
|
|
32
32
|
# @param warnings [Array<String>] Any warning strings generated while
|
|
33
|
-
# parsing this command will be
|
|
33
|
+
# parsing this command will be appended to this array
|
|
34
34
|
def self.parse_command(parser, target_name, commands, warnings)
|
|
35
35
|
parser = PacketParser.new(parser)
|
|
36
36
|
parser.verify_parameters()
|
|
@@ -48,7 +48,7 @@ module OpenC3
|
|
|
48
48
|
# used to perform lookups when the packet and item are known but the
|
|
49
49
|
# packet is not.
|
|
50
50
|
# @param warnings [Array<String>] Any warning strings generated while
|
|
51
|
-
# parsing this command will be
|
|
51
|
+
# parsing this command will be appended to this array
|
|
52
52
|
def self.parse_telemetry(parser, target_name, telemetry, latest_data, warnings)
|
|
53
53
|
parser = PacketParser.new(parser)
|
|
54
54
|
parser.verify_parameters()
|
|
@@ -188,21 +188,21 @@ module OpenC3
|
|
|
188
188
|
|
|
189
189
|
# Define an item in the structure. This creates a new instance of the
|
|
190
190
|
# item_class as given in the constructor and adds it to the items hash. It
|
|
191
|
-
# also resizes the buffer to
|
|
191
|
+
# also resizes the buffer to accommodate the new item.
|
|
192
192
|
#
|
|
193
193
|
# @param name [String] Name of the item. Used by the items hash to retrieve
|
|
194
194
|
# the item.
|
|
195
195
|
# @param bit_offset [Integer] Bit offset of the item in the raw buffer
|
|
196
196
|
# @param bit_size [Integer] Bit size of the item in the raw buffer
|
|
197
197
|
# @param data_type [Symbol] Type of data contained by the item. This is
|
|
198
|
-
#
|
|
198
|
+
# dependent on the item_class but by default see StructureItem.
|
|
199
199
|
# @param array_size [Integer] Set to a non nil value if the item is to
|
|
200
200
|
# represented as an array.
|
|
201
201
|
# @param endianness [Symbol] Endianness of this item. By default the
|
|
202
|
-
# endianness as set in the
|
|
202
|
+
# endianness as set in the constructor is used.
|
|
203
203
|
# @param overflow [Symbol] How to handle value overflows. This is
|
|
204
|
-
#
|
|
205
|
-
# @return [StrutureItem] The
|
|
204
|
+
# dependent on the item_class but by default see StructureItem.
|
|
205
|
+
# @return [StrutureItem] The structure item defined
|
|
206
206
|
def define_item(name, bit_offset, bit_size, data_type, array_size = nil, endianness = @default_endianness, overflow = :ERROR)
|
|
207
207
|
# Create the item
|
|
208
208
|
item = @item_class.new(name, bit_offset, bit_size, data_type, endianness, array_size, overflow)
|
|
@@ -210,10 +210,10 @@ module OpenC3
|
|
|
210
210
|
end
|
|
211
211
|
|
|
212
212
|
# Adds the given item to the items hash. It also resizes the buffer to
|
|
213
|
-
#
|
|
213
|
+
# accommodate the new item.
|
|
214
214
|
#
|
|
215
215
|
# @param item [StructureItem] The structure item to add
|
|
216
|
-
# @return [StrutureItem] The
|
|
216
|
+
# @return [StrutureItem] The structure item defined
|
|
217
217
|
def define(item)
|
|
218
218
|
# Handle Overwriting Existing Item
|
|
219
219
|
if @items[item.name]
|
|
@@ -289,7 +289,7 @@ module OpenC3
|
|
|
289
289
|
|
|
290
290
|
# Define an item at the end of the structure. This creates a new instance of the
|
|
291
291
|
# item_class as given in the constructor and adds it to the items hash. It
|
|
292
|
-
# also resizes the buffer to
|
|
292
|
+
# also resizes the buffer to accommodate the new item.
|
|
293
293
|
#
|
|
294
294
|
# @param name (see #define_item)
|
|
295
295
|
# @param bit_size (see #define_item)
|
|
@@ -307,7 +307,7 @@ module OpenC3
|
|
|
307
307
|
end
|
|
308
308
|
|
|
309
309
|
# Adds an item at the end of the structure. It adds the item to the items
|
|
310
|
-
# hash and resizes the buffer to
|
|
310
|
+
# hash and resizes the buffer to accommodate the new item.
|
|
311
311
|
#
|
|
312
312
|
# @param item (see #define)
|
|
313
313
|
# @return (see #define)
|
|
@@ -493,7 +493,7 @@ module OpenC3
|
|
|
493
493
|
# further modifications to the buffer have no effect on the structure
|
|
494
494
|
# items.
|
|
495
495
|
#
|
|
496
|
-
# @param buffer [String] Buffer of data to back the
|
|
496
|
+
# @param buffer [String] Buffer of data to back the structure items
|
|
497
497
|
def buffer=(buffer)
|
|
498
498
|
synchronize() do
|
|
499
499
|
internal_buffer_equals(buffer)
|
|
@@ -507,8 +507,8 @@ module OpenC3
|
|
|
507
507
|
# buffer of data
|
|
508
508
|
def clone
|
|
509
509
|
structure = super()
|
|
510
|
-
# Use instance_variable_set since we have
|
|
511
|
-
# additional work that isn't
|
|
510
|
+
# Use instance_variable_set since we have overridden buffer= to do
|
|
511
|
+
# additional work that isn't necessary here
|
|
512
512
|
structure.instance_variable_set("@buffer".freeze, @buffer.clone) if @buffer
|
|
513
513
|
# Need to update reference packet in the Accessor
|
|
514
514
|
structure.accessor.packet = structure
|
|
@@ -617,9 +617,17 @@ module OpenC3
|
|
|
617
617
|
# Anything with a negative bit offset should be left alone
|
|
618
618
|
if item.original_bit_offset >= 0
|
|
619
619
|
item.bit_offset = item.original_bit_offset + adjustment
|
|
620
|
-
|
|
620
|
+
|
|
621
|
+
# May need to update adjustment with variable length items
|
|
622
|
+
# Note legacy variable length does not push anything
|
|
623
|
+
if item.data_type != :DERIVED and item.variable_bit_size # Not DERIVED and New Variable Length
|
|
624
|
+
# Calculate the actual current size of this variable length item
|
|
621
625
|
new_bit_size = calculate_total_bit_size(item)
|
|
626
|
+
|
|
622
627
|
if item.original_bit_size != new_bit_size
|
|
628
|
+
# Bit size has changed from original - so we need to adjust everything after this item
|
|
629
|
+
# This includes items that may have the same bit_offset as the variable length item because it
|
|
630
|
+
# started out at zero bit_size
|
|
623
631
|
adjustment += (new_bit_size - item.original_bit_size)
|
|
624
632
|
end
|
|
625
633
|
end
|
|
@@ -95,6 +95,9 @@ module OpenC3
|
|
|
95
95
|
# @return [Hash] Variable bit size information
|
|
96
96
|
attr_reader :variable_bit_size
|
|
97
97
|
|
|
98
|
+
# @return [Integer] Incrementing value that shows relative order items are created
|
|
99
|
+
attr_reader :create_index
|
|
100
|
+
|
|
98
101
|
# Create a StructureItem by setting all the attributes. It
|
|
99
102
|
# calls all the setter routines to do the attribute verification and then
|
|
100
103
|
# verifies the overall integrity.
|
|
@@ -238,73 +241,56 @@ module OpenC3
|
|
|
238
241
|
verify_overall() if @structure_item_constructed
|
|
239
242
|
end
|
|
240
243
|
|
|
241
|
-
def create_index
|
|
242
|
-
@create_index.to_i
|
|
243
|
-
end
|
|
244
|
-
|
|
245
244
|
if RUBY_ENGINE != 'ruby' or ENV['OPENC3_NO_EXT']
|
|
246
|
-
# Comparison Operator based on bit_offset
|
|
247
|
-
# with different names or bit sizes are equal if they have the same bit
|
|
248
|
-
# offset.
|
|
245
|
+
# Comparison Operator primarily based on bit_offset
|
|
249
246
|
def <=>(other)
|
|
250
247
|
return nil unless other.kind_of?(StructureItem)
|
|
251
248
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
#
|
|
256
|
-
if
|
|
257
|
-
|
|
258
|
-
# This allows derived items with bit_size of 0 to be listed first
|
|
259
|
-
# Compare based on bit size then create index
|
|
260
|
-
if @bit_size == other_bit_size
|
|
261
|
-
if @create_index
|
|
262
|
-
if @create_index <= other.create_index
|
|
263
|
-
return -1
|
|
264
|
-
else
|
|
265
|
-
return 1
|
|
266
|
-
end
|
|
267
|
-
else
|
|
268
|
-
return 0
|
|
269
|
-
end
|
|
270
|
-
elsif @bit_size < other_bit_size
|
|
249
|
+
other_original_bit_offset = other.original_bit_offset
|
|
250
|
+
|
|
251
|
+
# Derived items should be first in the list with multiple derived sorted
|
|
252
|
+
# by create_index
|
|
253
|
+
if @data_type == :DERIVED
|
|
254
|
+
if other.data_type != :DERIVED
|
|
271
255
|
return -1
|
|
272
256
|
else
|
|
273
|
-
|
|
257
|
+
if @create_index <= other.create_index
|
|
258
|
+
return -1
|
|
259
|
+
else
|
|
260
|
+
return 1
|
|
261
|
+
end
|
|
274
262
|
end
|
|
263
|
+
elsif other.data_type == :DERIVED
|
|
264
|
+
return 1
|
|
275
265
|
end
|
|
276
266
|
|
|
277
|
-
# Handle
|
|
278
|
-
if ((@
|
|
267
|
+
# Handle non-derived items
|
|
268
|
+
if ((@original_bit_offset >= 0) && (other_original_bit_offset >= 0)) || ((@original_bit_offset < 0) && (other_original_bit_offset < 0))
|
|
279
269
|
# Both Have Same Sign
|
|
280
|
-
if @
|
|
281
|
-
|
|
282
|
-
|
|
270
|
+
if @original_bit_offset == other_original_bit_offset
|
|
271
|
+
# New Variable Bit Size items are before regular items
|
|
272
|
+
if @variable_bit_size
|
|
273
|
+
if not other.variable_bit_size
|
|
283
274
|
return -1
|
|
284
|
-
else
|
|
285
|
-
return 1
|
|
286
275
|
end
|
|
276
|
+
# If both variable_bit_size use create index
|
|
277
|
+
elsif other.variable_bit_size
|
|
278
|
+
return 1
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
if @create_index <= other.create_index
|
|
282
|
+
return -1
|
|
287
283
|
else
|
|
288
|
-
return
|
|
284
|
+
return 1
|
|
289
285
|
end
|
|
290
|
-
elsif @
|
|
286
|
+
elsif @original_bit_offset <= other_original_bit_offset
|
|
291
287
|
return -1
|
|
292
288
|
else
|
|
293
289
|
return 1
|
|
294
290
|
end
|
|
295
291
|
else
|
|
296
292
|
# Different Signs
|
|
297
|
-
if @
|
|
298
|
-
if @create_index
|
|
299
|
-
if @create_index < other.create_index
|
|
300
|
-
return -1
|
|
301
|
-
else
|
|
302
|
-
return 1
|
|
303
|
-
end
|
|
304
|
-
else
|
|
305
|
-
return 0
|
|
306
|
-
end
|
|
307
|
-
elsif @bit_offset < other_bit_offset
|
|
293
|
+
if @original_bit_offset < other_original_bit_offset
|
|
308
294
|
return 1
|
|
309
295
|
else
|
|
310
296
|
return -1
|