openc3 5.5.2 → 5.6.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.
Potentially problematic release.
This version of openc3 might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/openc3cli +167 -69
- data/data/config/_interfaces.yaml +1 -6
- data/data/config/interface_modifiers.yaml +55 -4
- data/data/config/microservice.yaml +30 -3
- data/ext/openc3/ext/crc/crc.c +82 -1
- data/lib/openc3/api/cmd_api.rb +19 -7
- data/lib/openc3/api/tlm_api.rb +13 -12
- data/lib/openc3/bridge/bridge_config.rb +4 -4
- data/lib/openc3/config/config_parser.rb +1 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +3 -1
- data/lib/openc3/ext/.keep +0 -0
- data/lib/openc3/interfaces/interface.rb +54 -26
- data/lib/openc3/interfaces/serial_interface.rb +4 -5
- data/lib/openc3/interfaces/simulated_target_interface.rb +4 -4
- data/lib/openc3/interfaces/stream_interface.rb +2 -2
- data/lib/openc3/interfaces/tcpip_client_interface.rb +4 -3
- data/lib/openc3/interfaces/tcpip_server_interface.rb +18 -19
- data/lib/openc3/interfaces/udp_interface.rb +10 -4
- data/lib/openc3/io/json_api.rb +72 -0
- data/lib/openc3/io/serial_driver.rb +4 -5
- data/lib/openc3/logs/buffered_packet_log_writer.rb +2 -4
- data/lib/openc3/logs/log_writer.rb +9 -8
- data/lib/openc3/logs/packet_log_reader.rb +8 -1
- data/lib/openc3/logs/packet_log_writer.rb +3 -4
- data/lib/openc3/logs/stream_log.rb +116 -0
- data/lib/openc3/logs/stream_log_pair.rb +70 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +1 -1
- data/lib/openc3/microservices/decom_microservice.rb +17 -2
- data/lib/openc3/microservices/interface_decom_common.rb +42 -0
- data/lib/openc3/microservices/interface_microservice.rb +24 -17
- data/lib/openc3/microservices/router_microservice.rb +46 -4
- data/lib/openc3/migrations/20221202214600_add_target_names.rb +1 -1
- data/lib/openc3/migrations/20230319154100_log_stream.rb +40 -0
- data/lib/openc3/migrations/20230413101100_remove_log.rb +30 -0
- data/lib/openc3/models/gem_model.rb +2 -2
- data/lib/openc3/models/interface_model.rb +13 -14
- data/lib/openc3/models/metadata_model.rb +1 -1
- data/lib/openc3/models/note_model.rb +1 -1
- data/lib/openc3/models/plugin_model.rb +3 -2
- data/lib/openc3/operators/operator.rb +2 -0
- data/lib/openc3/packets/commands.rb +2 -0
- data/lib/openc3/packets/packet_config.rb +3 -2
- data/lib/openc3/packets/parsers/xtce_converter.rb +2 -1
- data/lib/openc3/script/gems.rb +125 -0
- data/lib/openc3/script/plugins.rb +186 -0
- data/lib/openc3/script/screen.rb +119 -0
- data/lib/openc3/script/script.rb +3 -0
- data/lib/openc3/script/script_runner.rb +19 -8
- data/lib/openc3/script/suite_results.rb +2 -2
- data/lib/openc3/script/web_socket_api.rb +5 -1
- data/lib/openc3/streams/serial_stream.rb +14 -11
- data/lib/openc3/streams/tcpip_client_stream.rb +5 -2
- data/lib/openc3/streams/tcpip_socket_stream.rb +37 -71
- data/lib/openc3/streams/web_socket_client_stream.rb +5 -3
- data/lib/openc3/system/system.rb +2 -0
- data/lib/openc3/topics/interface_topic.rb +13 -4
- data/lib/openc3/topics/router_topic.rb +6 -6
- data/lib/openc3/topics/telemetry_decom_topic.rb +10 -1
- data/lib/openc3/utilities/bucket_utilities.rb +12 -5
- data/lib/openc3/utilities/cli_generator.rb +56 -4
- data/lib/openc3/utilities/crc.rb +42 -7
- data/lib/openc3/utilities/process_manager.rb +3 -1
- data/lib/openc3/utilities/ruby_lex_utils.rb +265 -504
- data/lib/openc3/version.rb +6 -6
- data/templates/conversion/conversion.rb +10 -2
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +1 -1
- data/templates/plugin/Rakefile +8 -1
- data/templates/widget/.browserslistrc +16 -0
- data/templates/widget/.eslintrc.js +43 -0
- data/templates/widget/.nycrc +3 -0
- data/templates/widget/.prettierrc.js +5 -0
- data/templates/widget/LICENSE.txt +20 -0
- data/templates/widget/Rakefile +24 -0
- data/templates/widget/babel.config.json +11 -0
- data/templates/widget/package.json +35 -0
- data/templates/widget/src/Widget.vue +46 -0
- data/templates/widget/vue.config.js +25 -0
- data/templates/widget/yarn.lock +8938 -0
- metadata +23 -4
- data/lib/openc3/io/raw_logger.rb +0 -170
- data/lib/openc3/io/raw_logger_pair.rb +0 -80
data/lib/openc3/api/cmd_api.rb
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
|
23
23
|
require 'openc3/models/target_model'
|
24
24
|
require 'openc3/topics/command_topic'
|
25
|
+
require 'openc3/topics/command_decom_topic'
|
25
26
|
require 'openc3/topics/interface_topic'
|
26
27
|
require 'openc3/script/extract'
|
27
28
|
|
@@ -313,9 +314,19 @@ module OpenC3
|
|
313
314
|
# PRIVATE implementation details
|
314
315
|
###########################################################################
|
315
316
|
|
316
|
-
def cmd_implementation(method_name, *args, range_check:, hazardous_check:, raw:, timeout: nil,
|
317
|
+
def cmd_implementation(method_name, *args, range_check:, hazardous_check:, raw:, timeout: nil, log_message: nil,
|
317
318
|
scope: $openc3_scope, token: $openc3_token, **kwargs)
|
318
319
|
extract_string_kwargs_to_args(args, kwargs)
|
320
|
+
unless [nil, true, false].include?(log_message)
|
321
|
+
raise "Invalid log_message parameter: #{log_message}. Must be true or false."
|
322
|
+
end
|
323
|
+
unless timeout.nil?
|
324
|
+
begin
|
325
|
+
Float(timeout)
|
326
|
+
rescue ArgumentError, TypeError
|
327
|
+
raise "Invalid timeout parameter: #{timeout}. Must be numeric."
|
328
|
+
end
|
329
|
+
end
|
319
330
|
|
320
331
|
case args.length
|
321
332
|
when 1
|
@@ -346,18 +357,19 @@ module OpenC3
|
|
346
357
|
'hazardous_check' => hazardous_check.to_s,
|
347
358
|
'raw' => raw.to_s
|
348
359
|
}
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
360
|
+
if log_message.nil? # This means the default was used, no argument was passed
|
361
|
+
log_message = true # Default is true
|
362
|
+
# If the packet has the DISABLE_MESSAGES keyword then no messages by default
|
363
|
+
log_message = false if packet["messages_disabled"]
|
364
|
+
# Check if any of the parameters have DISABLE_MESSAGES
|
353
365
|
cmd_params.each do |key, value|
|
354
366
|
item = packet['items'].find { |item| item['name'] == key.to_s }
|
355
367
|
if item['states'] && item['states'][value] && item['states'][value]["messages_disabled"]
|
356
|
-
|
368
|
+
log_message = false
|
357
369
|
end
|
358
370
|
end
|
359
371
|
end
|
360
|
-
if
|
372
|
+
if log_message
|
361
373
|
Logger.info(build_cmd_output_string(target_name, cmd_name, cmd_params, packet, raw), scope: scope)
|
362
374
|
end
|
363
375
|
CommandTopic.send_command(command, timeout: timeout, scope: scope)
|
data/lib/openc3/api/tlm_api.rb
CHANGED
@@ -24,6 +24,8 @@ require 'openc3/models/target_model'
|
|
24
24
|
require 'openc3/models/cvt_model'
|
25
25
|
require 'openc3/packets/packet'
|
26
26
|
require 'openc3/topics/telemetry_topic'
|
27
|
+
require 'openc3/topics/interface_topic'
|
28
|
+
require 'openc3/topics/telemetry_decom_topic'
|
27
29
|
|
28
30
|
module OpenC3
|
29
31
|
module Api
|
@@ -135,22 +137,21 @@ module OpenC3
|
|
135
137
|
TargetModel.packet(target_name, packet_name, scope: scope)
|
136
138
|
end
|
137
139
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
140
|
+
# See if this target has a tlm interface
|
141
|
+
interface_name = nil
|
142
|
+
InterfaceModel.all(scope: scope).each do |name, interface|
|
143
|
+
if interface['tlm_target_names'].include? target_name
|
144
|
+
interface_name = interface['name']
|
145
|
+
break
|
143
146
|
end
|
144
147
|
end
|
145
|
-
|
146
|
-
|
147
|
-
if
|
148
|
-
|
148
|
+
|
149
|
+
# Use an interface microservice if it exists, other use the decom microservice
|
150
|
+
if interface_name
|
151
|
+
InterfaceTopic.inject_tlm(interface_name, target_name, packet_name, item_hash, type: type, scope: scope)
|
149
152
|
else
|
150
|
-
|
153
|
+
TelemetryDecomTopic.inject_tlm(target_name, packet_name, item_hash, type: type, scope: scope)
|
151
154
|
end
|
152
|
-
packet.received_time = Time.now.sys
|
153
|
-
TelemetryTopic.write_packet(packet, scope: scope)
|
154
155
|
end
|
155
156
|
|
156
157
|
# Override the current value table such that a particular item always
|
@@ -144,7 +144,7 @@ module OpenC3
|
|
144
144
|
current_interface_or_router.config_params = params[1..-1]
|
145
145
|
@interfaces[interface_name] = current_interface_or_router
|
146
146
|
|
147
|
-
when 'RECONNECT_DELAY', 'LOG_RAW', 'OPTION', 'PROTOCOL'
|
147
|
+
when 'RECONNECT_DELAY', 'LOG_STREAM', 'LOG_RAW', 'OPTION', 'PROTOCOL'
|
148
148
|
raise parser.error("No current interface or router for #{keyword}") unless current_interface_or_router
|
149
149
|
|
150
150
|
case keyword
|
@@ -153,9 +153,9 @@ module OpenC3
|
|
153
153
|
parser.verify_num_parameters(1, 1, "#{keyword} <Delay in Seconds>")
|
154
154
|
current_interface_or_router.reconnect_delay = Float(params[0])
|
155
155
|
|
156
|
-
when 'LOG_RAW'
|
157
|
-
parser.verify_num_parameters(0, nil, "#{keyword} <
|
158
|
-
current_interface_or_router.
|
156
|
+
when 'LOG_STREAM', 'LOG_RAW'
|
157
|
+
parser.verify_num_parameters(0, nil, "#{keyword} <Log Stream Class File (optional)> <Log Stream Parameters (optional)>")
|
158
|
+
current_interface_or_router.stream_log_pair = StreamLogPair.new(current_interface_or_router.name, params)
|
159
159
|
current_interface_or_router.start_raw_logging
|
160
160
|
|
161
161
|
when 'OPTION'
|
@@ -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'
|
@@ -35,6 +35,8 @@ module OpenC3
|
|
35
35
|
super()
|
36
36
|
@seconds_item_name = seconds_item_name
|
37
37
|
@microseconds_item_name = microseconds_item_name
|
38
|
+
@converted_type = :RUBY_TIME
|
39
|
+
@converted_bit_size = 0
|
38
40
|
end
|
39
41
|
|
40
42
|
# @param (see Conversion#call)
|
File without changes
|
@@ -14,14 +14,14 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2023, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
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/api/api'
|
24
|
-
require 'openc3/
|
24
|
+
require 'openc3/logs/stream_log_pair'
|
25
25
|
require 'openc3/utilities/secrets'
|
26
26
|
|
27
27
|
module OpenC3
|
@@ -71,8 +71,8 @@ module OpenC3
|
|
71
71
|
# @return [Array] Array of stored packet log writers
|
72
72
|
attr_accessor :stored_packet_log_writer_pairs
|
73
73
|
|
74
|
-
# @return [
|
75
|
-
attr_accessor :
|
74
|
+
# @return [StreamLogPair] StreamLogPair instance or nil
|
75
|
+
attr_accessor :stream_log_pair
|
76
76
|
|
77
77
|
# @return [Array<Routers>] Array of routers that receive packets
|
78
78
|
# read from the interface
|
@@ -153,8 +153,6 @@ module OpenC3
|
|
153
153
|
@disable_disconnect = false
|
154
154
|
@packet_log_writer_pairs = []
|
155
155
|
@stored_packet_log_writer_pairs = []
|
156
|
-
# TODO: How should this get the log directory
|
157
|
-
@raw_logger_pair = RawLoggerPair.new(@name, 'outputs/logs')
|
158
156
|
@routers = []
|
159
157
|
@cmd_routers = []
|
160
158
|
@read_count = 0
|
@@ -375,18 +373,19 @@ module OpenC3
|
|
375
373
|
|
376
374
|
# Start raw logging for this interface
|
377
375
|
def start_raw_logging
|
378
|
-
@
|
376
|
+
@stream_log_pair = StreamLogPair.new(@name) unless @stream_log_pair
|
377
|
+
@stream_log_pair.start
|
379
378
|
end
|
380
379
|
|
381
380
|
# Stop raw logging for this interface
|
382
381
|
def stop_raw_logging
|
383
|
-
@
|
382
|
+
@stream_log_pair.stop if @stream_log_pair
|
384
383
|
end
|
385
384
|
|
386
385
|
# Set the interface name
|
387
386
|
def name=(name)
|
388
387
|
@name = name.to_s.clone
|
389
|
-
@
|
388
|
+
@stream_log_pair.name = name if @stream_log_pair
|
390
389
|
end
|
391
390
|
|
392
391
|
# Copy settings from this interface to another interface. All instance
|
@@ -411,7 +410,7 @@ module OpenC3
|
|
411
410
|
other_interface.write_count = self.write_count
|
412
411
|
other_interface.bytes_read = self.bytes_read
|
413
412
|
other_interface.bytes_written = self.bytes_written
|
414
|
-
other_interface.
|
413
|
+
other_interface.stream_log_pair = self.stream_log_pair.clone if @stream_log_pair
|
415
414
|
# num_clients is per interface so don't copy
|
416
415
|
# read_queue_size is the number of packets in the queue so don't copy
|
417
416
|
# write_queue_size is the number of packets in the queue so don't copy
|
@@ -420,7 +419,9 @@ module OpenC3
|
|
420
419
|
end
|
421
420
|
other_interface.protocol_info = []
|
422
421
|
self.protocol_info.each do |protocol_class, protocol_args, read_write|
|
423
|
-
|
422
|
+
unless read_write == :PARAMS
|
423
|
+
other_interface.add_protocol(protocol_class, protocol_args, read_write)
|
424
|
+
end
|
424
425
|
end
|
425
426
|
end
|
426
427
|
|
@@ -459,7 +460,7 @@ module OpenC3
|
|
459
460
|
@read_raw_data_time = Time.now
|
460
461
|
@read_raw_data = data.clone
|
461
462
|
@bytes_read += data.length
|
462
|
-
@
|
463
|
+
@stream_log_pair.read_log.write(data) if @stream_log_pair
|
463
464
|
end
|
464
465
|
|
465
466
|
# Called to write data to the underlying interface. Subclasses must
|
@@ -472,7 +473,7 @@ module OpenC3
|
|
472
473
|
@written_raw_data_time = Time.now
|
473
474
|
@written_raw_data = data.clone
|
474
475
|
@bytes_written += data.length
|
475
|
-
@
|
476
|
+
@stream_log_pair.write_log.write(data) if @stream_log_pair
|
476
477
|
end
|
477
478
|
|
478
479
|
def add_protocol(protocol_class, protocol_args, read_write)
|
@@ -483,7 +484,7 @@ module OpenC3
|
|
483
484
|
@read_protocols << protocol
|
484
485
|
when :WRITE
|
485
486
|
@write_protocols.unshift(protocol)
|
486
|
-
when :READ_WRITE
|
487
|
+
when :READ_WRITE, :PARAMS
|
487
488
|
@read_protocols << protocol
|
488
489
|
@write_protocols.unshift(protocol)
|
489
490
|
else
|
@@ -500,19 +501,46 @@ module OpenC3
|
|
500
501
|
|
501
502
|
def protocol_cmd(cmd_name, *cmd_args, read_write: :READ_WRITE, index: -1)
|
502
503
|
read_write = read_write.to_s.upcase.intern
|
503
|
-
|
504
|
-
case read_write
|
505
|
-
when :READ, :READ_WRITE
|
506
|
-
protocols = @read_protocols
|
507
|
-
when :WRITE
|
508
|
-
protocols = @write_protocols.reverse # Reverse so ordering matches configuration ordering
|
509
|
-
else
|
510
|
-
raise "Unknown protocol descriptor: #{read_write}. Must be :READ, :WRITE, or :READ_WRITE."
|
511
|
-
end
|
504
|
+
raise "Unknown protocol descriptor: #{read_write}. Must be :READ, :WRITE, or :READ_WRITE." unless [:READ, :WRITE, :READ_WRITE].include?(read_write)
|
512
505
|
handled = false
|
513
|
-
|
514
|
-
|
515
|
-
|
506
|
+
|
507
|
+
if index >= 0 or read_write == :READ_WRITE
|
508
|
+
# Reconstruct full list of protocols in correct order
|
509
|
+
protocols = []
|
510
|
+
read_protocols = @read_protocols
|
511
|
+
write_protocols = @write_protocols.reverse
|
512
|
+
read_index = 0
|
513
|
+
write_index = 0
|
514
|
+
@protocol_info.each do |protocol_class, protocol_args, protocol_read_write|
|
515
|
+
case protocol_read_write
|
516
|
+
when :READ
|
517
|
+
protocols << read_protocols[read_index]
|
518
|
+
read_index += 1
|
519
|
+
when :WRITE
|
520
|
+
protocols << write_protocols[write_index]
|
521
|
+
write_index += 1
|
522
|
+
when :READ_WRITE, :PARAMS
|
523
|
+
protocols << read_protocols[read_index]
|
524
|
+
read_index += 1
|
525
|
+
write_index += 1
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
protocols.each_with_index do |protocol, protocol_index|
|
530
|
+
# If index is given that is all that matters
|
531
|
+
result = protocol.protocol_cmd(cmd_name, *cmd_args) if index == protocol_index or index == -1
|
532
|
+
handled = true if result
|
533
|
+
end
|
534
|
+
elsif read_write == :READ # and index == -1
|
535
|
+
@read_protocols.each do |protocol|
|
536
|
+
result = protocol.protocol_cmd(cmd_name, *cmd_args)
|
537
|
+
handled = true if result
|
538
|
+
end
|
539
|
+
else # read_write == :WRITE and index == -1
|
540
|
+
@write_protocols.each do |protocol|
|
541
|
+
result = protocol.protocol_cmd(cmd_name, *cmd_args)
|
542
|
+
handled = true if result
|
543
|
+
end
|
516
544
|
end
|
517
545
|
return handled
|
518
546
|
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/stream_interface'
|
@@ -34,10 +34,9 @@ module OpenC3
|
|
34
34
|
# @param parity [Symbol] The parity which is normally :NONE.
|
35
35
|
# Must be one of :NONE, :EVEN, or :ODD.
|
36
36
|
# @param stop_bits [Integer] The number of stop bits which is normally 1.
|
37
|
-
# @param write_timeout [
|
38
|
-
#
|
39
|
-
#
|
40
|
-
# data from the serial port before aborting
|
37
|
+
# @param write_timeout [Float] Seconds to wait before aborting writes
|
38
|
+
# @param read_timeout [Float|nil] Seconds to wait before aborting reads.
|
39
|
+
# Pass nil to block until the read is complete.
|
41
40
|
# @param protocol_type [String] Combined with 'Protocol' to resolve
|
42
41
|
# to a OpenC3 protocol class
|
43
42
|
# @param protocol_args [Array] Arguments to pass to the protocol constructor
|
@@ -36,7 +36,6 @@ module OpenC3
|
|
36
36
|
@sim_target_class = OpenC3.require_class sim_target_file
|
37
37
|
@sim_target = nil
|
38
38
|
@write_raw_allowed = false
|
39
|
-
@raw_logger_pair = nil
|
40
39
|
end
|
41
40
|
|
42
41
|
# Initialize the simulated target object and "connect" to the target
|
@@ -67,8 +66,9 @@ module OpenC3
|
|
67
66
|
def read
|
68
67
|
packet = nil
|
69
68
|
if @connected
|
70
|
-
|
71
|
-
|
69
|
+
while true
|
70
|
+
packet = first_pending_packet()
|
71
|
+
break unless packet
|
72
72
|
# Support read_packet (but not read data) in protocols
|
73
73
|
# Generic protocol use is not supported
|
74
74
|
@read_protocols.each do |protocol|
|
@@ -143,7 +143,7 @@ module OpenC3
|
|
143
143
|
end
|
144
144
|
|
145
145
|
# Raise an error because raw logging is not supported for this interface
|
146
|
-
def
|
146
|
+
def stream_log_pair=(stream_log_pair)
|
147
147
|
raise "Raw logging not supported for SimulatedTargetInterface"
|
148
148
|
end
|
149
149
|
|
@@ -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/interface'
|
@@ -35,7 +35,7 @@ module OpenC3
|
|
35
35
|
if @protocol_type
|
36
36
|
protocol_class_name = protocol_type.to_s.capitalize << 'Protocol'
|
37
37
|
klass = OpenC3.require_class(protocol_class_name.class_name_to_filename)
|
38
|
-
add_protocol(klass, protocol_args, :
|
38
|
+
add_protocol(klass, protocol_args, :PARAMS)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -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/stream_interface'
|
@@ -29,8 +29,9 @@ module OpenC3
|
|
29
29
|
# @param hostname [String] Machine to connect to
|
30
30
|
# @param write_port [Integer] Port to write commands to
|
31
31
|
# @param read_port [Integer] Port to read telemetry from
|
32
|
-
# @param write_timeout [
|
33
|
-
# @param read_timeout [
|
32
|
+
# @param write_timeout [Float] Seconds to wait before aborting writes
|
33
|
+
# @param read_timeout [Float|nil] Seconds to wait before aborting reads.
|
34
|
+
# Pass nil to block until the read is complete.
|
34
35
|
# @param protocol_type [String] Name of the protocol to use
|
35
36
|
# with this interface
|
36
37
|
# @param protocol_args [Array<String>] Arguments to pass to the protocol
|
@@ -54,8 +54,8 @@ module OpenC3
|
|
54
54
|
# Callback method to call when a new client connects to the read port.
|
55
55
|
# This method will be called with the Interface as the only argument.
|
56
56
|
attr_accessor :read_connection_callback
|
57
|
-
# @return [
|
58
|
-
attr_accessor :
|
57
|
+
# @return [StreamLogPair] StreamLogPair instance or nil
|
58
|
+
attr_accessor :stream_log_pair
|
59
59
|
# @return [String] The ip address to bind to. Default to ANY (0.0.0.0)
|
60
60
|
attr_accessor :listen_address
|
61
61
|
|
@@ -63,10 +63,9 @@ module OpenC3
|
|
63
63
|
# and expect to receive data from this port.
|
64
64
|
# @param read_port [Integer] The server read port. Clients should connect
|
65
65
|
# and expect to send data to this port.
|
66
|
-
# @param write_timeout [Float
|
67
|
-
#
|
68
|
-
#
|
69
|
-
# read to complete. Pass nil to block until the read is complete.
|
66
|
+
# @param write_timeout [Float] Seconds to wait before aborting writes
|
67
|
+
# @param read_timeout [Float|nil] Seconds to wait before aborting reads.
|
68
|
+
# Pass nil to block until the read is complete.
|
70
69
|
# @param protocol_type [String] The name of the stream to
|
71
70
|
# use for both the read and write ports. This name is combined with
|
72
71
|
# 'Protocol' to result in a OpenC3 Protocol class.
|
@@ -108,7 +107,7 @@ module OpenC3
|
|
108
107
|
@write_raw_condition_variable = ConditionVariable.new if @write_port
|
109
108
|
@write_connection_callback = nil
|
110
109
|
@read_connection_callback = nil
|
111
|
-
@
|
110
|
+
@stream_log_pair = nil
|
112
111
|
@raw_logging_enabled = false
|
113
112
|
@connection_mutex = Mutex.new
|
114
113
|
@listen_address = "0.0.0.0"
|
@@ -294,19 +293,19 @@ module OpenC3
|
|
294
293
|
@connection_mutex.synchronize do
|
295
294
|
interface_infos.each do |interface_info|
|
296
295
|
interface_info.interface.disconnect
|
297
|
-
interface_info.interface.
|
296
|
+
interface_info.interface.stream_log_pair.stop if interface_info.interface.stream_log_pair
|
298
297
|
end
|
299
298
|
interface_infos.clear
|
300
299
|
end
|
301
300
|
end
|
302
301
|
|
303
302
|
def change_raw_logging(method)
|
304
|
-
if @
|
303
|
+
if @stream_log_pair
|
305
304
|
@write_interface_infos.each do |interface_info|
|
306
|
-
interface_info.interface.
|
305
|
+
interface_info.interface.stream_log_pair.public_send(method) if interface_info.interface.stream_log_pair
|
307
306
|
end
|
308
307
|
@read_interface_infos.each do |interface_info|
|
309
|
-
interface_info.interface.
|
308
|
+
interface_info.interface.stream_log_pair.public_send(method) if interface_info.interface.stream_log_pair
|
310
309
|
end
|
311
310
|
end
|
312
311
|
end
|
@@ -394,9 +393,9 @@ module OpenC3
|
|
394
393
|
interface.target_names = @target_names
|
395
394
|
interface.cmd_target_names = @cmd_target_names
|
396
395
|
interface.tlm_target_names = @tlm_target_names
|
397
|
-
if @
|
398
|
-
interface.
|
399
|
-
interface.
|
396
|
+
if @stream_log_pair
|
397
|
+
interface.stream_log_pair = @stream_log_pair.clone
|
398
|
+
interface.stream_log_pair.start if @raw_logging_enabled
|
400
399
|
end
|
401
400
|
@protocol_info.each do |protocol_class, protocol_args, read_write|
|
402
401
|
interface.add_protocol(protocol_class, protocol_args, read_write)
|
@@ -440,7 +439,7 @@ module OpenC3
|
|
440
439
|
if interface_info.interface == read_interface_info.interface
|
441
440
|
index_to_delete = index
|
442
441
|
read_interface_info.interface.disconnect
|
443
|
-
read_interface_info.interface.
|
442
|
+
read_interface_info.interface.stream_log_pair.stop if read_interface_info.interface.stream_log_pair
|
444
443
|
break
|
445
444
|
end
|
446
445
|
index += 1
|
@@ -503,7 +502,7 @@ module OpenC3
|
|
503
502
|
Logger.info "#{@name}: Tcpip server lost write connection to "\
|
504
503
|
"#{interface_info.hostname}(#{interface_info.host_ip}):#{interface_info.port}"
|
505
504
|
interface_info.interface.disconnect
|
506
|
-
interface_info.interface.
|
505
|
+
interface_info.interface.stream_log_pair.stop if interface_info.interface.stream_log_pair
|
507
506
|
end
|
508
507
|
|
509
508
|
def write_thread_hook(packet)
|
@@ -554,13 +553,13 @@ module OpenC3
|
|
554
553
|
# Client has disconnected (or is invalidly sending data on the socket)
|
555
554
|
Logger.info "#{@name}: Tcpip server lost write connection to #{interface_info.hostname}(#{interface_info.host_ip}):#{interface_info.port}"
|
556
555
|
interface_info.interface.disconnect
|
557
|
-
interface_info.interface.
|
556
|
+
interface_info.interface.stream_log_pair.stop if interface_info.interface.stream_log_pair
|
558
557
|
indexes_to_delete.unshift(index) # Put later indexes at front of array
|
559
558
|
rescue Errno::ECONNRESET, Errno::ECONNABORTED, IOError
|
560
559
|
# Client has disconnected
|
561
560
|
Logger.info "#{@name}: Tcpip server lost write connection to #{interface_info.hostname}(#{interface_info.host_ip}):#{interface_info.port}"
|
562
561
|
interface_info.interface.disconnect
|
563
|
-
interface_info.interface.
|
562
|
+
interface_info.interface.stream_log_pair.stop if interface_info.interface.stream_log_pair
|
564
563
|
indexes_to_delete.unshift(index) # Put later indexes at front of array
|
565
564
|
rescue Errno::EWOULDBLOCK
|
566
565
|
# Client is still cleanly connected as far as we can tell without writing to the socket
|
@@ -607,7 +606,7 @@ module OpenC3
|
|
607
606
|
if need_disconnect
|
608
607
|
Logger.info "#{@name}: Tcpip server lost write connection to #{interface_info.hostname}(#{interface_info.host_ip}):#{interface_info.port}"
|
609
608
|
interface_info.interface.disconnect
|
610
|
-
interface_info.interface.
|
609
|
+
interface_info.interface.stream_log_pair.stop if interface_info.interface.stream_log_pair
|
611
610
|
indexes_to_delete.unshift(index) # Put later indexes at front of array
|
612
611
|
end
|
613
612
|
index += 1
|
@@ -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/interface'
|
@@ -36,8 +36,9 @@ module OpenC3
|
|
36
36
|
# configure the outgoing multicast address.
|
37
37
|
# @param ttl [Integer] Time To Live value. The number of intermediate
|
38
38
|
# routers allowed before dropping the packet.
|
39
|
-
# @param write_timeout [
|
40
|
-
# @param read_timeout [
|
39
|
+
# @param write_timeout [Float] Seconds to wait before aborting writes
|
40
|
+
# @param read_timeout [Float|nil] Seconds to wait before aborting reads.
|
41
|
+
# Pass nil to block until the read is complete.
|
41
42
|
# @param bind_address [String] Address to bind UDP ports to
|
42
43
|
def initialize(
|
43
44
|
hostname,
|
@@ -70,7 +71,12 @@ module OpenC3
|
|
70
71
|
@ttl = ttl.to_i
|
71
72
|
@ttl = 1 if @ttl < 1
|
72
73
|
@write_timeout = ConfigParser.handle_nil(write_timeout)
|
73
|
-
|
74
|
+
if @write_timeout
|
75
|
+
@write_timeout = @write_timeout.to_f
|
76
|
+
else
|
77
|
+
Logger.instance.warn("Warning: To avoid interface lock, write_timeout can not be nil. Setting to 10 seconds.")
|
78
|
+
@write_timeout = 10.0
|
79
|
+
end
|
74
80
|
@read_timeout = ConfigParser.handle_nil(read_timeout)
|
75
81
|
@read_timeout = @read_timeout.to_f if @read_timeout
|
76
82
|
@bind_address = ConfigParser.handle_nil(bind_address)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2023 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
|
+
require 'openc3/io/json_api_object'
|
20
|
+
require 'openc3/utilities/authentication'
|
21
|
+
|
22
|
+
module OpenC3
|
23
|
+
class JsonApi
|
24
|
+
# Create a JsonApiObject connection to the API server
|
25
|
+
def initialize(microservice_name:, prefix:, schema: 'http', hostname: nil, port:, timeout: 5.0, url: nil, scope: $openc3_scope)
|
26
|
+
url = _generate_url(microservice_name: microservice_name, prefix: prefix, schema: schema, hostname: hostname, port: port, scope: scope) unless url
|
27
|
+
@json_api = JsonApiObject.new(
|
28
|
+
url: url,
|
29
|
+
timeout: timeout,
|
30
|
+
authentication: _generate_auth()
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def shutdown
|
35
|
+
@json_api.shutdown
|
36
|
+
end
|
37
|
+
|
38
|
+
# private
|
39
|
+
|
40
|
+
# pull openc3-cosmos-script-runner-api url from environment variables
|
41
|
+
def _generate_url(microservice_name:, prefix:, schema: 'http', hostname: nil, port:, scope: $openc3_scope)
|
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
|
49
|
+
return "#{schema}://#{hostname}:#{port.to_i}#{prefix}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# generate the auth object
|
54
|
+
def _generate_auth
|
55
|
+
if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
|
56
|
+
if ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
|
57
|
+
return OpenC3Authentication.new()
|
58
|
+
else
|
59
|
+
return nil
|
60
|
+
end
|
61
|
+
else
|
62
|
+
return OpenC3KeycloakAuthentication.new(ENV['OPENC3_KEYCLOAK_URL'])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def _request(*method_params, **kw_params)
|
67
|
+
kw_params[:scope] = $openc3_scope unless kw_params[:scope]
|
68
|
+
kw_params[:json] => true unless kw_params[:json]
|
69
|
+
@json_api.request(*method_params, **kw_params)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
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/core_ext/kernel'
|
@@ -39,10 +39,9 @@ module OpenC3
|
|
39
39
|
# @param baud_rate [Integer] Serial port baud rate
|
40
40
|
# @param parity [Symbol] Must be one of :EVEN, :ODD or :NONE
|
41
41
|
# @param stop_bits [Integer] Number of stop bits
|
42
|
-
# @param write_timeout [Float
|
43
|
-
#
|
44
|
-
#
|
45
|
-
# complete or nil to block
|
42
|
+
# @param write_timeout [Float] Seconds to wait before aborting writes
|
43
|
+
# @param read_timeout [Float|nil] Seconds to wait before aborting reads.
|
44
|
+
# Pass nil to block until the read is complete.
|
46
45
|
# @param flow_control [Symbol] Currently supported :NONE and :RTSCTS (default :NONE)
|
47
46
|
# @param data_bits [Integer] Number of data bits (default 8)
|
48
47
|
def initialize(port_name,
|