openc3 5.1.1 → 5.2.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 +48 -9
- data/data/config/interface_modifiers.yaml +14 -0
- data/data/config/parameter_modifiers.yaml +5 -3
- data/data/config/screen.yaml +12 -8
- data/data/config/target.yaml +33 -0
- data/ext/openc3/ext/config_parser/config_parser.c +66 -63
- data/ext/openc3/ext/packet/packet.c +1 -4
- data/lib/openc3/api/README.md +5 -0
- data/lib/openc3/api/api.rb +3 -1
- data/lib/openc3/api/cmd_api.rb +43 -112
- data/lib/openc3/api/interface_api.rb +3 -3
- data/lib/openc3/api/offline_access_api.rb +78 -0
- data/lib/openc3/api/settings_api.rb +3 -1
- data/lib/openc3/api/stash_api.rb +63 -0
- data/lib/openc3/api/target_api.rb +4 -5
- data/lib/openc3/config/config_parser.rb +47 -47
- data/lib/openc3/interfaces/interface.rb +11 -1
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +30 -16
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +8 -2
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +2 -2
- data/lib/openc3/interfaces/protocols/override_protocol.rb +2 -2
- data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -1
- data/lib/openc3/io/json_api_object.rb +30 -9
- data/lib/openc3/io/json_drb.rb +6 -1
- data/lib/openc3/io/json_drb_object.rb +18 -9
- data/lib/openc3/io/json_rpc.rb +5 -3
- data/lib/openc3/logs/buffered_packet_log_writer.rb +1 -1
- data/lib/openc3/logs/log_writer.rb +8 -2
- data/lib/openc3/microservices/cleanup_microservice.rb +3 -3
- data/lib/openc3/microservices/decom_microservice.rb +8 -8
- data/lib/openc3/microservices/interface_microservice.rb +86 -71
- data/lib/openc3/microservices/log_microservice.rb +5 -3
- data/lib/openc3/microservices/microservice.rb +18 -14
- data/lib/openc3/microservices/multi_microservice.rb +62 -0
- data/lib/openc3/microservices/periodic_microservice.rb +58 -0
- data/lib/openc3/microservices/reaction_microservice.rb +61 -47
- data/lib/openc3/microservices/reducer_microservice.rb +64 -40
- data/lib/openc3/microservices/router_microservice.rb +4 -4
- data/lib/openc3/microservices/text_log_microservice.rb +2 -2
- data/lib/openc3/microservices/timeline_microservice.rb +44 -30
- data/lib/openc3/microservices/trigger_group_microservice.rb +39 -36
- data/lib/openc3/migrations/20221202214600_add_target_names.rb +30 -0
- data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +65 -0
- data/lib/openc3/models/cvt_model.rb +1 -1
- data/lib/openc3/models/gem_model.rb +24 -20
- data/lib/openc3/models/interface_model.rb +69 -35
- data/lib/openc3/models/metadata_model.rb +1 -1
- data/lib/openc3/models/microservice_model.rb +7 -24
- data/lib/openc3/models/migration_model.rb +52 -0
- data/lib/openc3/models/model.rb +2 -7
- data/lib/openc3/models/note_model.rb +1 -1
- data/lib/openc3/models/offline_access_model.rb +55 -0
- data/lib/openc3/models/plugin_model.rb +12 -3
- data/lib/openc3/models/reaction_model.rb +6 -2
- data/lib/openc3/models/scope_model.rb +89 -13
- data/lib/openc3/models/settings_model.rb +1 -1
- data/lib/openc3/models/stash_model.rb +53 -0
- data/lib/openc3/models/target_model.rb +301 -130
- data/lib/openc3/models/tool_model.rb +1 -12
- data/lib/openc3/models/widget_model.rb +1 -6
- data/lib/openc3/operators/microservice_operator.rb +45 -6
- data/lib/openc3/operators/operator.rb +27 -5
- data/lib/openc3/packets/commands.rb +1 -25
- data/lib/openc3/packets/limits.rb +0 -75
- data/lib/openc3/packets/packet.rb +0 -28
- data/lib/openc3/packets/packet_item.rb +23 -0
- data/lib/openc3/packets/packet_item_limits.rb +2 -2
- data/lib/openc3/packets/parsers/state_parser.rb +10 -6
- data/lib/openc3/packets/telemetry.rb +1 -45
- data/lib/openc3/script/commands.rb +41 -71
- data/lib/openc3/script/extract.rb +15 -1
- data/lib/openc3/script/{calendar.rb → metadata.rb} +42 -17
- data/lib/openc3/script/script.rb +13 -5
- data/lib/openc3/script/storage.rb +3 -1
- data/lib/openc3/system/system.rb +19 -17
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +4 -4
- data/lib/openc3/top_level.rb +3 -3
- data/lib/openc3/topics/command_decom_topic.rb +2 -2
- data/lib/openc3/topics/command_topic.rb +7 -6
- data/lib/openc3/topics/interface_topic.rb +2 -2
- data/lib/openc3/topics/router_topic.rb +1 -1
- data/lib/openc3/topics/telemetry_topic.rb +2 -1
- data/lib/openc3/utilities/authentication.rb +35 -14
- data/lib/openc3/utilities/aws_bucket.rb +4 -3
- data/lib/openc3/utilities/bucket.rb +4 -2
- data/lib/openc3/utilities/bucket_file_cache.rb +3 -8
- data/lib/openc3/utilities/bucket_utilities.rb +77 -15
- data/lib/openc3/utilities/local_mode.rb +12 -9
- data/lib/openc3/utilities/logger.rb +17 -9
- data/lib/openc3/utilities/message_log.rb +6 -5
- data/lib/openc3/utilities/migration.rb +22 -0
- data/lib/openc3/utilities/store_autoload.rb +7 -5
- data/lib/openc3/utilities/target_file.rb +9 -7
- data/lib/openc3/version.rb +6 -6
- data/lib/openc3.rb +2 -1
- metadata +14 -3
data/lib/openc3/api/cmd_api.rb
CHANGED
@@ -17,12 +17,13 @@
|
|
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/models/target_model'
|
24
24
|
require 'openc3/topics/command_topic'
|
25
25
|
require 'openc3/topics/interface_topic'
|
26
|
+
require 'openc3/script/extract'
|
26
27
|
|
27
28
|
module OpenC3
|
28
29
|
module Api
|
@@ -49,134 +50,48 @@ module OpenC3
|
|
49
50
|
'get_cmd_cnts',
|
50
51
|
])
|
51
52
|
|
52
|
-
#
|
53
|
+
# The following methods send a command packet to a target. The 'raw' version of the equivalent
|
54
|
+
# command methods do not perform command parameter conversions.
|
53
55
|
#
|
54
56
|
# Accepts two different calling styles:
|
55
57
|
# cmd("TGT CMD with PARAM1 val, PARAM2 val")
|
56
58
|
# cmd('TGT','CMD','PARAM1'=>val,'PARAM2'=>val)
|
57
59
|
#
|
58
60
|
# Favor the first syntax where possible as it is more succinct.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
def
|
63
|
-
args
|
64
|
-
cmd_implementation(true, true, false, 'cmd', *args, scope: scope, token: token)
|
61
|
+
def cmd(*args, **kwargs)
|
62
|
+
cmd_implementation('cmd', *args, range_check: true, hazardous_check: true, raw: false, **kwargs)
|
63
|
+
end
|
64
|
+
def cmd_raw(*args, **kwargs)
|
65
|
+
cmd_implementation('cmd_raw', *args, range_check: true, hazardous_check: true, raw: true, **kwargs)
|
65
66
|
end
|
66
67
|
|
67
68
|
# Send a command packet to a target without performing any value range
|
68
69
|
# checks on the parameters. Useful for testing to allow sending command
|
69
70
|
# parameters outside the allowable range as defined in the configuration.
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
# Favor the first syntax where possible as it is more succinct.
|
76
|
-
#
|
77
|
-
# @param (see #cmd)
|
78
|
-
# @return (see #cmd)
|
79
|
-
def cmd_no_range_check(*args, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
80
|
-
args << kwargs unless kwargs.empty?
|
81
|
-
cmd_implementation(false, true, false, 'cmd_no_range_check', *args, scope: scope, token: token)
|
71
|
+
def cmd_no_range_check(*args, **kwargs)
|
72
|
+
cmd_implementation('cmd_no_range_check', *args, range_check: false, hazardous_check: true, raw: false, **kwargs)
|
73
|
+
end
|
74
|
+
def cmd_raw_no_range_check(*args, **kwargs)
|
75
|
+
cmd_implementation('cmd_raw_no_range_check', *args, range_check: false, hazardous_check: true, raw: true, **kwargs)
|
82
76
|
end
|
83
77
|
|
84
78
|
# Send a command packet to a target without performing any hazardous checks
|
85
79
|
# both on the command itself and its parameters. Useful in scripts to
|
86
80
|
# prevent popping up warnings to the user.
|
87
|
-
|
88
|
-
|
89
|
-
# cmd_no_hazardous_check("TGT CMD with PARAM1 val, PARAM2 val")
|
90
|
-
# cmd_no_hazardous_check('TGT','CMD','PARAM1'=>val,'PARAM2'=>val)
|
91
|
-
#
|
92
|
-
# Favor the first syntax where possible as it is more succinct.
|
93
|
-
#
|
94
|
-
# @param (see #cmd)
|
95
|
-
# @return (see #cmd)
|
96
|
-
def cmd_no_hazardous_check(*args, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
97
|
-
args << kwargs unless kwargs.empty?
|
98
|
-
cmd_implementation(true, false, false, 'cmd_no_hazardous_check', *args, scope: scope, token: token)
|
81
|
+
def cmd_no_hazardous_check(*args, **kwargs)
|
82
|
+
cmd_implementation('cmd_no_hazardous_check', *args, range_check: true, hazardous_check: false, raw: false, **kwargs)
|
99
83
|
end
|
100
|
-
|
101
|
-
|
102
|
-
# checks or hazardous checks both on the command itself and its parameters.
|
103
|
-
#
|
104
|
-
# Accepts two different calling styles:
|
105
|
-
# cmd_no_checks("TGT CMD with PARAM1 val, PARAM2 val")
|
106
|
-
# cmd_no_checks('TGT','CMD','PARAM1'=>val,'PARAM2'=>val)
|
107
|
-
#
|
108
|
-
# Favor the first syntax where possible as it is more succinct.
|
109
|
-
#
|
110
|
-
# @param (see #cmd)
|
111
|
-
# @return (see #cmd)
|
112
|
-
def cmd_no_checks(*args, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
113
|
-
args << kwargs unless kwargs.empty?
|
114
|
-
cmd_implementation(false, false, false, 'cmd_no_checks', *args, scope: scope, token: token)
|
115
|
-
end
|
116
|
-
|
117
|
-
# Send a command packet to a target without running conversions.
|
118
|
-
#
|
119
|
-
# Accepts two different calling styles:
|
120
|
-
# cmd_raw("TGT CMD with PARAM1 val, PARAM2 val")
|
121
|
-
# cmd_raw('TGT','CMD','PARAM1'=>val,'PARAM2'=>val)
|
122
|
-
#
|
123
|
-
# Favor the first syntax where possible as it is more succinct.
|
124
|
-
#
|
125
|
-
# @param args [String|Array<String>] See the description for calling style
|
126
|
-
# @return [Array<String, String, Hash>] target_name, command_name, parameters
|
127
|
-
def cmd_raw(*args, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
128
|
-
args << kwargs unless kwargs.empty?
|
129
|
-
cmd_implementation(true, true, true, 'cmd_raw', *args, scope: scope, token: token)
|
84
|
+
def cmd_raw_no_hazardous_check(*args, **kwargs)
|
85
|
+
cmd_implementation('cmd_raw_no_hazardous_check', *args, range_check: true, hazardous_check: false, raw: true, **kwargs)
|
130
86
|
end
|
131
87
|
|
132
88
|
# Send a command packet to a target without performing any value range
|
133
|
-
# checks on the parameters or running conversions. Useful for testing to allow sending command
|
134
|
-
# parameters outside the allowable range as defined in the configuration.
|
135
|
-
#
|
136
|
-
# Accepts two different calling styles:
|
137
|
-
# cmd_raw_no_range_check("TGT CMD with PARAM1 val, PARAM2 val")
|
138
|
-
# cmd_raw_no_range_check('TGT','CMD','PARAM1'=>val,'PARAM2'=>val)
|
139
|
-
#
|
140
|
-
# Favor the first syntax where possible as it is more succinct.
|
141
|
-
#
|
142
|
-
# @param (see #cmd)
|
143
|
-
# @return (see #cmd)
|
144
|
-
def cmd_raw_no_range_check(*args, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
145
|
-
args << kwargs unless kwargs.empty?
|
146
|
-
cmd_implementation(false, true, true, 'cmd_raw_no_range_check', *args, scope: scope, token: token)
|
147
|
-
end
|
148
|
-
|
149
|
-
# Send a command packet to a target without running conversions or performing any hazardous checks
|
150
|
-
# both on the command itself and its parameters. Useful in scripts to
|
151
|
-
# prevent popping up warnings to the user.
|
152
|
-
#
|
153
|
-
# Accepts two different calling styles:
|
154
|
-
# cmd_raw_no_hazardous_check("TGT CMD with PARAM1 val, PARAM2 val")
|
155
|
-
# cmd_raw_no_hazardous_check('TGT','CMD','PARAM1'=>val,'PARAM2'=>val)
|
156
|
-
#
|
157
|
-
# Favor the first syntax where possible as it is more succinct.
|
158
|
-
#
|
159
|
-
# @param (see #cmd)
|
160
|
-
# @return (see #cmd)
|
161
|
-
def cmd_raw_no_hazardous_check(*args, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
162
|
-
args << kwargs unless kwargs.empty?
|
163
|
-
cmd_implementation(true, false, true, 'cmd_raw_no_hazardous_check', *args, scope: scope, token: token)
|
164
|
-
end
|
165
|
-
|
166
|
-
# Send a command packet to a target without running conversions or performing any value range
|
167
89
|
# checks or hazardous checks both on the command itself and its parameters.
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
# Favor the first syntax where possible as it is more succinct.
|
174
|
-
#
|
175
|
-
# @param (see #cmd)
|
176
|
-
# @return (see #cmd)
|
177
|
-
def cmd_raw_no_checks(*args, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
178
|
-
args << kwargs unless kwargs.empty?
|
179
|
-
cmd_implementation(false, false, true, 'cmd_raw_no_checks', *args, scope: scope, token: token)
|
90
|
+
def cmd_no_checks(*args, **kwargs)
|
91
|
+
cmd_implementation('cmd_no_checks', *args, range_check: false, hazardous_check: false, raw: false, **kwargs)
|
92
|
+
end
|
93
|
+
def cmd_raw_no_checks(*args, **kwargs)
|
94
|
+
cmd_implementation('cmd_raw_no_checks', *args, range_check: false, hazardous_check: false, raw: true, **kwargs)
|
180
95
|
end
|
181
96
|
|
182
97
|
# Send a raw binary string to the specified interface.
|
@@ -258,7 +173,7 @@ module OpenC3
|
|
258
173
|
# @param args [String|Array<String>] See the description for calling style
|
259
174
|
# @return [Boolean] Whether the command is hazardous
|
260
175
|
def get_cmd_hazardous(*args, scope: $openc3_scope, token: $openc3_token, **kwargs)
|
261
|
-
args
|
176
|
+
extract_string_kwargs_to_args(args, kwargs)
|
262
177
|
case args.length
|
263
178
|
when 1
|
264
179
|
target_name, command_name, params = extract_fields_from_cmd_text(args[0], scope: scope)
|
@@ -375,7 +290,10 @@ module OpenC3
|
|
375
290
|
# PRIVATE implementation details
|
376
291
|
###########################################################################
|
377
292
|
|
378
|
-
def cmd_implementation(
|
293
|
+
def cmd_implementation(method_name, *args, range_check:, hazardous_check:, raw:, timeout: nil,
|
294
|
+
scope: $openc3_scope, token: $openc3_token, **kwargs)
|
295
|
+
extract_string_kwargs_to_args(args, kwargs)
|
296
|
+
|
379
297
|
case args.length
|
380
298
|
when 1
|
381
299
|
target_name, cmd_name, cmd_params = extract_fields_from_cmd_text(args[0], scope: scope)
|
@@ -402,8 +320,21 @@ module OpenC3
|
|
402
320
|
'hazardous_check' => hazardous_check.to_s,
|
403
321
|
'raw' => raw.to_s
|
404
322
|
}
|
405
|
-
|
406
|
-
|
323
|
+
log_cmd = true
|
324
|
+
if packet["messages_disabled"]
|
325
|
+
log_cmd = false
|
326
|
+
else
|
327
|
+
cmd_params.each do |key, value|
|
328
|
+
item = packet['items'].find { |item| item['name'] == key.to_s }
|
329
|
+
if item['states'] && item['states'][value] && item['states'][value]["messages_disabled"]
|
330
|
+
log_cmd = false
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
if log_cmd
|
335
|
+
Logger.info(build_cmd_output_string(target_name, cmd_name, cmd_params, packet, raw), scope: scope)
|
336
|
+
end
|
337
|
+
CommandTopic.send_command(command, timeout: timeout, scope: scope)
|
407
338
|
end
|
408
339
|
|
409
340
|
def build_cmd_output_string(target_name, cmd_name, cmd_params, packet, raw)
|
@@ -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/models/interface_model'
|
@@ -125,7 +125,7 @@ module OpenC3
|
|
125
125
|
#
|
126
126
|
# @param target_name [String/Array] The name of the target(s)
|
127
127
|
# @param interface_name (see #connect_interface)
|
128
|
-
def map_target_to_interface(target_name, interface_name, scope: $openc3_scope, token: $openc3_token)
|
128
|
+
def map_target_to_interface(target_name, interface_name, cmd_only: false, tlm_only: false, unmap_old: true, scope: $openc3_scope, token: $openc3_token)
|
129
129
|
authorize(permission: 'system_set', interface_name: interface_name, scope: scope, token: token)
|
130
130
|
new_interface = InterfaceModel.get_model(name: interface_name, scope: scope)
|
131
131
|
if Array === target_name
|
@@ -134,7 +134,7 @@ module OpenC3
|
|
134
134
|
target_names = [target_name]
|
135
135
|
end
|
136
136
|
target_names.each do |name|
|
137
|
-
new_interface.map_target(name)
|
137
|
+
new_interface.map_target(name, cmd_only: cmd_only, tlm_only: tlm_only, unmap_old: unmap_old)
|
138
138
|
Logger.info("Target #{name} mapped to Interface #{interface_name}", scope: scope)
|
139
139
|
end
|
140
140
|
nil
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2022 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/models/offline_access_model'
|
20
|
+
require 'openc3/utilities/authentication'
|
21
|
+
|
22
|
+
module OpenC3
|
23
|
+
module Api
|
24
|
+
WHITELIST ||= []
|
25
|
+
WHITELIST.concat([
|
26
|
+
'offline_access_needed',
|
27
|
+
'set_offline_access'
|
28
|
+
])
|
29
|
+
|
30
|
+
def offline_access_needed(scope: $openc3_scope, token: $openc3_token)
|
31
|
+
authorize(permission: 'system', scope: scope, token: token)
|
32
|
+
begin
|
33
|
+
authorize(permission: 'script_run', scope: scope, token: token)
|
34
|
+
rescue
|
35
|
+
# Not needed if can't run scripts
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
info = user_info(token)
|
39
|
+
if info['roles'].to_s.include?("offline_access")
|
40
|
+
username = info['username']
|
41
|
+
if username and username != ''
|
42
|
+
model = OfflineAccessModel.get_model(name: username, scope: scope)
|
43
|
+
if model and model.offline_access_token
|
44
|
+
auth = OpenC3KeycloakAuthentication.new(ENV['OPENC3_KEYCLOAK_URL'])
|
45
|
+
valid_token = auth.get_token_from_refresh_token(model.offline_access_token)
|
46
|
+
if valid_token
|
47
|
+
return false
|
48
|
+
else
|
49
|
+
model.offline_access_token = nil
|
50
|
+
model.update
|
51
|
+
return true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
return true
|
55
|
+
else
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
else
|
59
|
+
return false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_offline_access(offline_access_token, scope: $openc3_scope, token: $openc3_token)
|
64
|
+
authorize(permission: 'script_run', scope: scope, token: token)
|
65
|
+
info = user_info(token)
|
66
|
+
username = info['username']
|
67
|
+
raise "Invalid username" if not username or username == ''
|
68
|
+
model = OfflineAccessModel.get_model(name: username, scope: scope)
|
69
|
+
if model
|
70
|
+
model.offline_access_token = offline_access_token
|
71
|
+
model.update
|
72
|
+
else
|
73
|
+
model = OfflineAccessModel.new(name: username, offline_access_token: offline_access_token, scope: scope)
|
74
|
+
model.create
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -17,9 +17,11 @@
|
|
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
|
+
require 'openc3/models/settings_model'
|
24
|
+
|
23
25
|
module OpenC3
|
24
26
|
module Api
|
25
27
|
WHITELIST ||= []
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2022 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/models/stash_model'
|
20
|
+
|
21
|
+
module OpenC3
|
22
|
+
module Api
|
23
|
+
WHITELIST ||= []
|
24
|
+
WHITELIST.concat([
|
25
|
+
'stash_set',
|
26
|
+
'stash_get',
|
27
|
+
'stash_all',
|
28
|
+
'stash_keys',
|
29
|
+
'stash_delete'
|
30
|
+
])
|
31
|
+
|
32
|
+
def stash_set(key, value, scope: $openc3_scope, token: $openc3_token)
|
33
|
+
authorize(permission: 'script_run', scope: scope, token: token)
|
34
|
+
StashModel.set( {name: key, value: JSON.generate(value.as_json(:allow_nan => true)) }, scope: scope)
|
35
|
+
end
|
36
|
+
|
37
|
+
def stash_get(key, scope: $openc3_scope, token: $openc3_token)
|
38
|
+
authorize(permission: 'script_view', scope: scope, token: token)
|
39
|
+
result = StashModel.get(name: key, scope: scope)
|
40
|
+
if result
|
41
|
+
JSON.parse(result['value'], :allow_nan => true, :create_additions => true)
|
42
|
+
else
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def stash_all(scope: $openc3_scope, token: $openc3_token)
|
48
|
+
authorize(permission: 'script_view', scope: scope, token: token)
|
49
|
+
StashModel.all(scope: scope).transform_values { |hash| JSON.parse(hash["value"], :allow_nan => true, :create_additions => true) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def stash_keys(scope: $openc3_scope, token: $openc3_token)
|
53
|
+
authorize(permission: 'script_view', scope: scope, token: token)
|
54
|
+
StashModel.names(scope: scope)
|
55
|
+
end
|
56
|
+
|
57
|
+
def stash_delete(key, scope: $openc3_scope, token: $openc3_token)
|
58
|
+
authorize(permission: 'script_run', scope: scope, token: token)
|
59
|
+
model = StashModel.get_model(name: key, scope: scope)
|
60
|
+
model.destroy if model
|
61
|
+
end
|
62
|
+
end
|
63
|
+
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/models/target_model'
|
@@ -66,14 +66,13 @@ module OpenC3
|
|
66
66
|
packets.each do |packet|
|
67
67
|
tlm_cnt += Topic.get_cnt("#{scope}__TELEMETRY__{#{target_name}}__#{packet['packet_name']}")
|
68
68
|
end
|
69
|
-
|
69
|
+
interface_names = []
|
70
70
|
InterfaceModel.all(scope: scope).each do |name, interface|
|
71
71
|
if interface['target_names'].include? target_name
|
72
|
-
|
73
|
-
break
|
72
|
+
interface_names << interface['name']
|
74
73
|
end
|
75
74
|
end
|
76
|
-
info << [target_name,
|
75
|
+
info << [target_name, interface_names.join(","), cmd_cnt, tlm_cnt]
|
77
76
|
end
|
78
77
|
info
|
79
78
|
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/top_level'
|
@@ -449,12 +449,11 @@ module OpenC3
|
|
449
449
|
if RUBY_ENGINE != 'ruby' or ENV['OPENC3_NO_EXT']
|
450
450
|
# Iterates over each line of the io object and yields the keyword and parameters
|
451
451
|
def parse_loop(io, yield_non_keyword_lines, remove_quotes, size, rx)
|
452
|
-
|
453
|
-
|
452
|
+
string_concat = false
|
454
453
|
@line_number = 0
|
455
454
|
@keyword = nil
|
456
455
|
@parameters = []
|
457
|
-
@line =
|
456
|
+
@line = ''
|
458
457
|
|
459
458
|
while true
|
460
459
|
@line_number += 1
|
@@ -470,37 +469,57 @@ module OpenC3
|
|
470
469
|
end
|
471
470
|
|
472
471
|
line.strip!
|
473
|
-
|
474
|
-
|
472
|
+
# Ensure the line length is not 0
|
473
|
+
next if line.length == 0
|
475
474
|
|
476
|
-
if
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
@line = line
|
481
|
-
if (first_item.length == 0) || (first_item[0] == '#')
|
482
|
-
@keyword = nil
|
483
|
-
else
|
484
|
-
@keyword = first_item.upcase
|
475
|
+
if string_concat
|
476
|
+
# Skip comment lines after a string concatenation
|
477
|
+
if (line[0] == '#')
|
478
|
+
next
|
485
479
|
end
|
486
|
-
|
480
|
+
# Remove the opening quote if we're continuing the line
|
481
|
+
line = line[1..-1]
|
487
482
|
end
|
488
483
|
|
489
|
-
#
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
484
|
+
# Check for string continuation
|
485
|
+
case line[-1]
|
486
|
+
when '+', '\\' # String concatenation
|
487
|
+
newline = line[-1] == '+'
|
488
|
+
# Trim off the concat character plus any spaces, e.g. "line" \
|
489
|
+
trim = line[0..-2].strip()
|
490
|
+
# Now trim off the last quote so it will flow into the next line
|
491
|
+
@line += trim[0..-2]
|
492
|
+
@line += "\n" if newline
|
493
|
+
string_concat = true
|
494
|
+
next
|
495
|
+
when '&' # Line continuation
|
496
|
+
@line += line[0..-2]
|
494
497
|
next
|
498
|
+
else
|
499
|
+
@line += line
|
500
|
+
end
|
501
|
+
string_concat = false
|
502
|
+
|
503
|
+
data = @line.scan(rx)
|
504
|
+
first_item = ''
|
505
|
+
if data.length > 0
|
506
|
+
first_item += data[0]
|
495
507
|
end
|
496
508
|
|
497
|
-
if
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
509
|
+
if (first_item.length == 0) || (first_item[0] == '#')
|
510
|
+
@keyword = nil
|
511
|
+
else
|
512
|
+
@keyword = first_item.upcase
|
513
|
+
end
|
514
|
+
@parameters = []
|
515
|
+
|
516
|
+
# Ignore lines without keywords: comments and blank lines
|
517
|
+
if @keyword.nil?
|
518
|
+
if yield_non_keyword_lines
|
519
|
+
yield(@keyword, @parameters)
|
502
520
|
end
|
503
|
-
|
521
|
+
@line = ''
|
522
|
+
next
|
504
523
|
end
|
505
524
|
|
506
525
|
length = data.length
|
@@ -518,13 +537,6 @@ module OpenC3
|
|
518
537
|
end
|
519
538
|
end
|
520
539
|
|
521
|
-
# If the string is simply '&' and its the last string then its a line continuation so break the loop
|
522
|
-
if (string.length == 1) && (string[0] == '&') && (index == (length - 1))
|
523
|
-
line_continuation = true
|
524
|
-
next
|
525
|
-
end
|
526
|
-
|
527
|
-
line_continuation = false
|
528
540
|
if remove_quotes
|
529
541
|
@parameters << string.remove_quotes
|
530
542
|
else
|
@@ -533,20 +545,8 @@ module OpenC3
|
|
533
545
|
end
|
534
546
|
end
|
535
547
|
|
536
|
-
# If we detected a line continuation while going through all the
|
537
|
-
# strings on the line then we strip off the continuation character and
|
538
|
-
# return to the top of the loop to continue processing the line.
|
539
|
-
if line_continuation
|
540
|
-
# Strip the continuation character
|
541
|
-
if @line.length >= 1
|
542
|
-
@line = @line[0..-2]
|
543
|
-
else
|
544
|
-
@line = ""
|
545
|
-
end
|
546
|
-
next
|
547
|
-
end
|
548
|
-
|
549
548
|
yield(@keyword, @parameters)
|
549
|
+
@line = ''
|
550
550
|
end
|
551
551
|
|
552
552
|
@@progress_callback.call(1.0) if @@progress_callback
|
@@ -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/api/api'
|
@@ -38,6 +38,12 @@ module OpenC3
|
|
38
38
|
# @return [Array<String>] Array of target names associated with this interface
|
39
39
|
attr_accessor :target_names
|
40
40
|
|
41
|
+
# @return [Array<String>] Array of cmd target names associated with this interface
|
42
|
+
attr_accessor :cmd_target_names
|
43
|
+
|
44
|
+
# @return [Array<String>] Array of tlm target names associated with this interface
|
45
|
+
attr_accessor :tlm_target_names
|
46
|
+
|
41
47
|
# @return [Boolean] Flag indicating if the interface should be connected
|
42
48
|
# to on startup
|
43
49
|
attr_accessor :connect_on_startup
|
@@ -133,6 +139,8 @@ module OpenC3
|
|
133
139
|
@name = self.class.to_s.split("::")[-1] # Remove namespacing if present
|
134
140
|
@state = 'DISCONNECTED'
|
135
141
|
@target_names = []
|
142
|
+
@cmd_target_names = []
|
143
|
+
@tlm_target_names = []
|
136
144
|
@connect_on_startup = true
|
137
145
|
@auto_reconnect = true
|
138
146
|
@reconnect_delay = 5.0
|
@@ -381,6 +389,8 @@ module OpenC3
|
|
381
389
|
def copy_to(other_interface)
|
382
390
|
other_interface.name = self.name.clone
|
383
391
|
other_interface.target_names = self.target_names.clone
|
392
|
+
other_interface.cmd_target_names = self.cmd_target_names.clone
|
393
|
+
other_interface.tlm_target_names = self.tlm_target_names.clone
|
384
394
|
other_interface.connect_on_startup = self.connect_on_startup
|
385
395
|
other_interface.auto_reconnect = self.auto_reconnect
|
386
396
|
other_interface.reconnect_delay = self.reconnect_delay
|
@@ -17,7 +17,7 @@
|
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
|
-
# This file may also be used under the terms of a commercial license
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
require 'openc3/config/config_parser'
|
@@ -55,30 +55,44 @@ module OpenC3
|
|
55
55
|
# creating a Packet. It can discard a set number of bytes at the beginning
|
56
56
|
# before creating the Packet.
|
57
57
|
#
|
58
|
+
# Note: On the first call to this from any interface read(), data will contain a blank
|
59
|
+
# string. Blank string is an opportunity for protocols to return any queued up packets.
|
60
|
+
# If they have no queued up packets, they should pass the blank string down to chained
|
61
|
+
# protocols giving them the same opportunity.
|
62
|
+
#
|
58
63
|
# @return [String|nil] Data for a packet consisting of the bytes read
|
59
64
|
def read_data(data)
|
60
65
|
@data << data
|
61
66
|
|
62
|
-
|
63
|
-
|
67
|
+
while true
|
68
|
+
control = handle_sync_pattern()
|
69
|
+
return control if control and data.length > 0 # Only return here if not blank string test
|
64
70
|
|
65
|
-
|
66
|
-
|
71
|
+
# Reduce the data to a single packet
|
72
|
+
packet_data = reduce_to_single_packet()
|
73
|
+
if packet_data == :RESYNC
|
74
|
+
@sync_state = :SEARCHING
|
75
|
+
next if data.length > 0 # Only immediately resync if not blank string test
|
76
|
+
end
|
67
77
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
78
|
+
# Potentially allow blank string to be sent to other protocols if no packet is ready in this one
|
79
|
+
if Symbol === packet_data
|
80
|
+
if (data.length <= 0) and packet_data != :DISCONNECT
|
81
|
+
# On blank string test, return blank string (unless we had a packet or need disconnect)
|
82
|
+
# The base class handles the special case of returning STOP if on the last protocol in the
|
83
|
+
# chain
|
84
|
+
return super(data)
|
85
|
+
else
|
86
|
+
return packet_data # Return any control code if not on blank string test
|
87
|
+
end
|
74
88
|
end
|
75
|
-
end
|
76
89
|
|
77
|
-
|
90
|
+
@sync_state = :SEARCHING
|
78
91
|
|
79
|
-
|
80
|
-
|
81
|
-
|
92
|
+
# Discard leading bytes if necessary
|
93
|
+
packet_data.replace(packet_data[@discard_leading_bytes..-1]) if @discard_leading_bytes > 0
|
94
|
+
return packet_data
|
95
|
+
end
|
82
96
|
end
|
83
97
|
|
84
98
|
# Called to perform modifications on a command packet before it is sent
|