cosmos 5.0.4 → 5.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/cosmos +182 -41
- data/data/config/plugins.yaml +10 -0
- data/ext/cosmos/ext/cosmos_io/cosmos_io.c +14 -14
- data/ext/cosmos/ext/packet/packet.c +3 -3
- data/ext/cosmos/ext/structure/structure.c +31 -31
- data/lib/cosmos/api/tlm_api.rb +4 -4
- data/lib/cosmos/logs/log_writer.rb +76 -27
- data/lib/cosmos/microservices/interface_microservice.rb +0 -15
- data/lib/cosmos/models/gem_model.rb +7 -1
- data/lib/cosmos/models/interface_model.rb +16 -7
- data/lib/cosmos/models/metadata_model.rb +39 -15
- data/lib/cosmos/models/microservice_model.rb +6 -3
- data/lib/cosmos/models/model.rb +7 -0
- data/lib/cosmos/models/note_model.rb +4 -6
- data/lib/cosmos/models/plugin_model.rb +107 -47
- data/lib/cosmos/models/scope_model.rb +2 -0
- data/lib/cosmos/models/sorted_model.rb +3 -1
- data/lib/cosmos/models/target_model.rb +24 -15
- data/lib/cosmos/models/tool_model.rb +8 -8
- data/lib/cosmos/models/widget_model.rb +10 -10
- data/lib/cosmos/packets/packet.rb +1 -1
- data/lib/cosmos/packets/structure.rb +30 -33
- data/lib/cosmos/script/calendar.rb +13 -2
- data/lib/cosmos/tools/table_manager/table_config.rb +16 -1
- data/lib/cosmos/tools/table_manager/table_manager_core.rb +213 -309
- data/lib/cosmos/topics/config_topic.rb +68 -0
- data/lib/cosmos/version.rb +5 -5
- metadata +7 -8
- data/bin/xtce_converter +0 -92
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 520339a0daade42a51611f9e17fe6e5a2c1343d9bab3ad6b36dbb03f11f55f28
|
4
|
+
data.tar.gz: 59a4d41cc6ef453ea1f375c5e9671aa0b14b390da42d8413bd080ab7bdb18ff4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 700274a130767236a08e76ce223a09fa0229e659153c8a5f50896447796d3ca0e4487423704ece2d655511a642c6dfed0a8fc9482f8ee7ef9681f1726c23a2ce
|
7
|
+
data.tar.gz: 20773c2fd54d95674f66252edbd51faee8107cca83c05bace69a4607fd5563dc543d10f670513b4fb2df25d6ca6c18d0e58923f517e66f7f186fe7bc0e1eecbb
|
data/bin/cosmos
CHANGED
@@ -24,6 +24,7 @@ require 'cosmos'
|
|
24
24
|
require 'cosmos/utilities/s3'
|
25
25
|
require 'cosmos/models/scope_model'
|
26
26
|
require 'cosmos/models/plugin_model'
|
27
|
+
require 'cosmos/packets/packet_config'
|
27
28
|
require 'cosmos/bridge/bridge'
|
28
29
|
require 'ostruct'
|
29
30
|
require 'optparse'
|
@@ -32,6 +33,7 @@ require 'fileutils'
|
|
32
33
|
require 'find'
|
33
34
|
require 'json'
|
34
35
|
require 'redis'
|
36
|
+
require 'psych'
|
35
37
|
require 'erb'
|
36
38
|
|
37
39
|
$redis_url = "redis://#{ENV['COSMOS_REDIS_HOSTNAME']}:#{ENV['COSMOS_REDIS_PORT']}"
|
@@ -40,25 +42,27 @@ $redis_url = "redis://#{ENV['COSMOS_REDIS_HOSTNAME']}:#{ENV['COSMOS_REDIS_PORT']
|
|
40
42
|
MIGRATE_OPTIONS = OpenStruct.new
|
41
43
|
MIGRATE_OPTIONS.all = false
|
42
44
|
MIGRATE_PARSER = OptionParser.new do |op|
|
43
|
-
op.banner = "cosmos migrate PLUGIN [TGT1...]
|
44
|
-
op.on("-a", "--all", "Move all COSMOS 4 targets into a single COSMOS 5 plugin") do
|
45
|
+
op.banner = "cosmos migrate PLUGIN [TGT1...] # Create a COSMOS 5 plugin from existing COSMOS 4 targets"
|
46
|
+
op.on("-a", "--all", " Move all COSMOS 4 targets into a single COSMOS 5 plugin") do
|
45
47
|
MIGRATE_OPTIONS.all = true
|
46
48
|
end
|
47
49
|
end
|
50
|
+
ERROR_CODE = 67 # ASCII 'C' for COSMOS
|
48
51
|
|
49
52
|
# Prints the usage text for the cosmos executable
|
50
53
|
def print_usage
|
51
54
|
puts "Usage:"
|
52
55
|
puts " cosmos help # Displays this information"
|
53
56
|
puts " cosmos rake # Runs rake in the local directory"
|
54
|
-
puts " cosmos
|
57
|
+
puts " cosmos validate /PATH/FILENAME.gem SCOPE variables.txt # Validate a COSMOS plugin gem file"
|
58
|
+
puts " cosmos load /PATH/FILENAME.gem SCOPE variables.txt # Loads a COSMOS plugin gem file"
|
55
59
|
puts " cosmos generate plugin PLUGIN_NAME # Generate a COSMOS plugin"
|
56
60
|
puts " #{MIGRATE_PARSER}"
|
57
61
|
puts " cosmos bridge CONFIG_FILENAME # Run COSMOS host bridge"
|
58
62
|
puts " cosmos bridgesetup CONFIG_FILENAME # Create a default config file"
|
59
63
|
puts " cosmos geminstall GEMFILENAME # Install loaded gem to /gems"
|
60
64
|
puts " cosmos rubysloc # Counts Ruby SLOC recursively. Run with --help for more info."
|
61
|
-
|
65
|
+
puts " cosmos xtce_converter # Convert to and from the XTCE format. Run with --help for more info."
|
62
66
|
puts " cosmos cstol_converter # Converts CSTOL files (.prc) to COSMOS. Run with --help for more info."
|
63
67
|
puts ""
|
64
68
|
end
|
@@ -185,6 +189,76 @@ def migrate(args)
|
|
185
189
|
puts "Plugin complete: #{File.expand_path('.')}" # Remember we're inside the plugin dir
|
186
190
|
end
|
187
191
|
|
192
|
+
def xtce_converter(args)
|
193
|
+
options = {}
|
194
|
+
option_parser = OptionParser.new do |option_parser|
|
195
|
+
option_parser.banner = "Usage: xtce_converter [options] --import input_xtce_filename --output output_dir\n"+
|
196
|
+
" xtce_converter [options] --plugin /PATH/FILENAME.gem --output output_dir --variables variables.txt"
|
197
|
+
option_parser.separator("")
|
198
|
+
option_parser.on("-h", "--help", "Show this message") do
|
199
|
+
puts option_parser
|
200
|
+
exit
|
201
|
+
end
|
202
|
+
option_parser.on("-i VALUE", "--import VALUE", "Import the specified .xtce file") do |arg|
|
203
|
+
options[:import] = arg
|
204
|
+
end
|
205
|
+
option_parser.on("-o", "--output DIRECTORY", "Create files in the directory") do |arg|
|
206
|
+
options[:output] = arg
|
207
|
+
end
|
208
|
+
option_parser.on("-p", "--plugin PLUGIN", "Export .xtce file(s) from the plugin") do |arg|
|
209
|
+
options[:plugin] = arg
|
210
|
+
end
|
211
|
+
option_parser.on("-v", "--variables", "Optional variables file to pass to the plugin") do |arg|
|
212
|
+
options[:variables] = arg
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
begin
|
217
|
+
option_parser.parse!(args)
|
218
|
+
rescue => err
|
219
|
+
abort(option_parser.to_s)
|
220
|
+
end
|
221
|
+
|
222
|
+
if options[:import] && options[:plugin]
|
223
|
+
puts "xtce_converter options --import and --plugin are mutually exclusive"
|
224
|
+
abort(option_parser.to_s)
|
225
|
+
end
|
226
|
+
|
227
|
+
ENV['COSMOS_NO_STORE'] = '1' # it can be anything
|
228
|
+
Cosmos::Logger.stdout = false
|
229
|
+
Cosmos::Logger.level = Cosmos::Logger::DEBUG
|
230
|
+
|
231
|
+
if options[:import] && options[:output]
|
232
|
+
packet_config = Cosmos::PacketConfig.new
|
233
|
+
puts "Processing #{options[:import]}..."
|
234
|
+
packet_config.process_file(options[:import], nil)
|
235
|
+
puts "Writing COSMOS config files to #{options[:output]}/"
|
236
|
+
packet_config.to_config(options[:output])
|
237
|
+
exit(0)
|
238
|
+
elsif options[:plugin] && options[:output]
|
239
|
+
begin
|
240
|
+
variables = nil
|
241
|
+
variables = JSON.parse(File.read(options[:variables])) if options[:variables]
|
242
|
+
puts "Installing #{File.basename(options[:plugin])}"
|
243
|
+
plugin_hash = Cosmos::PluginModel.install_phase1(options[:plugin], variables, scope: 'DEFAULT', validate_only: true)
|
244
|
+
plugin_hash['variables']['xtce_output'] = options[:output]
|
245
|
+
Cosmos::PluginModel.install_phase2(plugin_hash['name'], plugin_hash['variables'], scope: 'DEFAULT', validate_only: true,
|
246
|
+
gem_file_path: options[:plugin])
|
247
|
+
result = 0 # bash and Windows consider 0 success
|
248
|
+
rescue => e
|
249
|
+
puts "Error: #{e.message}"
|
250
|
+
result = ERROR_CODE
|
251
|
+
ensure
|
252
|
+
name = Psych.safe_load(`gem spec #{options[:plugin]} name`).to_s
|
253
|
+
version = Psych.safe_load(`gem spec #{options[:plugin]} version`, permitted_classes: [Gem::Version]).to_s
|
254
|
+
Gem::Uninstaller.new(name, {:version => version, :force => true}).uninstall
|
255
|
+
exit(result)
|
256
|
+
end
|
257
|
+
else
|
258
|
+
abort(option_parser.to_s)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
188
262
|
# A helper method to make the zip writing recursion work
|
189
263
|
def write_zip_entries(base_dir, entries, zip_path, io)
|
190
264
|
io.add(zip_path, base_dir) # Add the directory whether it has entries or not
|
@@ -212,7 +286,66 @@ def put_into_archive(disk_file_path, io, zip_file_path)
|
|
212
286
|
end
|
213
287
|
end
|
214
288
|
|
215
|
-
def
|
289
|
+
def validate_plugin(plugin_file_path, scope:, variables_file: nil)
|
290
|
+
ENV['COSMOS_NO_STORE'] = '1' # it can be anything
|
291
|
+
Cosmos::Logger.stdout = false
|
292
|
+
Cosmos::Logger.level = Cosmos::Logger::DEBUG
|
293
|
+
scope ||= 'DEFAULT'
|
294
|
+
variables = nil
|
295
|
+
variables = JSON.parse(File.read(variables_file)) if variables_file
|
296
|
+
puts "Installing #{File.basename(plugin_file_path)}"
|
297
|
+
plugin_hash = Cosmos::PluginModel.install_phase1(plugin_file_path, variables, scope: scope, validate_only: true)
|
298
|
+
Cosmos::PluginModel.install_phase2(plugin_hash['name'], plugin_hash['variables'], scope: scope, validate_only: true,
|
299
|
+
gem_file_path: plugin_file_path)
|
300
|
+
puts "Successfully validated #{File.basename(plugin_file_path)}"
|
301
|
+
result = 0 # bash and Windows consider 0 success
|
302
|
+
rescue => e
|
303
|
+
puts "Error: #{e.message}"
|
304
|
+
result = ERROR_CODE
|
305
|
+
ensure
|
306
|
+
name = Psych.safe_load(`gem spec #{plugin_file_path} name`).to_s
|
307
|
+
version = Psych.safe_load(`gem spec #{plugin_file_path} version`, permitted_classes: [Gem::Version]).to_s
|
308
|
+
Gem::Uninstaller.new(name, {:version => version, :force => true}).uninstall
|
309
|
+
exit(result)
|
310
|
+
end
|
311
|
+
|
312
|
+
def update_plugin(plugin_file_path, plugin_name, variables: nil, plugin_txt_lines: nil, scope:)
|
313
|
+
new_gem = File.basename(plugin_file_path)
|
314
|
+
old_gem = plugin_name.split("__")[0]
|
315
|
+
puts "Updating existing plugin: #{plugin_name} with #{File.basename(plugin_file_path)}"
|
316
|
+
plugin_model = Cosmos::PluginModel.get_model(name: plugin_name, scope: scope)
|
317
|
+
begin
|
318
|
+
# Only update if something has changed
|
319
|
+
if (new_gem != old_gem) or (variables != plugin_model.variables) or (plugin_txt_lines != plugin_model.plugin_txt_lines)
|
320
|
+
variables = plugin_model.variables unless variables
|
321
|
+
plugin_model.destroy
|
322
|
+
plugin_hash = Cosmos::PluginModel.install_phase1(plugin_file_path, existing_variables: variables, existing_plugin_txt_lines: plugin_txt_lines, process_existing: true, scope: scope)
|
323
|
+
Cosmos::PluginModel.install_phase2(plugin_hash, scope: scope)
|
324
|
+
else
|
325
|
+
puts "No changes detected - Exiting without change"
|
326
|
+
end
|
327
|
+
rescue => error
|
328
|
+
puts error.formatted
|
329
|
+
plugin_model.restore if plugin_model.destroyed?
|
330
|
+
raise error
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# Loads a plugin into the COSMOS system
|
335
|
+
# This code is used from the command line and is the same code that gets called if you
|
336
|
+
# edit/upgrade or install a new plugin from the Admin interface
|
337
|
+
#
|
338
|
+
# Usage: cosmos load gemfile_path [scope] [plugin_hash_file_path]
|
339
|
+
#
|
340
|
+
# With just gemfile_path and/or scope: Will do nothing if any plugin
|
341
|
+
# with the same gem file already exists
|
342
|
+
#
|
343
|
+
# Otherwise will do what the plugin_hash_file says to do
|
344
|
+
# Plugin hash file must have the exact name of an existing plugin for upgrades and edits
|
345
|
+
# Otherwise, it will be assumed that the plugin is intentionally being installed for a second
|
346
|
+
# time
|
347
|
+
#
|
348
|
+
def load_plugin(plugin_file_path, scope:, plugin_hash_file: nil)
|
216
349
|
scope ||= 'DEFAULT'
|
217
350
|
# Only create the scope if it doesn't already exist
|
218
351
|
unless Cosmos::ScopeModel.names.include?(scope)
|
@@ -226,41 +359,47 @@ def load_plugin(plugin_file_path, scope:, variables_file: nil)
|
|
226
359
|
end
|
227
360
|
|
228
361
|
begin
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
if
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
362
|
+
if plugin_hash_file
|
363
|
+
# Admin Create / Edit / or Upgrade Plugin
|
364
|
+
Cosmos::PluginModel.install_phase1(plugin_file_path, scope: scope)
|
365
|
+
plugin_hash = JSON.parse(File.read(plugin_hash_file))
|
366
|
+
else
|
367
|
+
# Init or Command Line cosmos load with no plugin_hash_file
|
368
|
+
file_full_name = File.basename(plugin_file_path, ".gem")
|
369
|
+
file_gem_name = file_full_name.split('-')[0..-2].join('-')
|
370
|
+
found = false
|
371
|
+
plugin_names = Cosmos::PluginModel.names(scope: scope)
|
372
|
+
plugin_names.each do |plugin_name|
|
373
|
+
gem_name = plugin_name.split("__")[0]
|
374
|
+
full_name = File.basename(gem_name, ".gem")
|
375
|
+
gem_name = full_name.split('-')[0..-2].join('-')
|
376
|
+
if file_gem_name == gem_name
|
377
|
+
found = true
|
378
|
+
# Upgrade if version changed else do nothing
|
379
|
+
if file_full_name != full_name
|
380
|
+
update_plugin(plugin_file_path, plugin_name, scope: scope)
|
381
|
+
end
|
249
382
|
end
|
250
|
-
Cosmos::PluginModel.install_phase2(plugin_hash['name'], plugin_hash['variables'], scope: scope)
|
251
|
-
found = true
|
252
383
|
end
|
384
|
+
return if found
|
385
|
+
|
386
|
+
plugin_hash = Cosmos::PluginModel.install_phase1(plugin_file_path, scope: scope)
|
253
387
|
end
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
388
|
+
|
389
|
+
# Determine if plugin named in plugin_hash exists
|
390
|
+
existing_plugin_hash = Cosmos::PluginModel.get(name: plugin_hash['name'], scope: scope)
|
391
|
+
|
392
|
+
# Existing plugin hash will be present if plugin is being edited or upgraded
|
393
|
+
# If editing, gem name will match existing hash name
|
394
|
+
# If upgrading, gem name will not match the existing hash name
|
395
|
+
|
396
|
+
if existing_plugin_hash
|
397
|
+
# Upgrade or Edit
|
398
|
+
update_plugin(plugin_file_path, plugin_hash['name'], variables: plugin_hash['variables'], plugin_txt_lines: plugin_hash['plugin_txt_lines'], scope: scope)
|
399
|
+
else
|
400
|
+
# New Install
|
401
|
+
puts "Loading new plugin: #{plugin_file_path}\n#{plugin_hash}"
|
402
|
+
Cosmos::PluginModel.install_phase2(plugin_hash, scope: scope)
|
264
403
|
end
|
265
404
|
rescue => err
|
266
405
|
abort("Error installing plugin: #{scope}: #{plugin_file_path}: #{err.formatted}")
|
@@ -305,8 +444,11 @@ if not ARGV[0].nil? # argument(s) given
|
|
305
444
|
when 'rake'
|
306
445
|
puts `rake #{ARGV[1..-1].join(' ')}`
|
307
446
|
|
447
|
+
when 'validate'
|
448
|
+
validate_plugin(ARGV[1], scope: ARGV[2], variables_file: ARGV[3])
|
449
|
+
|
308
450
|
when 'load'
|
309
|
-
load_plugin(ARGV[1], scope: ARGV[2],
|
451
|
+
load_plugin(ARGV[1], scope: ARGV[2], plugin_hash_file: ARGV[3])
|
310
452
|
|
311
453
|
when 'geminstall'
|
312
454
|
gem_install(ARGV[1])
|
@@ -333,9 +475,8 @@ if not ARGV[0].nil? # argument(s) given
|
|
333
475
|
when 'cstol_converter'
|
334
476
|
puts `ruby /cosmos/bin/cstol_converter #{ARGV[1..-1].join(' ')}`
|
335
477
|
|
336
|
-
|
337
|
-
|
338
|
-
# puts `ruby /cosmos/bin/xtce_converter #{ARGV[1..-1].join(' ')}`
|
478
|
+
when 'xtce_converter'
|
479
|
+
xtce_converter(ARGV[1..-1])
|
339
480
|
|
340
481
|
when 'bridge'
|
341
482
|
ENV['COSMOS_NO_STORE'] = '1'
|
data/data/config/plugins.yaml
CHANGED
@@ -68,3 +68,13 @@ ROUTER:
|
|
68
68
|
<%= MetaConfigParser.load('target.yaml').to_meta_config_yaml() %>
|
69
69
|
<%= MetaConfigParser.load('microservice.yaml').to_meta_config_yaml() %>
|
70
70
|
<%= MetaConfigParser.load('tool.yaml').to_meta_config_yaml() %>
|
71
|
+
WIDGET:
|
72
|
+
summary: Define a custom widget
|
73
|
+
example: WIDGET HELLOWORLD
|
74
|
+
description: Defines a custom widget that can be used in Telemetry Viewer screens.
|
75
|
+
parameters:
|
76
|
+
- name: Widget Name
|
77
|
+
description: The name of the widget wil be used to build a path to the widget implementation. For example, `WIDGET HELLOWORLD` will find the as-built file tools/widgets/HelloworldWidget/HelloworldWidget.umd.min.js. See the [Custom Widgets](/docs/v5/custom-widgets)
|
78
|
+
guide for more details.
|
79
|
+
required: true
|
80
|
+
values: .+
|
@@ -30,19 +30,19 @@ VALUE mCosmosIO = Qnil;
|
|
30
30
|
static ID id_method_read = 0;
|
31
31
|
|
32
32
|
/* Reads a length field and then return the String resulting from reading the
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
33
|
+
* number of bytes the length field indicates
|
34
|
+
*
|
35
|
+
* For example:
|
36
|
+
* io = StringIO.new
|
37
|
+
* # where io is "\x02\x01\x02\x03\x04...."
|
38
|
+
* result = io.read_length_bytes(1)
|
39
|
+
* # result will be "\x01x02" because the length field was given
|
40
|
+
* # to be 1 byte. We read 1 byte which is a 2. So we then read two
|
41
|
+
* # bytes and return.
|
42
|
+
*
|
43
|
+
* @param length_num_bytes [Integer] Number of bytes in the length field
|
44
|
+
* @return [String] A String of "length field" number of bytes
|
45
|
+
*/
|
46
46
|
static VALUE read_length_bytes(int argc, VALUE *argv, VALUE self)
|
47
47
|
{
|
48
48
|
int length_num_bytes = 0;
|
@@ -134,7 +134,7 @@ static VALUE read_length_bytes(int argc, VALUE *argv, VALUE self)
|
|
134
134
|
}
|
135
135
|
|
136
136
|
/* Read String */
|
137
|
-
temp_string_length = UINT2NUM(string_length);
|
137
|
+
temp_string_length = UINT2NUM((unsigned int)string_length);
|
138
138
|
return_value = rb_funcall(self, id_method_read, 1, temp_string_length);
|
139
139
|
if (NIL_P(return_value) || (RSTRING_LEN(return_value) != string_length))
|
140
140
|
{
|
@@ -196,7 +196,7 @@ static VALUE packet_initialize(int argc, VALUE *argv, VALUE self)
|
|
196
196
|
packet_name = argv[1];
|
197
197
|
default_endianness = symbol_BIG_ENDIAN;
|
198
198
|
description = Qnil;
|
199
|
-
buffer =
|
199
|
+
buffer = Qnil;
|
200
200
|
item_class = cPacketItem;
|
201
201
|
break;
|
202
202
|
case 3:
|
@@ -204,7 +204,7 @@ static VALUE packet_initialize(int argc, VALUE *argv, VALUE self)
|
|
204
204
|
packet_name = argv[1];
|
205
205
|
default_endianness = argv[2];
|
206
206
|
description = Qnil;
|
207
|
-
buffer =
|
207
|
+
buffer = Qnil;
|
208
208
|
item_class = cPacketItem;
|
209
209
|
break;
|
210
210
|
case 4:
|
@@ -212,7 +212,7 @@ static VALUE packet_initialize(int argc, VALUE *argv, VALUE self)
|
|
212
212
|
packet_name = argv[1];
|
213
213
|
default_endianness = argv[2];
|
214
214
|
description = argv[3];
|
215
|
-
buffer =
|
215
|
+
buffer = Qnil;
|
216
216
|
item_class = cPacketItem;
|
217
217
|
break;
|
218
218
|
case 5:
|
@@ -56,6 +56,7 @@ static ID id_method_reverse = 0;
|
|
56
56
|
static ID id_method_Integer = 0;
|
57
57
|
static ID id_method_Float = 0;
|
58
58
|
static ID id_method_kind_of = 0;
|
59
|
+
static ID id_method_allocate_buffer_if_needed = 0;
|
59
60
|
|
60
61
|
static ID id_ivar_buffer = 0;
|
61
62
|
static ID id_ivar_bit_offset = 0;
|
@@ -520,7 +521,8 @@ static VALUE binary_accessor_read(VALUE self, VALUE param_bit_offset, VALUE para
|
|
520
521
|
{
|
521
522
|
string_length = upper_bound - lower_bound + 1;
|
522
523
|
string = malloc(string_length + 1);
|
523
|
-
if (string == NULL)
|
524
|
+
if (string == NULL)
|
525
|
+
{
|
524
526
|
rb_raise(rb_eNoMemError, "malloc of %d returned NULL", string_length + 1);
|
525
527
|
}
|
526
528
|
memcpy(string, buffer + lower_bound, string_length);
|
@@ -577,7 +579,8 @@ static VALUE binary_accessor_read(VALUE self, VALUE param_bit_offset, VALUE para
|
|
577
579
|
string_length = ((bit_size - 1) / 8) + 1;
|
578
580
|
array_length = string_length + 4; /* Required number of bytes plus slack */
|
579
581
|
unsigned_char_array = (unsigned char *)malloc(array_length);
|
580
|
-
if (unsigned_char_array == NULL)
|
582
|
+
if (unsigned_char_array == NULL)
|
583
|
+
{
|
581
584
|
rb_raise(rb_eNoMemError, "malloc of %d returned NULL", array_length);
|
582
585
|
}
|
583
586
|
read_bitfield(lower_bound, upper_bound, bit_offset, bit_size, given_bit_offset, given_bit_size, param_endianness, buffer, (int)buffer_length, unsigned_char_array);
|
@@ -692,7 +695,8 @@ static VALUE binary_accessor_read(VALUE self, VALUE param_bit_offset, VALUE para
|
|
692
695
|
string_length = ((bit_size - 1) / 8) + 1;
|
693
696
|
array_length = string_length + 4; /* Required number of bytes plus slack */
|
694
697
|
unsigned_char_array = (unsigned char *)malloc(array_length);
|
695
|
-
if (unsigned_char_array == NULL)
|
698
|
+
if (unsigned_char_array == NULL)
|
699
|
+
{
|
696
700
|
rb_raise(rb_eNoMemError, "malloc of %d returned NULL", array_length);
|
697
701
|
}
|
698
702
|
read_bitfield(lower_bound, upper_bound, bit_offset, bit_size, given_bit_offset, given_bit_size, param_endianness, buffer, (int)buffer_length, unsigned_char_array);
|
@@ -1147,7 +1151,8 @@ static VALUE binary_accessor_write(VALUE self, VALUE value, VALUE param_bit_offs
|
|
1147
1151
|
string_length = ((bit_size - 1) / 8) + 1;
|
1148
1152
|
array_length = string_length + 4; /* Required number of bytes plus slack */
|
1149
1153
|
unsigned_char_array = (unsigned char *)malloc(array_length);
|
1150
|
-
if (unsigned_char_array == NULL)
|
1154
|
+
if (unsigned_char_array == NULL)
|
1155
|
+
{
|
1151
1156
|
rb_raise(rb_eNoMemError, "malloc of %d returned NULL", array_length);
|
1152
1157
|
}
|
1153
1158
|
|
@@ -1275,15 +1280,8 @@ static VALUE binary_accessor_write(VALUE self, VALUE value, VALUE param_bit_offs
|
|
1275
1280
|
*/
|
1276
1281
|
static int get_int_length(VALUE self)
|
1277
1282
|
{
|
1278
|
-
|
1279
|
-
|
1280
|
-
{
|
1281
|
-
return (int)RSTRING_LEN(buffer);
|
1282
|
-
}
|
1283
|
-
else
|
1284
|
-
{
|
1285
|
-
return 0;
|
1286
|
-
}
|
1283
|
+
rb_funcall(self, id_method_allocate_buffer_if_needed, 0);
|
1284
|
+
return (int)RSTRING_LEN(rb_ivar_get(self, id_ivar_buffer));
|
1287
1285
|
}
|
1288
1286
|
|
1289
1287
|
/*
|
@@ -1310,24 +1308,21 @@ static VALUE read_item_internal(VALUE self, VALUE item, VALUE buffer)
|
|
1310
1308
|
return Qnil;
|
1311
1309
|
}
|
1312
1310
|
|
1313
|
-
if (RTEST(buffer))
|
1311
|
+
if (!(RTEST(buffer)))
|
1314
1312
|
{
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
{
|
1325
|
-
return binary_accessor_read(cBinaryAccessor, bit_offset, bit_size, data_type, buffer, endianness);
|
1326
|
-
}
|
1313
|
+
buffer = rb_funcall(self, id_method_allocate_buffer_if_needed, 0);
|
1314
|
+
}
|
1315
|
+
bit_offset = rb_ivar_get(item, id_ivar_bit_offset);
|
1316
|
+
bit_size = rb_ivar_get(item, id_ivar_bit_size);
|
1317
|
+
array_size = rb_ivar_get(item, id_ivar_array_size);
|
1318
|
+
endianness = rb_ivar_get(item, id_ivar_endianness);
|
1319
|
+
if (RTEST(array_size))
|
1320
|
+
{
|
1321
|
+
return rb_funcall(cBinaryAccessor, id_method_read_array, 6, bit_offset, bit_size, data_type, array_size, buffer, endianness);
|
1327
1322
|
}
|
1328
1323
|
else
|
1329
1324
|
{
|
1330
|
-
|
1325
|
+
return binary_accessor_read(cBinaryAccessor, bit_offset, bit_size, data_type, buffer, endianness);
|
1331
1326
|
}
|
1332
1327
|
}
|
1333
1328
|
|
@@ -1404,8 +1399,8 @@ static VALUE structure_item_spaceship(VALUE self, VALUE other_item)
|
|
1404
1399
|
if ((bit_offset == 0) && (other_bit_offset == 0))
|
1405
1400
|
{
|
1406
1401
|
/* Both bit_offsets are 0 so sort by bit_size
|
1407
|
-
|
1408
|
-
|
1402
|
+
* This allows derived items with bit_size of 0 to be listed first
|
1403
|
+
* Compare based on bit size */
|
1409
1404
|
bit_size = FIX2INT(rb_ivar_get(self, id_ivar_bit_size));
|
1410
1405
|
other_bit_size = FIX2INT(rb_ivar_get(other_item, id_ivar_bit_size));
|
1411
1406
|
if (bit_size == other_bit_size)
|
@@ -1518,12 +1513,12 @@ static VALUE structure_initialize(int argc, VALUE *argv, VALUE self)
|
|
1518
1513
|
{
|
1519
1514
|
case 0:
|
1520
1515
|
default_endianness = HOST_ENDIANNESS;
|
1521
|
-
buffer =
|
1516
|
+
buffer = Qnil;
|
1522
1517
|
item_class = cStructureItem;
|
1523
1518
|
break;
|
1524
1519
|
case 1:
|
1525
1520
|
default_endianness = argv[0];
|
1526
|
-
buffer =
|
1521
|
+
buffer = Qnil;
|
1527
1522
|
item_class = cStructureItem;
|
1528
1523
|
break;
|
1529
1524
|
case 2:
|
@@ -1592,6 +1587,10 @@ static VALUE resize_buffer(VALUE self)
|
|
1592
1587
|
rb_str_concat(buffer, rb_str_times(ZERO_STRING, INT2FIX(defined_length - current_length)));
|
1593
1588
|
}
|
1594
1589
|
}
|
1590
|
+
else
|
1591
|
+
{
|
1592
|
+
rb_funcall(self, id_method_allocate_buffer_if_needed, 0);
|
1593
|
+
}
|
1595
1594
|
|
1596
1595
|
return self;
|
1597
1596
|
}
|
@@ -1618,6 +1617,7 @@ void Init_structure(void)
|
|
1618
1617
|
id_method_Integer = rb_intern("Integer");
|
1619
1618
|
id_method_Float = rb_intern("Float");
|
1620
1619
|
id_method_kind_of = rb_intern("kind_of?");
|
1620
|
+
id_method_allocate_buffer_if_needed = rb_intern("allocate_buffer_if_needed");
|
1621
1621
|
|
1622
1622
|
MIN_INT8 = INT2NUM(-128);
|
1623
1623
|
MAX_INT8 = INT2NUM(127);
|
data/lib/cosmos/api/tlm_api.rb
CHANGED
@@ -111,11 +111,11 @@ module Cosmos
|
|
111
111
|
|
112
112
|
# Injects a packet into the system as if it was received from an interface
|
113
113
|
#
|
114
|
-
# @param target_name[String] Target name of the packet
|
115
|
-
# @param packet_name[String] Packet name of the packet
|
116
|
-
# @param item_hash[Hash] Hash of item_name and value for each item you want to change from the current value table
|
114
|
+
# @param target_name [String] Target name of the packet
|
115
|
+
# @param packet_name [String] Packet name of the packet
|
116
|
+
# @param item_hash [Hash] Hash of item_name and value for each item you want to change from the current value table
|
117
117
|
# @param type [Symbol] Telemetry type, :RAW, :CONVERTED (default), :FORMATTED, or :WITH_UNITS
|
118
|
-
def inject_tlm(target_name, packet_name, item_hash = nil,
|
118
|
+
def inject_tlm(target_name, packet_name, item_hash = nil, type: :CONVERTED, scope: $cosmos_scope, token: $cosmos_token)
|
119
119
|
authorize(permission: 'tlm_set', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
|
120
120
|
unless CvtModel::VALUE_TYPES.include?(type.intern)
|
121
121
|
raise "Unknown type '#{type}' for #{target_name} #{packet_name}"
|