openc3 5.10.1 → 5.11.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/Rakefile +3 -2
- data/data/config/target.yaml +9 -0
- data/ext/openc3/ext/packet/packet.c +3 -0
- data/ext/openc3/ext/reducer_microservice/extconf.rb +13 -0
- data/ext/openc3/ext/reducer_microservice/reducer_microservice.c +165 -0
- data/ext/openc3/ext/structure/structure.c +7 -9
- data/lib/openc3/accessors/accessor.rb +53 -3
- data/lib/openc3/accessors/binary_accessor.rb +16 -0
- data/lib/openc3/accessors/cbor_accessor.rb +3 -3
- data/lib/openc3/accessors/form_accessor.rb +78 -0
- data/lib/openc3/accessors/http_accessor.rb +145 -0
- data/lib/openc3/accessors/json_accessor.rb +19 -3
- data/lib/openc3/accessors/xml_accessor.rb +18 -1
- data/lib/openc3/accessors.rb +3 -1
- data/lib/openc3/config/config_parser.rb +7 -5
- data/lib/openc3/config/meta_config_parser.rb +1 -1
- data/lib/openc3/core_ext/string.rb +16 -1
- data/lib/openc3/interfaces/http_client_interface.rb +202 -0
- data/lib/openc3/interfaces/http_server_interface.rb +183 -0
- data/lib/openc3/interfaces/interface.rb +86 -16
- data/lib/openc3/interfaces/mqtt_interface.rb +6 -5
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +11 -11
- data/lib/openc3/interfaces/protocols/cobs_protocol.rb +7 -7
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +7 -7
- data/lib/openc3/interfaces/protocols/length_protocol.rb +6 -6
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +9 -5
- data/lib/openc3/interfaces/protocols/protocol.rb +8 -6
- data/lib/openc3/interfaces/protocols/slip_protocol.rb +8 -8
- data/lib/openc3/interfaces/protocols/template_protocol.rb +6 -7
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +4 -4
- data/lib/openc3/interfaces/simulated_target_interface.rb +2 -0
- data/lib/openc3/interfaces/stream_interface.rb +6 -4
- data/lib/openc3/interfaces/tcpip_server_interface.rb +2 -0
- data/lib/openc3/interfaces/udp_interface.rb +8 -5
- data/lib/openc3/interfaces.rb +2 -0
- data/lib/openc3/logs/buffered_packet_log_writer.rb +6 -7
- data/lib/openc3/logs/log_writer.rb +2 -10
- data/lib/openc3/logs/packet_log_constants.rb +13 -3
- data/lib/openc3/logs/packet_log_reader.rb +35 -98
- data/lib/openc3/logs/packet_log_writer.rb +24 -62
- data/lib/openc3/logs/text_log_writer.rb +32 -6
- data/lib/openc3/microservices/cleanup_microservice.rb +23 -16
- data/lib/openc3/microservices/decom_microservice.rb +8 -20
- data/lib/openc3/microservices/log_microservice.rb +3 -1
- data/lib/openc3/microservices/reaction_microservice.rb +22 -11
- data/lib/openc3/microservices/reducer_microservice.rb +174 -130
- data/lib/openc3/{models/notification_model.rb → microservices/scope_cleanup_microservice.rb} +20 -21
- data/lib/openc3/microservices/text_log_microservice.rb +2 -5
- data/lib/openc3/microservices/timeline_microservice.rb +0 -1
- data/lib/openc3/microservices/trigger_group_microservice.rb +0 -1
- data/lib/openc3/migrations/20230915000002_no_scope_log_messages.rb +44 -0
- data/lib/openc3/models/microservice_model.rb +1 -1
- data/lib/openc3/models/scope_model.rb +65 -34
- data/lib/openc3/models/target_model.rb +25 -5
- data/lib/openc3/models/tool_model.rb +14 -2
- data/lib/openc3/models/widget_model.rb +1 -1
- data/lib/openc3/packets/json_packet.rb +10 -2
- data/lib/openc3/packets/packet.rb +30 -9
- data/lib/openc3/packets/packet_config.rb +6 -2
- data/lib/openc3/packets/parsers/packet_item_parser.rb +11 -6
- data/lib/openc3/packets/structure.rb +19 -12
- data/lib/openc3/script/storage.rb +1 -1
- data/lib/openc3/script/web_socket_api.rb +17 -14
- data/lib/openc3/topics/telemetry_topic.rb +2 -1
- data/lib/openc3/utilities/bucket_utilities.rb +2 -0
- data/lib/openc3/utilities/cli_generator.rb +1 -1
- data/lib/openc3/utilities/logger.rb +62 -47
- data/lib/openc3/utilities/metric.rb +19 -1
- data/lib/openc3/utilities/sleeper.rb +3 -1
- data/lib/openc3/utilities/throttle.rb +76 -0
- data/lib/openc3/version.rb +6 -6
- data/templates/tool_angular/package.json +20 -20
- data/templates/tool_angular/yarn.lock +112 -106
- data/templates/tool_react/package.json +16 -18
- data/templates/tool_react/yarn.lock +977 -664
- data/templates/tool_svelte/.prettierrc.js +5 -0
- data/templates/tool_svelte/package.json +18 -18
- data/templates/tool_svelte/src/services/cable.js +1 -1
- data/templates/tool_svelte/src/services/openc3-api.js +173 -173
- data/templates/tool_svelte/yarn.lock +767 -665
- data/templates/tool_vue/package.json +10 -10
- data/templates/tool_vue/yarn.lock +225 -43
- data/templates/widget/package.json +10 -10
- data/templates/widget/yarn.lock +223 -46
- metadata +41 -4
- data/lib/openc3/topics/notifications_topic.rb +0 -31
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
require 'openc3/api/api'
|
|
24
24
|
require 'openc3/logs/stream_log_pair'
|
|
25
25
|
require 'openc3/utilities/secrets'
|
|
26
|
+
require 'rufus-scheduler'
|
|
26
27
|
|
|
27
28
|
module OpenC3
|
|
28
29
|
# Define a class to allow interfaces and protocols to reject commands without
|
|
@@ -140,6 +141,9 @@ module OpenC3
|
|
|
140
141
|
# @return [Secrets] Interface secrets manager class
|
|
141
142
|
attr_accessor :secrets
|
|
142
143
|
|
|
144
|
+
# @return [Scheduler] Scheduler used for periodic commanding
|
|
145
|
+
attr_accessor :scheduler
|
|
146
|
+
|
|
143
147
|
# Initialize default attribute values
|
|
144
148
|
def initialize
|
|
145
149
|
@name = self.class.to_s.split("::")[-1] # Remove namespacing if present
|
|
@@ -177,12 +181,38 @@ module OpenC3
|
|
|
177
181
|
@config_params = []
|
|
178
182
|
@interfaces = []
|
|
179
183
|
@secrets = Secrets.getClient
|
|
184
|
+
@scheduler = nil
|
|
180
185
|
end
|
|
181
186
|
|
|
182
187
|
# Connects the interface to its target(s). Must be implemented by a
|
|
183
188
|
# subclass.
|
|
184
189
|
def connect
|
|
185
190
|
(@read_protocols | @write_protocols).each { |protocol| protocol.connect_reset }
|
|
191
|
+
|
|
192
|
+
periodic_cmds = @options['PERIODIC_CMD']
|
|
193
|
+
if periodic_cmds
|
|
194
|
+
if not @scheduler
|
|
195
|
+
@scheduler = Rufus::Scheduler.new
|
|
196
|
+
|
|
197
|
+
periodic_cmds.each do |log_dont_log, period, cmd_string|
|
|
198
|
+
log_dont_log.upcase!
|
|
199
|
+
period = "#{period.to_f}s"
|
|
200
|
+
@scheduler.every period do
|
|
201
|
+
begin
|
|
202
|
+
if log_dont_log == 'DONT_LOG'
|
|
203
|
+
cmd(cmd_string, log_message: false)
|
|
204
|
+
else
|
|
205
|
+
cmd(cmd_string)
|
|
206
|
+
end
|
|
207
|
+
rescue Exception => err
|
|
208
|
+
Logger.error("Error sending periodic cmd(#{cmd_string}):\n#{err.formatted}")
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
else
|
|
213
|
+
@scheduler.resume
|
|
214
|
+
end
|
|
215
|
+
end
|
|
186
216
|
end
|
|
187
217
|
|
|
188
218
|
# Indicates if the interface is connected to its target(s) or not. Must be
|
|
@@ -194,6 +224,11 @@ module OpenC3
|
|
|
194
224
|
# Disconnects the interface from its target(s). Must be implemented by a
|
|
195
225
|
# subclass.
|
|
196
226
|
def disconnect
|
|
227
|
+
periodic_cmds = @options['PERIODIC_CMD']
|
|
228
|
+
if periodic_cmds and @scheduler
|
|
229
|
+
@scheduler.pause
|
|
230
|
+
end
|
|
231
|
+
|
|
197
232
|
(@read_protocols | @write_protocols).each { |protocol| protocol.disconnect_reset }
|
|
198
233
|
end
|
|
199
234
|
|
|
@@ -201,7 +236,7 @@ module OpenC3
|
|
|
201
236
|
raise "read_interface not defined by Interface"
|
|
202
237
|
end
|
|
203
238
|
|
|
204
|
-
def write_interface
|
|
239
|
+
def write_interface(data, extra = nil)
|
|
205
240
|
raise "write_interface not defined by Interface"
|
|
206
241
|
end
|
|
207
242
|
|
|
@@ -217,9 +252,10 @@ module OpenC3
|
|
|
217
252
|
# Protocols may have cached data for a packet, so initially just inject a blank string
|
|
218
253
|
# Otherwise we can hold off outputing other packets where all the data has already
|
|
219
254
|
# been received
|
|
255
|
+
extra = nil
|
|
220
256
|
if !first or @read_protocols.length <= 0
|
|
221
257
|
# Read data for a packet
|
|
222
|
-
data = read_interface()
|
|
258
|
+
data, extra = read_interface()
|
|
223
259
|
unless data
|
|
224
260
|
Logger.info("#{@name}: read_interface requested disconnect")
|
|
225
261
|
return nil
|
|
@@ -230,7 +266,12 @@ module OpenC3
|
|
|
230
266
|
end
|
|
231
267
|
|
|
232
268
|
@read_protocols.each do |protocol|
|
|
233
|
-
|
|
269
|
+
# Extra check is for backwards compatibility
|
|
270
|
+
if extra
|
|
271
|
+
data, extra = protocol.read_data(data, extra)
|
|
272
|
+
else
|
|
273
|
+
data, extra = protocol.read_data(data)
|
|
274
|
+
end
|
|
234
275
|
if data == :DISCONNECT
|
|
235
276
|
Logger.info("#{@name}: Protocol #{protocol.class} read_data requested disconnect")
|
|
236
277
|
return nil
|
|
@@ -239,7 +280,12 @@ module OpenC3
|
|
|
239
280
|
end
|
|
240
281
|
next if data == :STOP
|
|
241
282
|
|
|
242
|
-
|
|
283
|
+
# Extra check is for backwards compatibility
|
|
284
|
+
if extra
|
|
285
|
+
packet = convert_data_to_packet(data, extra)
|
|
286
|
+
else
|
|
287
|
+
packet = convert_data_to_packet(data)
|
|
288
|
+
end
|
|
243
289
|
|
|
244
290
|
# Potentially modify packet
|
|
245
291
|
@read_protocols.each do |protocol|
|
|
@@ -283,11 +329,16 @@ module OpenC3
|
|
|
283
329
|
return if packet == :STOP
|
|
284
330
|
end
|
|
285
331
|
|
|
286
|
-
data = convert_packet_to_data(packet)
|
|
332
|
+
data, extra = convert_packet_to_data(packet)
|
|
287
333
|
|
|
288
334
|
# Potentially modify packet data
|
|
289
335
|
@write_protocols.each do |protocol|
|
|
290
|
-
|
|
336
|
+
# Extra check is for backwards compatibility
|
|
337
|
+
if extra
|
|
338
|
+
data, extra = protocol.write_data(data, extra)
|
|
339
|
+
else
|
|
340
|
+
data, extra = protocol.write_data(data)
|
|
341
|
+
end
|
|
291
342
|
if data == :DISCONNECT
|
|
292
343
|
Logger.info("#{@name}: Protocol #{protocol.class} write_data requested disconnect")
|
|
293
344
|
disconnect()
|
|
@@ -297,11 +348,20 @@ module OpenC3
|
|
|
297
348
|
end
|
|
298
349
|
|
|
299
350
|
# Actually write out data if not handled by protocol
|
|
300
|
-
|
|
351
|
+
# Extra check is for backwards compatibility
|
|
352
|
+
if extra
|
|
353
|
+
write_interface(data, extra)
|
|
354
|
+
else
|
|
355
|
+
write_interface(data)
|
|
356
|
+
end
|
|
301
357
|
|
|
302
358
|
# Potentially block and wait for response
|
|
303
359
|
@write_protocols.each do |protocol|
|
|
304
|
-
|
|
360
|
+
if extra
|
|
361
|
+
packet, data, extra = protocol.post_write_interface(packet, data, extra)
|
|
362
|
+
else
|
|
363
|
+
packet, data, extra = protocol.post_write_interface(packet, data)
|
|
364
|
+
end
|
|
305
365
|
if packet == :DISCONNECT
|
|
306
366
|
Logger.info("#{@name}: Protocol #{protocol.class} post_write_packet requested disconnect")
|
|
307
367
|
disconnect()
|
|
@@ -317,12 +377,12 @@ module OpenC3
|
|
|
317
377
|
# Writes preformatted data onto the interface. Malformed data may cause
|
|
318
378
|
# problems.
|
|
319
379
|
# @param data [String] The raw data to send out the interface
|
|
320
|
-
def write_raw(data)
|
|
380
|
+
def write_raw(data, extra = nil)
|
|
321
381
|
raise "Interface not connected for write_raw: #{@name}" unless connected?
|
|
322
382
|
raise "Interface not write-rawable: #{@name}" unless write_raw_allowed?
|
|
323
383
|
|
|
324
384
|
_write do
|
|
325
|
-
write_interface(data)
|
|
385
|
+
write_interface(data, extra)
|
|
326
386
|
end
|
|
327
387
|
end
|
|
328
388
|
|
|
@@ -429,15 +489,25 @@ module OpenC3
|
|
|
429
489
|
# @param option_name name of the option
|
|
430
490
|
# @param option_values array of option values
|
|
431
491
|
def set_option(option_name, option_values)
|
|
432
|
-
|
|
492
|
+
option_name_upcase = option_name.upcase
|
|
493
|
+
|
|
494
|
+
if option_name_upcase == 'PERIODIC_CMD'
|
|
495
|
+
# OPTION PERIODIC_CMD LOG/DONT_LOG 1.0 "INST COLLECT with TYPE NORMAL"
|
|
496
|
+
@options[option_name_upcase] ||= []
|
|
497
|
+
@options[option_name_upcase] << option_values.clone
|
|
498
|
+
else
|
|
499
|
+
@options[option_name_upcase] = option_values.clone
|
|
500
|
+
end
|
|
433
501
|
end
|
|
434
502
|
|
|
435
503
|
# Called to convert the read data into a OpenC3 Packet object
|
|
436
504
|
#
|
|
437
505
|
# @param data [String] Raw packet data
|
|
438
506
|
# @return [Packet] OpenC3 Packet with buffer filled with data
|
|
439
|
-
def convert_data_to_packet(data)
|
|
440
|
-
Packet.new(nil, nil, :BIG_ENDIAN, nil, data)
|
|
507
|
+
def convert_data_to_packet(data, extra = nil)
|
|
508
|
+
packet = Packet.new(nil, nil, :BIG_ENDIAN, nil, data)
|
|
509
|
+
packet.extra = extra
|
|
510
|
+
return packet
|
|
441
511
|
end
|
|
442
512
|
|
|
443
513
|
# Called to convert a packet into the data to send
|
|
@@ -445,7 +515,7 @@ module OpenC3
|
|
|
445
515
|
# @param packet [Packet] Packet to extract data from
|
|
446
516
|
# @return data
|
|
447
517
|
def convert_packet_to_data(packet)
|
|
448
|
-
packet.buffer(true) # Copy buffer so logged command isn't modified
|
|
518
|
+
return packet.buffer(true), packet.extra # Copy buffer so logged command isn't modified
|
|
449
519
|
end
|
|
450
520
|
|
|
451
521
|
# Called to read data and manipulate it until enough data is
|
|
@@ -456,7 +526,7 @@ module OpenC3
|
|
|
456
526
|
# method is called. Subclasses must implement this method.
|
|
457
527
|
#
|
|
458
528
|
# @return [String] Raw packet data
|
|
459
|
-
def read_interface_base(data)
|
|
529
|
+
def read_interface_base(data, extra = nil)
|
|
460
530
|
@read_raw_data_time = Time.now
|
|
461
531
|
@read_raw_data = data.clone
|
|
462
532
|
@bytes_read += data.length
|
|
@@ -469,7 +539,7 @@ module OpenC3
|
|
|
469
539
|
#
|
|
470
540
|
# @param data [String] Raw packet data
|
|
471
541
|
# @return [String] The exact data written
|
|
472
|
-
def write_interface_base(data)
|
|
542
|
+
def write_interface_base(data, extra = nil)
|
|
473
543
|
@written_raw_data_time = Time.now
|
|
474
544
|
@written_raw_data = data.clone
|
|
475
545
|
@bytes_written += data.length
|
|
@@ -196,19 +196,20 @@ module OpenC3
|
|
|
196
196
|
return nil
|
|
197
197
|
end
|
|
198
198
|
@read_topics << topic
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
extra = nil
|
|
200
|
+
read_interface_base(data, extra)
|
|
201
|
+
return data, extra
|
|
201
202
|
rescue IOError # Disconnected
|
|
202
203
|
return nil
|
|
203
204
|
end
|
|
204
205
|
|
|
205
206
|
# Writes to the socket
|
|
206
207
|
# @param data [String] Raw packet data
|
|
207
|
-
def write_interface(data)
|
|
208
|
-
write_interface_base(data)
|
|
208
|
+
def write_interface(data, extra = nil)
|
|
209
|
+
write_interface_base(data, extra)
|
|
209
210
|
topic = @write_topics.shift
|
|
210
211
|
@client.publish(topic, data)
|
|
211
|
-
data
|
|
212
|
+
return data, extra
|
|
212
213
|
end
|
|
213
214
|
|
|
214
215
|
# Supported Options
|
|
@@ -61,15 +61,16 @@ module OpenC3
|
|
|
61
61
|
# protocols giving them the same opportunity.
|
|
62
62
|
#
|
|
63
63
|
# @return [String|nil] Data for a packet consisting of the bytes read
|
|
64
|
-
def read_data(data)
|
|
64
|
+
def read_data(data, extra = nil)
|
|
65
65
|
@data << data
|
|
66
|
+
@extra = extra
|
|
66
67
|
|
|
67
68
|
while true
|
|
68
69
|
control = handle_sync_pattern()
|
|
69
70
|
return control if control and data.length > 0 # Only return here if not blank string test
|
|
70
71
|
|
|
71
72
|
# Reduce the data to a single packet
|
|
72
|
-
packet_data = reduce_to_single_packet()
|
|
73
|
+
packet_data, extra = reduce_to_single_packet()
|
|
73
74
|
if packet_data == :RESYNC
|
|
74
75
|
@sync_state = :SEARCHING
|
|
75
76
|
next if data.length > 0 # Only immediately resync if not blank string test
|
|
@@ -81,9 +82,9 @@ module OpenC3
|
|
|
81
82
|
# On blank string test, return blank string (unless we had a packet or need disconnect)
|
|
82
83
|
# The base class handles the special case of returning STOP if on the last protocol in the
|
|
83
84
|
# chain
|
|
84
|
-
return super(data)
|
|
85
|
+
return super(data, extra)
|
|
85
86
|
else
|
|
86
|
-
return packet_data # Return any control code if not on blank string test
|
|
87
|
+
return packet_data, extra # Return any control code if not on blank string test
|
|
87
88
|
end
|
|
88
89
|
end
|
|
89
90
|
|
|
@@ -91,7 +92,7 @@ module OpenC3
|
|
|
91
92
|
|
|
92
93
|
# Discard leading bytes if necessary
|
|
93
94
|
packet_data.replace(packet_data[@discard_leading_bytes..-1]) if @discard_leading_bytes > 0
|
|
94
|
-
return packet_data
|
|
95
|
+
return packet_data, extra
|
|
95
96
|
end
|
|
96
97
|
end
|
|
97
98
|
|
|
@@ -115,7 +116,7 @@ module OpenC3
|
|
|
115
116
|
#
|
|
116
117
|
# @param data [String] Raw packet data
|
|
117
118
|
# @return [String] Potentially modified packet data
|
|
118
|
-
def write_data(data)
|
|
119
|
+
def write_data(data, extra = nil)
|
|
119
120
|
# If we're filling the sync pattern and discarding the leading bytes
|
|
120
121
|
# during a read then we need to put them back during a write.
|
|
121
122
|
# If we're discarding the bytes then by definition they can't be part
|
|
@@ -127,7 +128,7 @@ module OpenC3
|
|
|
127
128
|
data, :BIG_ENDIAN, :ERROR)
|
|
128
129
|
end
|
|
129
130
|
end
|
|
130
|
-
super(data)
|
|
131
|
+
return super(data, extra)
|
|
131
132
|
end
|
|
132
133
|
|
|
133
134
|
# @return [Boolean] control code (nil, :STOP)
|
|
@@ -156,8 +157,7 @@ module OpenC3
|
|
|
156
157
|
|
|
157
158
|
if found
|
|
158
159
|
if sync_index != 0
|
|
159
|
-
|
|
160
|
-
log_discard(discard_length, true)
|
|
160
|
+
log_discard(sync_index, true)
|
|
161
161
|
# Delete Data Before Sync Pattern
|
|
162
162
|
@data.replace(@data[sync_index..-1])
|
|
163
163
|
end
|
|
@@ -165,7 +165,7 @@ module OpenC3
|
|
|
165
165
|
return nil
|
|
166
166
|
|
|
167
167
|
else # not found
|
|
168
|
-
log_discard(
|
|
168
|
+
log_discard(sync_index + 1, false)
|
|
169
169
|
# Delete Data Before and including first character of suspected sync Pattern
|
|
170
170
|
@data.replace(@data[(sync_index + 1)..-1])
|
|
171
171
|
next
|
|
@@ -203,7 +203,7 @@ module OpenC3
|
|
|
203
203
|
# Reduce to packet data and clear data for next packet
|
|
204
204
|
packet_data = @data.clone
|
|
205
205
|
@data.replace('')
|
|
206
|
-
packet_data
|
|
206
|
+
return packet_data, @extra
|
|
207
207
|
end
|
|
208
208
|
end
|
|
209
209
|
end
|
|
@@ -53,9 +53,9 @@ module OpenC3
|
|
|
53
53
|
)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
def read_data(data)
|
|
57
|
-
data = super(data)
|
|
58
|
-
return data if data.length <= 0 or Symbol === data
|
|
56
|
+
def read_data(data, extra = nil)
|
|
57
|
+
data, extra = super(data, extra)
|
|
58
|
+
return data, extra if data.length <= 0 or Symbol === data
|
|
59
59
|
|
|
60
60
|
result_data = ''
|
|
61
61
|
while data.length > 1
|
|
@@ -75,10 +75,10 @@ module OpenC3
|
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
-
return result_data
|
|
78
|
+
return result_data, extra
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
def write_data(data)
|
|
81
|
+
def write_data(data, extra = nil)
|
|
82
82
|
# Intentionally not calling super()
|
|
83
83
|
|
|
84
84
|
need_insert = false
|
|
@@ -90,7 +90,7 @@ module OpenC3
|
|
|
90
90
|
result_data << data[0..253]
|
|
91
91
|
data = data[254..-1]
|
|
92
92
|
need_insert = false
|
|
93
|
-
else # index <=
|
|
93
|
+
else # index <= 253 or (index.nil? and data.length < 254)
|
|
94
94
|
if index
|
|
95
95
|
result_data << [index + 1].pack('C')
|
|
96
96
|
if index >= 1
|
|
@@ -113,7 +113,7 @@ module OpenC3
|
|
|
113
113
|
# Terminate message with 0x00
|
|
114
114
|
result_data << "\x00"
|
|
115
115
|
|
|
116
|
-
return result_data
|
|
116
|
+
return result_data, extra
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
|
|
@@ -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/config/config_parser'
|
|
@@ -147,8 +147,8 @@ module OpenC3
|
|
|
147
147
|
end
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
def read_data(data)
|
|
151
|
-
return super(data) if data.length <= 0
|
|
150
|
+
def read_data(data, extra = nil)
|
|
151
|
+
return super(data, extra) if data.length <= 0
|
|
152
152
|
|
|
153
153
|
crc = BinaryAccessor.read(@bit_offset, @bit_size, :UINT, data, @endianness)
|
|
154
154
|
calculated_crc = @crc.calc(data[0...(@bit_offset / 8)])
|
|
@@ -163,9 +163,9 @@ module OpenC3
|
|
|
163
163
|
new_data = new_data[0...(@bit_offset / 8)]
|
|
164
164
|
end_range = (@bit_offset + @bit_size) / 8
|
|
165
165
|
new_data << data[end_range..-1] if end_range != 0
|
|
166
|
-
return new_data
|
|
166
|
+
return new_data, extra
|
|
167
167
|
end
|
|
168
|
-
return data
|
|
168
|
+
return data, extra
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
def write_packet(packet)
|
|
@@ -177,7 +177,7 @@ module OpenC3
|
|
|
177
177
|
packet
|
|
178
178
|
end
|
|
179
179
|
|
|
180
|
-
def write_data(data)
|
|
180
|
+
def write_data(data, extra = nil)
|
|
181
181
|
unless @write_item_name
|
|
182
182
|
if @bit_size == 64
|
|
183
183
|
crc = @crc.calc(data)
|
|
@@ -190,7 +190,7 @@ module OpenC3
|
|
|
190
190
|
BinaryAccessor.write(crc, -@bit_size, @bit_size, :UINT, data, @endianness, :ERROR)
|
|
191
191
|
end
|
|
192
192
|
end
|
|
193
|
-
data
|
|
193
|
+
return data, extra
|
|
194
194
|
end
|
|
195
195
|
end
|
|
196
196
|
end
|
|
@@ -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/binary_accessor'
|
|
@@ -96,7 +96,7 @@ module OpenC3
|
|
|
96
96
|
# If the start of the length field is past what we discard, then the
|
|
97
97
|
# length field is inside the packet
|
|
98
98
|
if @length_bit_offset >= (@discard_leading_bytes * 8)
|
|
99
|
-
length = calculate_length(packet.buffer.length + @discard_leading_bytes)
|
|
99
|
+
length = calculate_length(packet.buffer(false).length + @discard_leading_bytes)
|
|
100
100
|
# Subtract off the discarded bytes since they haven't been added yet
|
|
101
101
|
# Adding bytes happens in the write_data method
|
|
102
102
|
offset = @length_bit_offset - (@discard_leading_bytes * 8)
|
|
@@ -112,8 +112,8 @@ module OpenC3
|
|
|
112
112
|
#
|
|
113
113
|
# @param data [String] Raw packet data
|
|
114
114
|
# @return [String] Potentially modified packet data
|
|
115
|
-
def write_data(data)
|
|
116
|
-
data = super(data)
|
|
115
|
+
def write_data(data, extra = nil)
|
|
116
|
+
data, extra = super(data, extra)
|
|
117
117
|
if @fill_fields
|
|
118
118
|
# If the start of the length field is before what we discard, then the
|
|
119
119
|
# length field is outside the packet
|
|
@@ -122,7 +122,7 @@ module OpenC3
|
|
|
122
122
|
data, @length_endianness, :ERROR)
|
|
123
123
|
end
|
|
124
124
|
end
|
|
125
|
-
return data
|
|
125
|
+
return data, extra
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
protected
|
|
@@ -162,7 +162,7 @@ module OpenC3
|
|
|
162
162
|
packet_data = @data[0..(packet_length - 1)]
|
|
163
163
|
@data.replace(@data[packet_length..-1])
|
|
164
164
|
|
|
165
|
-
return packet_data
|
|
165
|
+
return packet_data, @extra
|
|
166
166
|
end
|
|
167
167
|
end
|
|
168
168
|
end
|
|
@@ -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/interfaces/protocols/burst_protocol'
|
|
@@ -49,7 +49,11 @@ module OpenC3
|
|
|
49
49
|
packet.packet_name = @read_packet_name
|
|
50
50
|
if @mode == 4 # COSMOS4.3+ Protocol
|
|
51
51
|
packet.stored = @read_stored
|
|
52
|
-
packet.extra
|
|
52
|
+
if packet.extra and @read_extra
|
|
53
|
+
packet.extra.merge(@read_extra)
|
|
54
|
+
else
|
|
55
|
+
packet.extra = @read_extra
|
|
56
|
+
end
|
|
53
57
|
end
|
|
54
58
|
return packet
|
|
55
59
|
end
|
|
@@ -75,7 +79,7 @@ module OpenC3
|
|
|
75
79
|
return packet
|
|
76
80
|
end
|
|
77
81
|
|
|
78
|
-
def write_data(data)
|
|
82
|
+
def write_data(data, extra = nil)
|
|
79
83
|
data_length = [data.length].pack('N') # UINT32
|
|
80
84
|
data_to_send = ''
|
|
81
85
|
data_to_send << @sync_pattern if @sync_pattern
|
|
@@ -94,7 +98,7 @@ module OpenC3
|
|
|
94
98
|
data_to_send << @write_packet_name
|
|
95
99
|
data_to_send << data_length
|
|
96
100
|
data_to_send << data
|
|
97
|
-
return data_to_send
|
|
101
|
+
return data_to_send, extra
|
|
98
102
|
end
|
|
99
103
|
|
|
100
104
|
protected
|
|
@@ -200,7 +204,7 @@ module OpenC3
|
|
|
200
204
|
return :STOP if packet_data == :STOP
|
|
201
205
|
|
|
202
206
|
@reduction_state = :START
|
|
203
|
-
return packet_data
|
|
207
|
+
return packet_data, @extra
|
|
204
208
|
end
|
|
205
209
|
|
|
206
210
|
raise "Error should never reach end of method #{@reduction_state}"
|
|
@@ -29,6 +29,7 @@ module OpenC3
|
|
|
29
29
|
class Protocol
|
|
30
30
|
attr_accessor :interface
|
|
31
31
|
attr_accessor :allow_empty_data
|
|
32
|
+
attr_accessor :extra
|
|
32
33
|
|
|
33
34
|
# @param allow_empty_data [true/false/nil] Whether or not this protocol will allow an empty string
|
|
34
35
|
# to be passed down to later Protocols (instead of returning :STOP). Can be true, false, or nil, where
|
|
@@ -40,6 +41,7 @@ module OpenC3
|
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
def reset
|
|
44
|
+
@extra = nil
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
def connect_reset
|
|
@@ -51,7 +53,7 @@ module OpenC3
|
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
# Ensure we have some data in case this is the only protocol
|
|
54
|
-
def read_data(data)
|
|
56
|
+
def read_data(data, extra = nil)
|
|
55
57
|
if data.length <= 0
|
|
56
58
|
if @allow_empty_data.nil?
|
|
57
59
|
if @interface and @interface.read_protocols[-1] == self
|
|
@@ -63,7 +65,7 @@ module OpenC3
|
|
|
63
65
|
return :STOP
|
|
64
66
|
end
|
|
65
67
|
end
|
|
66
|
-
data
|
|
68
|
+
return data, extra
|
|
67
69
|
end
|
|
68
70
|
|
|
69
71
|
def read_packet(packet)
|
|
@@ -74,12 +76,12 @@ module OpenC3
|
|
|
74
76
|
return packet
|
|
75
77
|
end
|
|
76
78
|
|
|
77
|
-
def write_data(data)
|
|
78
|
-
return data
|
|
79
|
+
def write_data(data, extra = nil)
|
|
80
|
+
return data, extra
|
|
79
81
|
end
|
|
80
82
|
|
|
81
|
-
def post_write_interface(packet, data)
|
|
82
|
-
return packet, data
|
|
83
|
+
def post_write_interface(packet, data, extra = nil)
|
|
84
|
+
return packet, data, extra
|
|
83
85
|
end
|
|
84
86
|
|
|
85
87
|
def protocol_cmd(cmd_name, *cmd_args)
|
|
@@ -55,7 +55,7 @@ module OpenC3
|
|
|
55
55
|
allow_empty_data = nil)
|
|
56
56
|
|
|
57
57
|
@start_char = ConfigParser.handle_nil(start_char)
|
|
58
|
-
@start_char = [Integer(
|
|
58
|
+
@start_char = [Integer(start_char)].pack('C') if @start_char
|
|
59
59
|
@end_char = [Integer(end_char)].pack('C')
|
|
60
60
|
@esc_char = [Integer(esc_char)].pack('C')
|
|
61
61
|
@esc_end_char = [Integer(esc_end_char)].pack('C')
|
|
@@ -89,9 +89,9 @@ module OpenC3
|
|
|
89
89
|
)
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
-
def read_data(data)
|
|
93
|
-
data = super(data)
|
|
94
|
-
return data if data.length <= 0 or Symbol === data
|
|
92
|
+
def read_data(data, extra = nil)
|
|
93
|
+
data, extra = super(data, extra)
|
|
94
|
+
return data, extra if data.length <= 0 or Symbol === data
|
|
95
95
|
|
|
96
96
|
if @read_strip_characters
|
|
97
97
|
if @start_char
|
|
@@ -104,10 +104,10 @@ module OpenC3
|
|
|
104
104
|
data = data.gsub(@replace_end, @end_char).gsub(@replace_esc, @esc_char)
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
return data
|
|
107
|
+
return data, extra
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
def write_data(data)
|
|
110
|
+
def write_data(data, extra = nil)
|
|
111
111
|
# Intentionally not calling super()
|
|
112
112
|
|
|
113
113
|
if @write_enable_escaping
|
|
@@ -120,7 +120,7 @@ module OpenC3
|
|
|
120
120
|
|
|
121
121
|
data << @end_char
|
|
122
122
|
|
|
123
|
-
return data
|
|
123
|
+
return data, extra
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
def reduce_to_single_packet
|
|
@@ -140,7 +140,7 @@ module OpenC3
|
|
|
140
140
|
packet_data = @data[0..(@read_termination_characters.length - 1)]
|
|
141
141
|
end
|
|
142
142
|
@data.replace(@data[(index + @read_termination_characters.length)..-1])
|
|
143
|
-
return packet_data
|
|
143
|
+
return packet_data, @extra
|
|
144
144
|
else
|
|
145
145
|
return :STOP
|
|
146
146
|
end
|
|
@@ -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/config/config_parser'
|
|
@@ -108,8 +108,8 @@ module OpenC3
|
|
|
108
108
|
@write_block_queue << nil # Unblock the write block queue
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
def read_data(data)
|
|
112
|
-
return super(data) if data.length <= 0
|
|
111
|
+
def read_data(data, extra = nil)
|
|
112
|
+
return super(data, extra) if data.length <= 0
|
|
113
113
|
|
|
114
114
|
# Drop all data until the initial_read_delay is complete.
|
|
115
115
|
# This gets rid of unused welcome messages,
|
|
@@ -119,7 +119,7 @@ module OpenC3
|
|
|
119
119
|
|
|
120
120
|
@initial_read_delay_needed = false
|
|
121
121
|
end
|
|
122
|
-
super(data)
|
|
122
|
+
return super(data, extra)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
def read_packet(packet)
|
|
@@ -165,7 +165,6 @@ module OpenC3
|
|
|
165
165
|
result_packet.write(response_item_names[i], value)
|
|
166
166
|
rescue => error
|
|
167
167
|
handle_error("#{@interface ? @interface.name : ""}: Could not write value #{value} due to #{error.message}")
|
|
168
|
-
break
|
|
169
168
|
end
|
|
170
169
|
end
|
|
171
170
|
|
|
@@ -230,7 +229,7 @@ module OpenC3
|
|
|
230
229
|
return raw_packet
|
|
231
230
|
end
|
|
232
231
|
|
|
233
|
-
def post_write_interface(packet, data)
|
|
232
|
+
def post_write_interface(packet, data, extra = nil)
|
|
234
233
|
if @response_template && @response_packet
|
|
235
234
|
if @response_timeout
|
|
236
235
|
response_timeout_time = Time.now + @response_timeout
|
|
@@ -253,7 +252,7 @@ module OpenC3
|
|
|
253
252
|
@response_target_name = nil
|
|
254
253
|
@response_packets.clear
|
|
255
254
|
end
|
|
256
|
-
return super(packet, data)
|
|
255
|
+
return super(packet, data, extra)
|
|
257
256
|
end
|
|
258
257
|
|
|
259
258
|
def handle_error(msg)
|