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.

Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/bin/openc3cli +167 -69
  3. data/data/config/_interfaces.yaml +1 -6
  4. data/data/config/interface_modifiers.yaml +55 -4
  5. data/data/config/microservice.yaml +30 -3
  6. data/ext/openc3/ext/crc/crc.c +82 -1
  7. data/lib/openc3/api/cmd_api.rb +19 -7
  8. data/lib/openc3/api/tlm_api.rb +13 -12
  9. data/lib/openc3/bridge/bridge_config.rb +4 -4
  10. data/lib/openc3/config/config_parser.rb +1 -0
  11. data/lib/openc3/conversions/unix_time_conversion.rb +3 -1
  12. data/lib/openc3/ext/.keep +0 -0
  13. data/lib/openc3/interfaces/interface.rb +54 -26
  14. data/lib/openc3/interfaces/serial_interface.rb +4 -5
  15. data/lib/openc3/interfaces/simulated_target_interface.rb +4 -4
  16. data/lib/openc3/interfaces/stream_interface.rb +2 -2
  17. data/lib/openc3/interfaces/tcpip_client_interface.rb +4 -3
  18. data/lib/openc3/interfaces/tcpip_server_interface.rb +18 -19
  19. data/lib/openc3/interfaces/udp_interface.rb +10 -4
  20. data/lib/openc3/io/json_api.rb +72 -0
  21. data/lib/openc3/io/serial_driver.rb +4 -5
  22. data/lib/openc3/logs/buffered_packet_log_writer.rb +2 -4
  23. data/lib/openc3/logs/log_writer.rb +9 -8
  24. data/lib/openc3/logs/packet_log_reader.rb +8 -1
  25. data/lib/openc3/logs/packet_log_writer.rb +3 -4
  26. data/lib/openc3/logs/stream_log.rb +116 -0
  27. data/lib/openc3/logs/stream_log_pair.rb +70 -0
  28. data/lib/openc3/microservices/cleanup_microservice.rb +1 -1
  29. data/lib/openc3/microservices/decom_microservice.rb +17 -2
  30. data/lib/openc3/microservices/interface_decom_common.rb +42 -0
  31. data/lib/openc3/microservices/interface_microservice.rb +24 -17
  32. data/lib/openc3/microservices/router_microservice.rb +46 -4
  33. data/lib/openc3/migrations/20221202214600_add_target_names.rb +1 -1
  34. data/lib/openc3/migrations/20230319154100_log_stream.rb +40 -0
  35. data/lib/openc3/migrations/20230413101100_remove_log.rb +30 -0
  36. data/lib/openc3/models/gem_model.rb +2 -2
  37. data/lib/openc3/models/interface_model.rb +13 -14
  38. data/lib/openc3/models/metadata_model.rb +1 -1
  39. data/lib/openc3/models/note_model.rb +1 -1
  40. data/lib/openc3/models/plugin_model.rb +3 -2
  41. data/lib/openc3/operators/operator.rb +2 -0
  42. data/lib/openc3/packets/commands.rb +2 -0
  43. data/lib/openc3/packets/packet_config.rb +3 -2
  44. data/lib/openc3/packets/parsers/xtce_converter.rb +2 -1
  45. data/lib/openc3/script/gems.rb +125 -0
  46. data/lib/openc3/script/plugins.rb +186 -0
  47. data/lib/openc3/script/screen.rb +119 -0
  48. data/lib/openc3/script/script.rb +3 -0
  49. data/lib/openc3/script/script_runner.rb +19 -8
  50. data/lib/openc3/script/suite_results.rb +2 -2
  51. data/lib/openc3/script/web_socket_api.rb +5 -1
  52. data/lib/openc3/streams/serial_stream.rb +14 -11
  53. data/lib/openc3/streams/tcpip_client_stream.rb +5 -2
  54. data/lib/openc3/streams/tcpip_socket_stream.rb +37 -71
  55. data/lib/openc3/streams/web_socket_client_stream.rb +5 -3
  56. data/lib/openc3/system/system.rb +2 -0
  57. data/lib/openc3/topics/interface_topic.rb +13 -4
  58. data/lib/openc3/topics/router_topic.rb +6 -6
  59. data/lib/openc3/topics/telemetry_decom_topic.rb +10 -1
  60. data/lib/openc3/utilities/bucket_utilities.rb +12 -5
  61. data/lib/openc3/utilities/cli_generator.rb +56 -4
  62. data/lib/openc3/utilities/crc.rb +42 -7
  63. data/lib/openc3/utilities/process_manager.rb +3 -1
  64. data/lib/openc3/utilities/ruby_lex_utils.rb +265 -504
  65. data/lib/openc3/version.rb +6 -6
  66. data/templates/conversion/conversion.rb +10 -2
  67. data/templates/microservice/microservices/TEMPLATE/microservice.rb +1 -1
  68. data/templates/plugin/Rakefile +8 -1
  69. data/templates/widget/.browserslistrc +16 -0
  70. data/templates/widget/.eslintrc.js +43 -0
  71. data/templates/widget/.nycrc +3 -0
  72. data/templates/widget/.prettierrc.js +5 -0
  73. data/templates/widget/LICENSE.txt +20 -0
  74. data/templates/widget/Rakefile +24 -0
  75. data/templates/widget/babel.config.json +11 -0
  76. data/templates/widget/package.json +35 -0
  77. data/templates/widget/src/Widget.vue +46 -0
  78. data/templates/widget/vue.config.js +25 -0
  79. data/templates/widget/yarn.lock +8938 -0
  80. metadata +23 -4
  81. data/lib/openc3/io/raw_logger.rb +0 -170
  82. data/lib/openc3/io/raw_logger_pair.rb +0 -80
