openc3 5.5.2 → 5.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9de820bd93122cc0e11533c3d875e3d6babce9247128f9a63fe3ad6e75b6d196
|
4
|
+
data.tar.gz: 293cf85c989666a805a3dec9125ba35692548c27910a09aff871f3c4c523fe7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26a29caa9cd9a211959587b54c76c389dbb70390d573587972a52938c9a3c8ccfcbd702d52f942b37f89133bf76048018ef569a9dcd6ff1990b9030ba62d9208
|
7
|
+
data.tar.gz: c8dce98075822016cfe3c10624b2e54f174d32b87fda748eb04d43031a89535538d8746f1da0945201f9a8b614499c961bcf3bc61fd03973999dfccae122ceb3
|
data/bin/openc3cli
CHANGED
@@ -79,6 +79,28 @@ def print_usage
|
|
79
79
|
puts ""
|
80
80
|
end
|
81
81
|
|
82
|
+
def check_environment
|
83
|
+
hostname = ENV['OPENC3_API_HOSTNAME'] || (ENV['OPENC3_DEVEL'] ? '127.0.0.1' : 'openc3-cosmos-cmd-tlm-api')
|
84
|
+
begin
|
85
|
+
Resolv.getaddress(hostname)
|
86
|
+
rescue Resolv::ResolvError
|
87
|
+
abort "Unable to resolv api hostname: #{hostname}"
|
88
|
+
end
|
89
|
+
|
90
|
+
if hostname =~ /openc3-cosmos-cmd-tlm-api/
|
91
|
+
$openc3_in_cluster = true
|
92
|
+
else
|
93
|
+
$openc3_in_cluster = false
|
94
|
+
end
|
95
|
+
|
96
|
+
unless $openc3_in_cluster
|
97
|
+
# Make sure the user has all the required environment variables set
|
98
|
+
abort "OPENC3_API_HOSTNAME environment variable is required" unless ENV['OPENC3_API_HOSTNAME']
|
99
|
+
abort "OPENC3_API_PORT environment variable is required" unless ENV['OPENC3_API_PORT']
|
100
|
+
abort "OPENC3_API_PASSWORD environment variable is required" unless ENV['OPENC3_API_PASSWORD']
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
82
104
|
def migrate(args)
|
83
105
|
MIGRATE_PARSER.parse!(args)
|
84
106
|
abort(MIGRATE_PARSER.to_s) if args.length == 0
|
@@ -101,9 +123,7 @@ def migrate(args)
|
|
101
123
|
# NOTE: generate does a chdir to be inside the plugin directory
|
102
124
|
###############################################################
|
103
125
|
plugin = args.shift
|
104
|
-
|
105
|
-
# Delete target contents from the plugin framework (but keep directory)
|
106
|
-
FileUtils.rm_rf Dir.glob("targets/#{target_name}/*")
|
126
|
+
OpenC3::CliGenerator.generate(['plugin', plugin])
|
107
127
|
|
108
128
|
if MIGRATE_OPTIONS.all
|
109
129
|
# Grab all target directories to match the command line input
|
@@ -301,6 +321,29 @@ def update_plugin(plugin_file_path, plugin_name, variables: nil, plugin_txt_line
|
|
301
321
|
end
|
302
322
|
end
|
303
323
|
|
324
|
+
def wait_process_complete(process_name)
|
325
|
+
STDOUT.flush
|
326
|
+
state = 'Running'
|
327
|
+
status = nil
|
328
|
+
while state == 'Running'
|
329
|
+
status = plugin_status(process_name)
|
330
|
+
state = status['state']
|
331
|
+
sleep(5)
|
332
|
+
print '.'
|
333
|
+
STDOUT.flush
|
334
|
+
end
|
335
|
+
puts "\nFinished: #{state}"
|
336
|
+
puts "Output:\n"
|
337
|
+
puts status['output']
|
338
|
+
if state == 'Complete'
|
339
|
+
puts "Success!"
|
340
|
+
exit 0
|
341
|
+
else
|
342
|
+
puts "Failed!"
|
343
|
+
exit 1
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
304
347
|
# Loads a plugin into the OpenC3 system
|
305
348
|
# This code is used from the command line and is the same code that gets called if you
|
306
349
|
# edit/upgrade or install a new plugin from the Admin interface
|
@@ -320,90 +363,142 @@ end
|
|
320
363
|
#
|
321
364
|
def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil, force: false)
|
322
365
|
scope ||= 'DEFAULT'
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
366
|
+
check_environment()
|
367
|
+
if $openc3_in_cluster
|
368
|
+
# In Cluster
|
369
|
+
|
370
|
+
# Only create the scope if it doesn't already exist
|
371
|
+
unless OpenC3::ScopeModel.names.include?(scope)
|
372
|
+
begin
|
373
|
+
puts "Creating scope: #{scope}"
|
374
|
+
scope_model = OpenC3::ScopeModel.new(name: scope, scope: scope)
|
375
|
+
scope_model.create
|
376
|
+
scope_model.deploy(".", {})
|
377
|
+
rescue => err
|
378
|
+
abort("Error creating scope: #{scope}: #{err.formatted}")
|
379
|
+
end
|
332
380
|
end
|
333
|
-
end
|
334
381
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
382
|
+
begin
|
383
|
+
if plugin_hash_file
|
384
|
+
# Admin Create / Edit / or Upgrade Plugin
|
385
|
+
OpenC3::PluginModel.install_phase1(plugin_file_path, scope: scope)
|
386
|
+
plugin_hash = JSON.parse(File.read(plugin_hash_file), :allow_nan => true, :create_additions => true)
|
387
|
+
else
|
388
|
+
# Init or Command Line openc3cli load with no plugin_hash_file
|
389
|
+
file_full_name = File.basename(plugin_file_path, ".gem")
|
390
|
+
file_gem_name = file_full_name.split('-')[0..-2].join('-')
|
391
|
+
found = false
|
392
|
+
plugin_names = OpenC3::PluginModel.names(scope: scope)
|
393
|
+
plugin_names.each do |plugin_name|
|
394
|
+
gem_name = plugin_name.split("__")[0]
|
395
|
+
full_name = File.basename(gem_name, ".gem")
|
396
|
+
gem_name = full_name.split('-')[0..-2].join('-')
|
397
|
+
if file_gem_name == gem_name
|
398
|
+
found = true
|
399
|
+
# Upgrade if version changed else do nothing
|
400
|
+
if file_full_name != full_name
|
401
|
+
update_plugin(plugin_file_path, plugin_name, scope: scope, existing_plugin_name: plugin_name, force: force)
|
402
|
+
else
|
403
|
+
puts "No version change detected for: #{plugin_name}"
|
404
|
+
end
|
357
405
|
end
|
358
406
|
end
|
407
|
+
return if found
|
408
|
+
|
409
|
+
plugin_hash = OpenC3::PluginModel.install_phase1(plugin_file_path, scope: scope)
|
359
410
|
end
|
360
|
-
return if found
|
361
411
|
|
362
|
-
|
363
|
-
|
412
|
+
# Determine if plugin named in plugin_hash exists
|
413
|
+
existing_plugin_hash = OpenC3::PluginModel.get(name: plugin_hash['name'], scope: scope)
|
414
|
+
|
415
|
+
# Existing plugin hash will be present if plugin is being edited or upgraded
|
416
|
+
# However, a missing existing could also be that a plugin was updated in local mode directly from across installations
|
417
|
+
# changing the plugin name without really meaning to create a new instance of the plugin
|
418
|
+
# ie.
|
419
|
+
# User on machine 1 checks in a changed plugin_instance.json with a different name - There is still only one plugin desired and committed
|
420
|
+
# User on machine 2 starts up with the new configuration, OpenC3::PluginModel.get will return nil because the exact name is different
|
421
|
+
# In this case, the plugin should be updated without installing a second instance. analyze_local_mode figures this out.
|
422
|
+
unless existing_plugin_hash
|
423
|
+
existing_plugin_hash = OpenC3::LocalMode.analyze_local_mode(plugin_name: plugin_hash['name'], scope: scope)
|
424
|
+
end
|
364
425
|
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
426
|
+
if existing_plugin_hash
|
427
|
+
# Upgrade or Edit
|
428
|
+
update_plugin(plugin_file_path, plugin_hash['name'], variables: plugin_hash['variables'], scope: scope,
|
429
|
+
plugin_txt_lines: plugin_hash['plugin_txt_lines'], existing_plugin_name: existing_plugin_hash['name'], force: force)
|
430
|
+
else
|
431
|
+
# New Install
|
432
|
+
puts "Loading new plugin: #{plugin_file_path}\n#{plugin_hash}"
|
433
|
+
plugin_hash = OpenC3::PluginModel.install_phase2(plugin_hash, scope: scope)
|
434
|
+
OpenC3::LocalMode.update_local_plugin(plugin_file_path, plugin_hash, scope: scope)
|
435
|
+
end
|
436
|
+
rescue => error
|
437
|
+
abort("Error installing plugin: #{scope}: #{plugin_file_path}\n#{error.message}")
|
377
438
|
end
|
439
|
+
else
|
440
|
+
# Outside Cluster
|
441
|
+
require 'openc3/script'
|
378
442
|
|
379
|
-
if
|
380
|
-
|
381
|
-
update_plugin(plugin_file_path, plugin_hash['name'], variables: plugin_hash['variables'], scope: scope,
|
382
|
-
plugin_txt_lines: plugin_hash['plugin_txt_lines'], existing_plugin_name: existing_plugin_hash['name'], force: force)
|
443
|
+
if plugin_hash_file
|
444
|
+
plugin_hash = JSON.parse(File.read(plugin_hash_file), :allow_nan => true, :create_additions => true)
|
383
445
|
else
|
384
|
-
|
385
|
-
puts "Loading new plugin: #{plugin_file_path}\n#{plugin_hash}"
|
386
|
-
plugin_hash = OpenC3::PluginModel.install_phase2(plugin_hash, scope: scope)
|
387
|
-
OpenC3::LocalMode.update_local_plugin(plugin_file_path, plugin_hash, scope: scope)
|
446
|
+
plugin_hash = plugin_install_phase1(plugin_file_path, scope: scope)
|
388
447
|
end
|
389
|
-
|
390
|
-
|
448
|
+
|
449
|
+
process_name = plugin_install_phase2(plugin_hash, scope: scope)
|
450
|
+
|
451
|
+
print "Installing..."
|
452
|
+
wait_process_complete(process_name)
|
391
453
|
end
|
392
454
|
end
|
393
455
|
|
394
456
|
def unload_plugin(plugin_name, scope:)
|
395
457
|
scope ||= 'DEFAULT'
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
458
|
+
check_environment()
|
459
|
+
if $openc3_in_cluster
|
460
|
+
begin
|
461
|
+
plugin_model = OpenC3::PluginModel.get_model(name: plugin_name, scope: scope)
|
462
|
+
plugin_model.destroy
|
463
|
+
OpenC3::LocalMode.remove_local_plugin(plugin_name, scope: scope)
|
464
|
+
OpenC3::Logger.info("PluginModel destroyed: #{plugin_name}", scope: scope)
|
465
|
+
rescue => err
|
466
|
+
abort("Error uninstalling plugin: #{scope}: #{plugin_name}: #{err.formatted}")
|
467
|
+
end
|
468
|
+
else
|
469
|
+
# Outside Cluster
|
470
|
+
require 'openc3/script'
|
471
|
+
process_name = plugin_uninstall(plugin_name, scope: scope)
|
472
|
+
print "Uninstalling..."
|
473
|
+
wait_process_complete(process_name)
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
def cli_gem_install(gem_filename, scope:)
|
478
|
+
scope ||= 'DEFAULT'
|
479
|
+
check_environment()
|
480
|
+
if $openc3_in_cluster
|
481
|
+
OpenC3::GemModel.install(gem_filename, scope: scope)
|
482
|
+
else
|
483
|
+
# Outside Cluster
|
484
|
+
require 'openc3/script'
|
485
|
+
process_name = gem_install(gem_filename, scope: scope)
|
486
|
+
print "Installing..."
|
487
|
+
wait_process_complete(process_name)
|
402
488
|
end
|
403
489
|
end
|
404
490
|
|
405
|
-
def
|
406
|
-
|
491
|
+
def cli_gem_uninstall(gem_filename, scope:)
|
492
|
+
scope ||= 'DEFAULT'
|
493
|
+
check_environment()
|
494
|
+
if $openc3_in_cluster
|
495
|
+
OpenC3::GemModel.destroy(gem_filename)
|
496
|
+
else
|
497
|
+
# Outside Cluster
|
498
|
+
require 'openc3/script'
|
499
|
+
gem_uninstall(gem_filename, scope: scope)
|
500
|
+
puts "Success!"
|
501
|
+
end
|
407
502
|
end
|
408
503
|
|
409
504
|
def get_redis_keys
|
@@ -510,7 +605,10 @@ if not ARGV[0].nil? # argument(s) given
|
|
510
605
|
unload_plugin(ARGV[1], scope: ARGV[2])
|
511
606
|
|
512
607
|
when 'geminstall'
|
513
|
-
|
608
|
+
cli_gem_install(ARGV[1], scope: ARGV[2])
|
609
|
+
|
610
|
+
when 'gemuninstall'
|
611
|
+
cli_gem_uninstall(ARGV[1], scope: ARGV[2])
|
514
612
|
|
515
613
|
when 'generate'
|
516
614
|
OpenC3::CliGenerator.generate(ARGV[1..-1])
|
@@ -17,7 +17,6 @@ tcpip_client_interface.rb:
|
|
17
17
|
- name: Write Timeout
|
18
18
|
required: true
|
19
19
|
description: Number of seconds to wait before aborting the write.
|
20
|
-
Pass 'nil' to block on write.
|
21
20
|
values: .+
|
22
21
|
- name: Read Timeout
|
23
22
|
required: true
|
@@ -43,7 +42,6 @@ tcpip_server_interface.rb:
|
|
43
42
|
- name: Write Timeout
|
44
43
|
required: true
|
45
44
|
description: Number of seconds to wait before aborting the write.
|
46
|
-
Pass 'nil' to block on write.
|
47
45
|
values: .+
|
48
46
|
- name: Read Timeout
|
49
47
|
required: true
|
@@ -90,9 +88,7 @@ udp_interface.rb:
|
|
90
88
|
values: .+
|
91
89
|
- name: Write Timeout
|
92
90
|
required: false
|
93
|
-
description:
|
94
|
-
Number of seconds to wait before aborting the write. Default is
|
95
|
-
'nil' (block on write).
|
91
|
+
description: Number of seconds to wait before aborting the write
|
96
92
|
values: .+
|
97
93
|
- name: Read Timeout
|
98
94
|
required: false
|
@@ -134,7 +130,6 @@ serial_interface.rb:
|
|
134
130
|
- name: Write Timeout
|
135
131
|
required: true
|
136
132
|
description: Number of seconds to wait before aborting the write.
|
137
|
-
Pass 'nil' to block on write.
|
138
133
|
values: .+
|
139
134
|
- name: Read Timeout
|
140
135
|
required: true
|
@@ -6,6 +6,9 @@ MAP_TARGET:
|
|
6
6
|
required: true
|
7
7
|
description: Target name to map to this interface
|
8
8
|
values: .+
|
9
|
+
example: |
|
10
|
+
INTERFACE DATA_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST
|
11
|
+
MAP_TARGET DATA
|
9
12
|
MAP_CMD_TARGET:
|
10
13
|
summary: Maps a target name to an interface for commands only
|
11
14
|
since: 5.2.0
|
@@ -14,6 +17,9 @@ MAP_CMD_TARGET:
|
|
14
17
|
required: true
|
15
18
|
description: Command target name to map to this interface
|
16
19
|
values: .+
|
20
|
+
example: |
|
21
|
+
INTERFACE CMD_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST
|
22
|
+
MAP_CMD_TARGET DATA # Only DATA commands go on the CMD_INT interface
|
17
23
|
MAP_TLM_TARGET:
|
18
24
|
summary: Maps a target name to an interface for telemetry only
|
19
25
|
since: 5.2.0
|
@@ -22,6 +28,9 @@ MAP_TLM_TARGET:
|
|
22
28
|
required: true
|
23
29
|
description: Telemetry target name to map to this interface
|
24
30
|
values: .+
|
31
|
+
example: |
|
32
|
+
INTERFACE TLM_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST
|
33
|
+
MAP_TLM_TARGET DATA # Only DATA telemetry received on TLM_INT interface
|
25
34
|
DONT_CONNECT:
|
26
35
|
summary: Server will not automatically try to connect to the interface at startup
|
27
36
|
DONT_RECONNECT:
|
@@ -43,14 +52,41 @@ DISABLE_DISCONNECT:
|
|
43
52
|
Use this keyword to prevent the user from disconnecting from the interface.
|
44
53
|
This is typically used in a 'production' environment where you would not want
|
45
54
|
the user to inadvertantly disconnect from a target.
|
46
|
-
DONT_LOG:
|
47
|
-
summary: Disable logging commands and telemetry on this interface
|
48
55
|
LOG_RAW:
|
56
|
+
summary: Deprecated, use LOG_STREAM
|
57
|
+
LOG_STREAM:
|
49
58
|
summary: Log all data on the interface exactly as it is sent and received
|
50
59
|
description:
|
51
|
-
|
60
|
+
LOG_STREAM does not add any OpenC3 headers and thus can not be read by OpenC3 tools.
|
52
61
|
It is primarily useful for low level debugging of an interface. You will have to
|
53
62
|
manually parse these logs yourself using a hex editor or other application.
|
63
|
+
since: 5.5.2
|
64
|
+
parameters:
|
65
|
+
- name: Cycle Time
|
66
|
+
required: false
|
67
|
+
description:
|
68
|
+
Amount of time to wait before cycling the log file. Default is 10 min.
|
69
|
+
If nil refer to Cycle Hour and Cycle Minute.
|
70
|
+
values: .*
|
71
|
+
- name: Cycle Size
|
72
|
+
required: false
|
73
|
+
description: Amount of data to write before cycling the log file. Default is 50MB.
|
74
|
+
values: .*
|
75
|
+
- name: Cycle Hour
|
76
|
+
required: false
|
77
|
+
description:
|
78
|
+
The time at which to cycle the log. Combined with Cycle Minute to cycle
|
79
|
+
the log daily at the specified time. If nil, the log will be cycled hourly at the specified Cycle Minute.
|
80
|
+
Only applies if Cycle Time is nil.
|
81
|
+
values: .*
|
82
|
+
- name: Cycle Minute
|
83
|
+
required: false
|
84
|
+
description: See Cycle Hour.
|
85
|
+
values: .*
|
86
|
+
example: |
|
87
|
+
INTERFACE EXAMPLE example_interface.rb
|
88
|
+
# Override the default log time of 600
|
89
|
+
LOG_STREAM 60
|
54
90
|
PROTOCOL:
|
55
91
|
summary: Protocols modify the interface by processing the data
|
56
92
|
description:
|
@@ -71,6 +107,14 @@ PROTOCOL:
|
|
71
107
|
- name: Protocol specific parameters
|
72
108
|
required: false
|
73
109
|
description: Additional parameters used by the protocol
|
110
|
+
example: |
|
111
|
+
INTERFACE DATA_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil nil
|
112
|
+
MAP_TARGET DATA
|
113
|
+
# Rather than defining the LENGTH protocol on the INTERFACE line we define it here
|
114
|
+
PROTOCOL READ LengthProtocol 0 16 0 1 BIG_ENDIAN 4 0xBA5EBA11
|
115
|
+
INTERFACE DATA_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST
|
116
|
+
MAP_TARGET DATA
|
117
|
+
PROTOCOL READ IgnorePacketProtocol INST IMAGE # Drop all INST IMAGE packets
|
74
118
|
OPTION:
|
75
119
|
summary: Set a parameter on an interface
|
76
120
|
description:
|
@@ -90,6 +134,10 @@ OPTION:
|
|
90
134
|
required: false
|
91
135
|
description: Parameters to pass to the option
|
92
136
|
values: .*
|
137
|
+
example: |
|
138
|
+
INTERFACE SERIAL_INT serial_interface.rb COM1 COM1 115200 NONE 1 10.0 nil
|
139
|
+
OPTION FLOW_CONTROL RTSCTS
|
140
|
+
OPTION DATA_BITS 8
|
93
141
|
SECRET:
|
94
142
|
summary: Define a secret needed by this interface
|
95
143
|
description: Defines a secret for this interface and optionally assigns its value to an option
|
@@ -105,7 +153,7 @@ SECRET:
|
|
105
153
|
required: true
|
106
154
|
description: The name of the secret to retrieve
|
107
155
|
values: .*
|
108
|
-
- name: Environment Variable
|
156
|
+
- name: Environment Variable or File Path
|
109
157
|
required: true
|
110
158
|
description: Environment variable name or file path to store secret
|
111
159
|
values: .*
|
@@ -117,3 +165,6 @@ SECRET:
|
|
117
165
|
required: false
|
118
166
|
description: Name of the secret store for stores with multipart keys
|
119
167
|
values: .*
|
168
|
+
example: |
|
169
|
+
SECRET ENV USERNAME ENV_USERNAME USERNAME
|
170
|
+
SECRET FILE KEY "/tmp/DATA/cert" KEY
|
@@ -1,7 +1,6 @@
|
|
1
1
|
---
|
2
2
|
MICROSERVICE:
|
3
3
|
summary: Defines a new microservice
|
4
|
-
example: MICROSERVICE EXAMPLE example-microservice
|
5
4
|
description: Defines a microservice that the plugin adds to the OpenC3 system. Microservices are background software processes that perform persistent processing.
|
6
5
|
parameters:
|
7
6
|
- name: Microservice Folder Name
|
@@ -12,6 +11,7 @@ MICROSERVICE:
|
|
12
11
|
description: The specific name of this instance of the microservice in the OpenC3 system
|
13
12
|
required: true
|
14
13
|
values: .+
|
14
|
+
example: MICROSERVICE EXAMPLE openc3-example
|
15
15
|
modifiers:
|
16
16
|
ENV:
|
17
17
|
summary: Sets an environment variable in the microservice.
|
@@ -24,6 +24,9 @@ MICROSERVICE:
|
|
24
24
|
required: true
|
25
25
|
description: Environment variable value
|
26
26
|
values: .+
|
27
|
+
example: |
|
28
|
+
MICROSERVICE EXAMPLE openc3-example
|
29
|
+
ENV COMPANY OpenC3
|
27
30
|
WORK_DIR:
|
28
31
|
summary: Set the working directory
|
29
32
|
description: Working directory to run the microservice CMD in. Can be a path relative to the microservice folder in the plugin, or an absolute path in the container the microservice runs in.
|
@@ -32,6 +35,9 @@ MICROSERVICE:
|
|
32
35
|
required: true
|
33
36
|
description: Working directory to run the microservice CMD in. Can be a path relative to the microservice folder in the plugin, or an absolute path in the container the microservice runs in.
|
34
37
|
values: .+
|
38
|
+
example: |
|
39
|
+
MICROSERVICE EXAMPLE openc3-example
|
40
|
+
WORK_DIR .
|
35
41
|
PORT:
|
36
42
|
summary: Open port for the microservice
|
37
43
|
description: Kubernetes needs a Service to be applied to open a port so this is required for Kubernetes support
|
@@ -45,6 +51,9 @@ MICROSERVICE:
|
|
45
51
|
required: false
|
46
52
|
description: Port protocol. Default is TCP.
|
47
53
|
values: .+
|
54
|
+
example: |
|
55
|
+
MICROSERVICE EXAMPLE openc3-example
|
56
|
+
PORT 7272
|
48
57
|
TOPIC:
|
49
58
|
summary: Associate a Redis topic
|
50
59
|
description: Redis topic to associate with this microservice. Standard OpenC3 microservices such as decom_microservice use this information to know what packet streams to subscribe to. The TOPIC keyword can be used as many times as necessary to associate all needed topics.
|
@@ -53,6 +62,12 @@ MICROSERVICE:
|
|
53
62
|
required: true
|
54
63
|
description: Redis Topic to associate with the microservice
|
55
64
|
values: .+
|
65
|
+
example: |
|
66
|
+
MICROSERVICE EXAMPLE openc3-example
|
67
|
+
# Manually assigning topics is an advanced topic and requires
|
68
|
+
# intimate knowledge of the internal COSMOS data structures.
|
69
|
+
TOPIC DEFAULT__openc3_log_messages
|
70
|
+
TOPIC DEFAULT__TELEMETRY__EXAMPLE__STATUS
|
56
71
|
TARGET_NAME:
|
57
72
|
summary: Associate a OpenC3 target
|
58
73
|
description: OpenC3 target to associate with the microservice. For standard OpenC3 microservices such as decom_microservice this causes the target configuration to get loaded into the container for the microservice.
|
@@ -61,6 +76,9 @@ MICROSERVICE:
|
|
61
76
|
required: true
|
62
77
|
description: OpenC3 target to associate with the microservice
|
63
78
|
values: .+
|
79
|
+
example: |
|
80
|
+
MICROSERVICE EXAMPLE openc3-example
|
81
|
+
TARGET_NAME EXAMPLE
|
64
82
|
CMD:
|
65
83
|
summary: Command line to execute to run the microservice.
|
66
84
|
description: Command line to execute to run the microservice.
|
@@ -69,6 +87,9 @@ MICROSERVICE:
|
|
69
87
|
required: true
|
70
88
|
description: One or more arguments to exec to run the microservice.
|
71
89
|
values: .+
|
90
|
+
example: |
|
91
|
+
MICROSERVICE EXAMPLE openc3-example
|
92
|
+
CMD ruby example_target.rb
|
72
93
|
OPTION:
|
73
94
|
summary: Pass an option to the microservice
|
74
95
|
description: Generic key/value(s) options to pass to the microservice. These take the form of KEYWORD/PARAMS like a line in a OpenC3 configuration file. Multiple OPTION keywords can be used to pass multiple options to the microservice.
|
@@ -82,8 +103,8 @@ MICROSERVICE:
|
|
82
103
|
description: One or more values to associate with the option
|
83
104
|
values: .+
|
84
105
|
CONTAINER:
|
85
|
-
summary: Docker Container
|
86
|
-
description: Container to execute and run the microservice in.
|
106
|
+
summary: Docker Container
|
107
|
+
description: Container to execute and run the microservice in. Only used in COSMOS Enterprise Edition.
|
87
108
|
parameters:
|
88
109
|
- name: Args
|
89
110
|
required: false
|
@@ -112,6 +133,9 @@ MICROSERVICE:
|
|
112
133
|
required: false
|
113
134
|
description: Name of the secret store for stores with multipart keys
|
114
135
|
values: .*
|
136
|
+
example: |
|
137
|
+
SECRET ENV USERNAME ENV_USERNAME
|
138
|
+
SECRET FILE KEY "/tmp/DATA/cert"
|
115
139
|
ROUTE_PREFIX:
|
116
140
|
summary: Prefix of route
|
117
141
|
description: Prefix of route to the microservice to expose externally with Traefik
|
@@ -121,3 +145,6 @@ MICROSERVICE:
|
|
121
145
|
required: true
|
122
146
|
description: Route prefix. Must be unique across all scopes. Something like /myprefix
|
123
147
|
values: .*
|
148
|
+
example: |
|
149
|
+
MICROSERVICE CFDP CFDP
|
150
|
+
ROUTE_PREFIX /cfdp
|
data/ext/openc3/ext/crc/crc.c
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
# All changes Copyright 2022, OpenC3, Inc.
|
19
19
|
# All Rights Reserved
|
20
20
|
#
|
21
|
-
# This file may also be used under the terms of a commercial license
|
21
|
+
# This file may also be used under the terms of a commercial license
|
22
22
|
# if purchased from OpenC3, Inc.
|
23
23
|
*/
|
24
24
|
|
@@ -27,6 +27,7 @@
|
|
27
27
|
|
28
28
|
VALUE mOpenC3;
|
29
29
|
VALUE cCrc;
|
30
|
+
VALUE cCrc8;
|
30
31
|
VALUE cCrc16;
|
31
32
|
VALUE cCrc32;
|
32
33
|
VALUE cCrc64;
|
@@ -98,6 +99,83 @@ static unsigned long long bit_reverse_64(unsigned long long value)
|
|
98
99
|
((unsigned long long)BIT_REVERSE_TABLE[(value >> 56) & 0x00000000000000ffULL]);
|
99
100
|
}
|
100
101
|
|
102
|
+
/*
|
103
|
+
* Calculate a 8-bit CRC
|
104
|
+
*/
|
105
|
+
static VALUE crc8_calculate(int argc, VALUE *argv, VALUE self)
|
106
|
+
{
|
107
|
+
volatile VALUE param_data = Qnil;
|
108
|
+
volatile VALUE param_seed = Qnil;
|
109
|
+
unsigned char *data = NULL;
|
110
|
+
unsigned char *table = NULL;
|
111
|
+
int i = 0;
|
112
|
+
long length = 0;
|
113
|
+
unsigned char crc = 0;
|
114
|
+
|
115
|
+
switch (argc)
|
116
|
+
{
|
117
|
+
case 1:
|
118
|
+
Check_Type(argv[0], T_STRING);
|
119
|
+
param_data = argv[0];
|
120
|
+
param_seed = rb_ivar_get(self, id_ivar_seed);
|
121
|
+
break;
|
122
|
+
case 2:
|
123
|
+
Check_Type(argv[0], T_STRING);
|
124
|
+
param_data = argv[0];
|
125
|
+
if (argv[1] == Qnil)
|
126
|
+
{
|
127
|
+
param_seed = rb_ivar_get(self, id_ivar_seed);
|
128
|
+
}
|
129
|
+
else
|
130
|
+
{
|
131
|
+
param_seed = argv[1];
|
132
|
+
}
|
133
|
+
break;
|
134
|
+
default:
|
135
|
+
/* Invalid number of arguments given */
|
136
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
|
137
|
+
break;
|
138
|
+
};
|
139
|
+
|
140
|
+
crc = NUM2UINT(param_seed);
|
141
|
+
data = (unsigned char *)RSTRING_PTR(param_data);
|
142
|
+
length = RSTRING_LEN(param_data);
|
143
|
+
table = (unsigned char *)RSTRING_PTR(rb_ivar_get(self, id_ivar_table));
|
144
|
+
|
145
|
+
if (RTEST(rb_ivar_get(self, id_ivar_reflect)))
|
146
|
+
{
|
147
|
+
for (i = 0; i < length; i++)
|
148
|
+
{
|
149
|
+
crc = (crc << 8) ^ table[(crc) ^ bit_reverse_8(data[i])];
|
150
|
+
}
|
151
|
+
|
152
|
+
if (RTEST(rb_ivar_get(self, id_ivar_xor)))
|
153
|
+
{
|
154
|
+
return UINT2NUM(bit_reverse_8(crc ^ 0xFF));
|
155
|
+
}
|
156
|
+
else
|
157
|
+
{
|
158
|
+
return UINT2NUM(bit_reverse_8(crc));
|
159
|
+
}
|
160
|
+
}
|
161
|
+
else
|
162
|
+
{
|
163
|
+
for (i = 0; i < length; i++)
|
164
|
+
{
|
165
|
+
crc = (crc << 8) ^ table[(crc) ^ data[i]];
|
166
|
+
}
|
167
|
+
|
168
|
+
if (RTEST(rb_ivar_get(self, id_ivar_xor)))
|
169
|
+
{
|
170
|
+
return UINT2NUM(crc ^ 0xFF);
|
171
|
+
}
|
172
|
+
else
|
173
|
+
{
|
174
|
+
return UINT2NUM(crc);
|
175
|
+
}
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
101
179
|
/*
|
102
180
|
* Calculate a 16-bit CRC
|
103
181
|
*/
|
@@ -343,6 +421,9 @@ void Init_crc()
|
|
343
421
|
|
344
422
|
cCrc = rb_define_class_under(mOpenC3, "Crc", rb_cObject);
|
345
423
|
|
424
|
+
cCrc8 = rb_define_class_under(mOpenC3, "Crc8", cCrc);
|
425
|
+
rb_define_method(cCrc8, "calc", crc8_calculate, -1);
|
426
|
+
|
346
427
|
cCrc16 = rb_define_class_under(mOpenC3, "Crc16", cCrc);
|
347
428
|
rb_define_method(cCrc16, "calc", crc16_calculate, -1);
|
348
429
|
|