@@ -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
- log_cmd = true
350
- if packet["messages_disabled"]
351
- log_cmd = false
352
- else
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
- log_cmd = false
368
+ log_message = false
357
369
  end
358
370
  end
359
371
  end
360
- if log_cmd
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)
@@ -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
- packet_hash = get_telemetry(target_name, packet_name, scope: scope, token: token)
139
- packet = Packet.from_json(packet_hash)
140
- if item_hash
141
- item_hash.each do |name, value|
142
- packet.write(name.to_s, value, type)
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
- topic = "#{scope}__TELEMETRY__{#{target_name}}__#{packet_name}"
146
- msg_id, msg_hash = Topic.get_newest_message(topic)
147
- if msg_id
148
- packet.received_count = msg_hash['received_count'].to_i + 1
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
- packet.received_count = 1
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} <Raw Logger Class File (optional)> <Raw Logger Parameters (optional)>")
158
- current_interface_or_router.raw_logger_pair = RawLoggerPair.new(current_interface_or_router.name, Dir.pwd, params)
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'
@@ -23,6 +23,7 @@
23
23
  require 'openc3/top_level'
24
24
  require 'openc3/ext/config_parser' if RUBY_ENGINE == 'ruby' and !ENV['OPENC3_NO_EXT']
25
25
  require 'erb'
26
+ require 'fileutils'
26
27
 
27
28
  module OpenC3
28
29
  # Reads OpenC3 style configuration data which consists of keywords followed
@@ -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 2022, OpenC3, Inc.
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/io/raw_logger_pair'
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 [RawLoggerPair] RawLoggerPair instance or nil
75
- attr_accessor :raw_logger_pair
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
- @raw_logger_pair.start if @raw_logger_pair
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
- @raw_logger_pair.stop if @raw_logger_pair
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
- @raw_logger_pair.name = name if @raw_logger_pair
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.raw_logger_pair = self.raw_logger_pair.clone if @raw_logger_pair
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
- other_interface.add_protocol(protocol_class, protocol_args, read_write)
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
- @raw_logger_pair.read_logger.write(data) if @raw_logger_pair
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
- @raw_logger_pair.write_logger.write(data) if @raw_logger_pair
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
- protocols = nil
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
- protocols.each_with_index do |protocol, protocol_index|
514
- result = protocol.protocol_cmd(cmd_name, @cmd_args) if index == protocol_index or index == -1
515
- handled = true if result
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 [Integer] The number of seconds to attempt the write
38
- # before aborting
39
- # @param read_timeout [Integer] The number of seconds to attempt to read
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
- packet = first_pending_packet()
71
- if packet
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 raw_logger_pair=(raw_logger_pair)
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, :READ_WRITE)
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 [Integer] Seconds to wait before aborting writes
33
- # @param read_timeout [Integer] Seconds to wait before aborting reads
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 [RawLoggerPair] RawLoggerPair instance or nil
58
- attr_accessor :raw_logger_pair
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|nil] The number of seconds to wait for the
67
- # write to complete. Pass nil to block until the write is complete.
68
- # @param read_timeout [Float|nil] The number of seconds to wait for the
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
- @raw_logger_pair = nil
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.raw_logger_pair.stop if interface_info.interface.raw_logger_pair
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 @raw_logger_pair
303
+ if @stream_log_pair
305
304
  @write_interface_infos.each do |interface_info|
306
- interface_info.interface.raw_logger_pair.public_send(method) if interface_info.interface.raw_logger_pair
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.raw_logger_pair.public_send(method) if interface_info.interface.raw_logger_pair
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 @raw_logger_pair
398
- interface.raw_logger_pair = @raw_logger_pair.clone
399
- interface.raw_logger_pair.start if @raw_logging_enabled
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.raw_logger_pair.stop if read_interface_info.interface.raw_logger_pair
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.raw_logger_pair.stop if interface_info.interface.raw_logger_pair
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.raw_logger_pair.stop if interface_info.interface.raw_logger_pair
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.raw_logger_pair.stop if interface_info.interface.raw_logger_pair
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.raw_logger_pair.stop if interface_info.interface.raw_logger_pair
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 [Integer] Seconds to wait before aborting writes
40
- # @param read_timeout [Integer] Seconds to wait before aborting reads
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
- @write_timeout = @write_timeout.to_f if @write_timeout
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|nil] Number of seconds to wait for the write to
43
- # complete or nil to block
44
- # @param read_timeout [Float|nil] Number of seconds to wait for the read to
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,