cosmos 3.1.2 → 3.2.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.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/Manifest.txt +17 -1
- data/autohotkey/tools/test_runner2.ahk +1 -0
- data/autohotkey/tools/tlm_grapher.ahk +13 -1
- data/data/crc.txt +39 -30
- data/demo/config/data/crc.txt +3 -3
- data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +3 -1
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +7 -1
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +6 -1
- data/lib/cosmos.rb +2 -2
- data/lib/cosmos/gui/dialogs/about_dialog.rb +18 -5
- data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +0 -7
- data/lib/cosmos/gui/line_graph/overview_graph.rb +12 -2
- data/lib/cosmos/gui/utilities/script_module_gui.rb +11 -3
- data/lib/cosmos/interfaces/interface.rb +12 -0
- data/lib/cosmos/interfaces/stream_interface.rb +1 -21
- data/lib/cosmos/interfaces/tcpip_server_interface.rb +10 -0
- data/lib/cosmos/io/json_drb_object.rb +75 -56
- data/lib/cosmos/io/tcpip_server.rb +1 -11
- data/lib/cosmos/packet_logs.rb +1 -0
- data/lib/cosmos/packet_logs/ccsds_log_reader.rb +103 -0
- data/lib/cosmos/packets/packet.rb +70 -1
- data/lib/cosmos/packets/packet_config.rb +59 -611
- data/lib/cosmos/packets/parsers/format_string_parser.rb +58 -0
- data/lib/cosmos/packets/parsers/limits_parser.rb +146 -0
- data/lib/cosmos/packets/parsers/limits_response_parser.rb +52 -0
- data/lib/cosmos/packets/parsers/macro_parser.rb +116 -0
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +215 -0
- data/lib/cosmos/packets/parsers/packet_parser.rb +123 -0
- data/lib/cosmos/packets/parsers/processor_parser.rb +63 -0
- data/lib/cosmos/packets/parsers/state_parser.rb +116 -0
- data/lib/cosmos/packets/structure.rb +59 -22
- data/lib/cosmos/packets/structure_item.rb +1 -1
- data/lib/cosmos/script/script.rb +4 -5
- data/lib/cosmos/streams/serial_stream.rb +5 -0
- data/lib/cosmos/streams/stream.rb +8 -2
- data/lib/cosmos/streams/stream_protocol.rb +1 -0
- data/lib/cosmos/streams/tcpip_client_stream.rb +37 -7
- data/lib/cosmos/streams/tcpip_socket_stream.rb +9 -6
- data/lib/cosmos/system/target.rb +3 -6
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +57 -48
- data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +7 -3
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +1 -1
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +7 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +1 -2
- data/lib/cosmos/top_level.rb +22 -11
- data/lib/cosmos/utilities/message_log.rb +14 -9
- data/lib/cosmos/version.rb +5 -5
- data/spec/interfaces/cmd_tlm_server_interface_spec.rb +16 -16
- data/spec/interfaces/linc_interface_spec.rb +3 -0
- data/spec/interfaces/tcpip_client_interface_spec.rb +1 -0
- data/spec/interfaces/tcpip_server_interface_spec.rb +9 -0
- data/spec/io/json_drb_object_spec.rb +1 -1
- data/spec/io/serial_driver_spec.rb +0 -1
- data/spec/packet_logs/packet_log_writer_spec.rb +5 -3
- data/spec/packets/packet_config_spec.rb +22 -837
- data/spec/packets/packet_item_spec.rb +10 -10
- data/spec/packets/packet_spec.rb +239 -1
- data/spec/packets/parsers/format_string_parser_spec.rb +122 -0
- data/spec/packets/parsers/limits_parser_spec.rb +282 -0
- data/spec/packets/parsers/limits_response_parser_spec.rb +149 -0
- data/spec/packets/parsers/macro_parser_spec.rb +184 -0
- data/spec/packets/parsers/packet_item_parser_spec.rb +306 -0
- data/spec/packets/parsers/packet_parser_spec.rb +99 -0
- data/spec/packets/parsers/processor_parser_spec.rb +114 -0
- data/spec/packets/parsers/state_parser_spec.rb +156 -0
- data/spec/packets/structure_item_spec.rb +14 -14
- data/spec/packets/structure_spec.rb +162 -16
- data/spec/streams/fixed_stream_protocol_spec.rb +7 -4
- data/spec/streams/length_stream_protocol_spec.rb +3 -0
- data/spec/streams/preidentified_stream_protocol_spec.rb +3 -0
- data/spec/streams/serial_stream_spec.rb +12 -0
- data/spec/streams/stream_protocol_spec.rb +14 -0
- data/spec/streams/stream_spec.rb +1 -0
- data/spec/streams/tcpip_client_stream_spec.rb +3 -0
- data/spec/streams/tcpip_socket_stream_spec.rb +15 -3
- data/spec/streams/template_stream_protocol_spec.rb +5 -0
- data/spec/streams/terminated_stream_protocol_spec.rb +4 -0
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +21 -1
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +1 -1
- data/spec/tools/cmd_tlm_server/interfaces_spec.rb +1 -1
- metadata +19 -3
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2014 Ball Aerospace & Technologies Corp.
|
|
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 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
|
+
require 'cosmos/packets/packet'
|
|
12
|
+
|
|
13
|
+
module Cosmos
|
|
14
|
+
|
|
15
|
+
class PacketParser
|
|
16
|
+
# @param parser [ConfigParser] Configuration parser
|
|
17
|
+
# @param target_name [String] The name of the target to create the packet
|
|
18
|
+
# under. If the target name is 'SYSTEM' the keyword parameter will be
|
|
19
|
+
# used instead of this parameter.
|
|
20
|
+
# @param commands [Hash] Hash of the currently defined commands
|
|
21
|
+
# @param warnings [Array<String>] Any warning strings generated while
|
|
22
|
+
# parsing this command will be appened to this array
|
|
23
|
+
def self.parse_command(parser, target_name, commands, warnings)
|
|
24
|
+
parser = PacketParser.new(parser)
|
|
25
|
+
parser.verify_parameters()
|
|
26
|
+
parser.create_command(target_name, commands, warnings)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param parser [ConfigParser] Configuration parser
|
|
30
|
+
# @param target_name [String] The name of the target to create the packet
|
|
31
|
+
# under. If the target name is 'SYSTEM' the keyword parameter will be
|
|
32
|
+
# used instead of this parameter.
|
|
33
|
+
# @param telemetry [Hash] Hash of the currently defined telemetry packets
|
|
34
|
+
# @param latest_data [Hash<String=>Hash<String=>Array(Packet)>>] Hash of hashes keyed
|
|
35
|
+
# first by the target name and then by the item name. This results in an
|
|
36
|
+
# array of packets containing that target and item. This structure is
|
|
37
|
+
# used to perform lookups when the packet and item are known but the
|
|
38
|
+
# packet is not.
|
|
39
|
+
# @param warnings [Array<String>] Any warning strings generated while
|
|
40
|
+
# parsing this command will be appened to this array
|
|
41
|
+
def self.parse_telemetry(parser, target_name, telemetry, latest_data, warnings)
|
|
42
|
+
parser = PacketParser.new(parser)
|
|
43
|
+
parser.verify_parameters()
|
|
44
|
+
parser.create_telemetry(target_name, telemetry, latest_data, warnings)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @param packet [Packet] Packet to check all default and range items for
|
|
48
|
+
# appropriate data types. Only applicable to COMMAND packets.
|
|
49
|
+
def self.check_item_data_types(packet)
|
|
50
|
+
packet.sorted_items.each do |item|
|
|
51
|
+
item.check_default_and_range_data_types()
|
|
52
|
+
end
|
|
53
|
+
rescue => err
|
|
54
|
+
# Add the target name and packet name to the error message so the user
|
|
55
|
+
# can debug where the error occurred
|
|
56
|
+
raise $!, "#{packet.target_name} #{packet.packet_name} #{$!}", $!.backtrace
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @param parser [ConfigParser] Configuration parser
|
|
60
|
+
def initialize(parser)
|
|
61
|
+
@parser = parser
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def verify_parameters
|
|
65
|
+
@usage = "#{@parser.keyword} <TARGET NAME> <PACKET NAME> <ENDIANNESS: BIG_ENDIAN/LITTLE_ENDIAN> <DESCRIPTION (Optional)>"
|
|
66
|
+
@parser.verify_num_parameters(3, 4, @usage)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def create_command(target_name, commands, warnings)
|
|
70
|
+
packet = create_packet(target_name)
|
|
71
|
+
warning = check_for_duplicate('Command', commands, packet)
|
|
72
|
+
warnings << warning if warning
|
|
73
|
+
commands[packet.target_name] ||= {}
|
|
74
|
+
packet
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def create_telemetry(target_name, telemetry, latest_data, warnings)
|
|
78
|
+
packet = create_packet(target_name)
|
|
79
|
+
warning = check_for_duplicate('Telemetry', telemetry, packet)
|
|
80
|
+
warnings << warning if warning
|
|
81
|
+
|
|
82
|
+
# Add received time packet items
|
|
83
|
+
item = packet.define_item('RECEIVED_TIMESECONDS', 0, 0, :DERIVED, nil, packet.default_endianness, :ERROR, '%0.6f', ReceivedTimeSecondsConversion.new)
|
|
84
|
+
item.description = 'COSMOS Received Time (UTC, Floating point, Unix epoch)'
|
|
85
|
+
item = packet.define_item('RECEIVED_TIMEFORMATTED', 0, 0, :DERIVED, nil, packet.default_endianness, :ERROR, nil, ReceivedTimeFormattedConversion.new)
|
|
86
|
+
item.description = 'COSMOS Received Time (Local time zone, Formatted string)'
|
|
87
|
+
item = packet.define_item('RECEIVED_COUNT', 0, 0, :DERIVED, nil, packet.default_endianness, :ERROR, nil, ReceivedCountConversion.new)
|
|
88
|
+
item.description = 'COSMOS packet received count'
|
|
89
|
+
|
|
90
|
+
unless telemetry[packet.target_name]
|
|
91
|
+
telemetry[packet.target_name] = {}
|
|
92
|
+
latest_data[packet.target_name] = {}
|
|
93
|
+
end
|
|
94
|
+
packet
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
def create_packet(target_name)
|
|
100
|
+
params = @parser.parameters
|
|
101
|
+
target_name = params[0].to_s.upcase if target_name == 'SYSTEM'
|
|
102
|
+
packet_name = params[1].to_s.upcase
|
|
103
|
+
endianness = params[2].to_s.upcase.to_sym
|
|
104
|
+
description = params[3].to_s
|
|
105
|
+
if endianness != :BIG_ENDIAN and endianness != :LITTLE_ENDIAN
|
|
106
|
+
raise @parser.error("Invalid endianness #{params[2]}. Must be BIG_ENDIAN or LITTLE_ENDIAN.", @usage)
|
|
107
|
+
end
|
|
108
|
+
Packet.new(target_name, packet_name, endianness, description)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def check_for_duplicate(type, list, packet)
|
|
112
|
+
msg = nil
|
|
113
|
+
if list[packet.target_name]
|
|
114
|
+
if list[packet.target_name][packet.packet_name]
|
|
115
|
+
msg = "#{type} Packet #{packet.target_name} #{packet.packet_name} redefined."
|
|
116
|
+
Logger.instance.warn msg
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
msg
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
end
|
|
123
|
+
end # module Cosmos
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2014 Ball Aerospace & Technologies Corp.
|
|
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 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
|
+
require 'cosmos/processors'
|
|
12
|
+
|
|
13
|
+
module Cosmos
|
|
14
|
+
|
|
15
|
+
class ProcessorParser
|
|
16
|
+
# @param parser [ConfigParser] Configuration parser
|
|
17
|
+
# @param packet [Packet] The current packet
|
|
18
|
+
# @param cmd_or_tlm [String] Whether this is a command or telemetry packet
|
|
19
|
+
def self.parse(parser, packet, cmd_or_tlm)
|
|
20
|
+
@parser = ProcessorParser.new(parser)
|
|
21
|
+
@parser.verify_parameters(cmd_or_tlm)
|
|
22
|
+
@parser.create_processor(packet)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @param parser [ConfigParser] Configuration parser
|
|
26
|
+
def initialize(parser)
|
|
27
|
+
@parser = parser
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @param cmd_or_tlm [String] Whether this is a command or telemetry packet
|
|
31
|
+
def verify_parameters(cmd_or_tlm)
|
|
32
|
+
if cmd_or_tlm == PacketConfig::COMMAND
|
|
33
|
+
raise @parser.error("PROCESSOR only applies to telemetry packets")
|
|
34
|
+
end
|
|
35
|
+
@usage = "PROCESSOR <PROCESSOR NAME> <PROCESSOR CLASS FILENAME> <PROCESSOR SPECIFIC OPTIONS>"
|
|
36
|
+
@parser.verify_num_parameters(2, nil, @usage)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @param packet [Packet] The packet the processor should be added to
|
|
40
|
+
def create_processor(packet)
|
|
41
|
+
# require should be performed in target.txt
|
|
42
|
+
klass = @parser.parameters[1].filename_to_class_name.to_class
|
|
43
|
+
raise @parser.error("#{@parser.parameters[1].filename_to_class_name} class not found. Did you require the file in target.txt?", @usage) unless klass
|
|
44
|
+
if @parser.parameters[2]
|
|
45
|
+
processor = klass.new(*@parser.parameters[2..(@parser.parameters.length - 1)])
|
|
46
|
+
else
|
|
47
|
+
processor = klass.new
|
|
48
|
+
end
|
|
49
|
+
raise ArgumentError, "processor must be a Cosmos::Processor but is a #{processor.class}" unless Cosmos::Processor === processor
|
|
50
|
+
processor.name = get_processor_name()
|
|
51
|
+
packet.processors[processor.name] = processor
|
|
52
|
+
rescue Exception => err
|
|
53
|
+
raise @parser.error(err, @usage)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def get_processor_name
|
|
59
|
+
@parser.parameters[0].to_s.upcase
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end # module Cosmos
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2014 Ball Aerospace & Technologies Corp.
|
|
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 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
|
+
require 'cosmos/packets/packet_item'
|
|
12
|
+
|
|
13
|
+
module Cosmos
|
|
14
|
+
|
|
15
|
+
class StateParser
|
|
16
|
+
# @param parser [ConfigParser] Configuration parser
|
|
17
|
+
# @param packet [Packet] The current packet
|
|
18
|
+
# @param cmd_or_tlm [String] Whether this is a command or telemetry packet
|
|
19
|
+
# @param item [PacketItem] The packet item to create states on
|
|
20
|
+
# @param warnings [Array<String>] Array of string warnings which will be
|
|
21
|
+
# appended with any warnings found when parsing the limits
|
|
22
|
+
def self.parse(parser, packet, cmd_or_tlm, item, warnings)
|
|
23
|
+
@parser = StateParser.new(parser)
|
|
24
|
+
@parser.verify_parameters(cmd_or_tlm)
|
|
25
|
+
@parser.create_state(packet, cmd_or_tlm, item, warnings)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @param parser [ConfigParser] Configuration parser
|
|
29
|
+
def initialize(parser)
|
|
30
|
+
@parser = parser
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @param cmd_or_tlm [String] Whether this is a command or telemetry packet
|
|
34
|
+
def verify_parameters(cmd_or_tlm)
|
|
35
|
+
@usage = "STATE <STATE NAME> <STATE VALUE> "
|
|
36
|
+
if cmd_or_tlm == PacketConfig::COMMAND
|
|
37
|
+
@usage << "<HAZARDOUS (Optional)> <Hazardous Description (Optional)>"
|
|
38
|
+
@parser.verify_num_parameters(2, 4, @usage)
|
|
39
|
+
else
|
|
40
|
+
@usage << "<COLOR: GREEN/YELLOW/RED (Optional)>"
|
|
41
|
+
@parser.verify_num_parameters(2, 3, @usage)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @param packet [Packet] The current packet
|
|
46
|
+
# @param cmd_or_tlm [String] Whether this is a command or telemetry packet
|
|
47
|
+
# @param item [PacketItem] The packet item to create states on
|
|
48
|
+
# @param warnings [Array<String>] Array of string warnings which will be
|
|
49
|
+
# appended with any warnings found when parsing the limits
|
|
50
|
+
def create_state(packet, cmd_or_tlm, item, warnings)
|
|
51
|
+
item.states ||= {}
|
|
52
|
+
|
|
53
|
+
state_name = get_state_name()
|
|
54
|
+
check_for_duplicate_states(item, warnings)
|
|
55
|
+
item.states[state_name] = get_state_value(item.data_type)
|
|
56
|
+
parse_additional_parameters(packet, cmd_or_tlm, item)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def get_state_name
|
|
62
|
+
@parser.parameters[0].upcase
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def get_state_value(data_type)
|
|
66
|
+
if data_type == :STRING || data_type == :BLOCK
|
|
67
|
+
@parser.parameters[1]
|
|
68
|
+
else
|
|
69
|
+
@parser.parameters[1].convert_to_value
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def check_for_duplicate_states(item, warnings)
|
|
74
|
+
if item.states[get_state_name()]
|
|
75
|
+
msg = "Duplicate state defined on line #{@parser.line_number}: #{@parser.line}"
|
|
76
|
+
Logger.instance.warn(msg)
|
|
77
|
+
warnings << msg
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def parse_additional_parameters(packet, cmd_or_tlm, item)
|
|
82
|
+
return unless @parser.parameters.length > 2
|
|
83
|
+
|
|
84
|
+
if cmd_or_tlm == PacketConfig::COMMAND
|
|
85
|
+
get_hazardous(item)
|
|
86
|
+
else
|
|
87
|
+
get_state_colors(item)
|
|
88
|
+
packet.update_limits_items_cache
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def get_hazardous(item)
|
|
93
|
+
if @parser.parameters[2].upcase == 'HAZARDOUS'
|
|
94
|
+
item.hazardous ||= {}
|
|
95
|
+
if @parser.parameters[3]
|
|
96
|
+
item.hazardous[get_state_name()] = @parser.parameters[3]
|
|
97
|
+
else
|
|
98
|
+
item.hazardous[get_state_name()] = ""
|
|
99
|
+
end
|
|
100
|
+
else
|
|
101
|
+
raise @parser.error("HAZARDOUS expected as third parameter for this line.", @usage)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def get_state_colors(item)
|
|
106
|
+
color = @parser.parameters[2].upcase.to_sym
|
|
107
|
+
unless PacketItem::STATE_COLORS.include? color
|
|
108
|
+
raise @parser.error("Invalid state color #{color}. Must be one of #{PacketItem::STATE_COLORS.join(' ')}.", @usage)
|
|
109
|
+
end
|
|
110
|
+
item.limits.enabled = true
|
|
111
|
+
item.state_colors ||= {}
|
|
112
|
+
item.state_colors[get_state_name()] = color
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
116
|
+
end # module Cosmos
|
|
@@ -66,6 +66,20 @@ module Cosmos
|
|
|
66
66
|
@sorted_items.length > 0
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
+
# Rename an existing item
|
|
70
|
+
#
|
|
71
|
+
# @param item_name [String] Name of the currently defined item
|
|
72
|
+
# @param new_item_name [String] New name for the item
|
|
73
|
+
def rename_item(item_name, new_item_name)
|
|
74
|
+
item = get_item(item_name)
|
|
75
|
+
item.name = new_item_name
|
|
76
|
+
@items.delete(item_name)
|
|
77
|
+
@items[new_item_name] = item
|
|
78
|
+
# Since @sorted_items contains the actual item reference it is
|
|
79
|
+
# updated when we set the item.name
|
|
80
|
+
item
|
|
81
|
+
end
|
|
82
|
+
|
|
69
83
|
# Define an item in the structure. This creates a new instance of the
|
|
70
84
|
# item_class as given in the constructor and adds it to the items hash. It
|
|
71
85
|
# also resizes the buffer to accomodate the new item.
|
|
@@ -89,12 +103,20 @@ module Cosmos
|
|
|
89
103
|
|
|
90
104
|
# Create the item
|
|
91
105
|
item = @item_class.new(name_upcase, bit_offset, bit_size, data_type, endianness, array_size, overflow)
|
|
106
|
+
define(item)
|
|
107
|
+
end
|
|
92
108
|
|
|
109
|
+
# Adds the given item to the items hash. It also resizes the buffer to
|
|
110
|
+
# accomodate the new item.
|
|
111
|
+
#
|
|
112
|
+
# @param item [StructureItem] The structure item to add
|
|
113
|
+
# @return [StrutureItem] The struture item defined
|
|
114
|
+
def define(item)
|
|
93
115
|
# Handle Overwriting Existing Item
|
|
94
|
-
if @items[
|
|
116
|
+
if @items[item.name]
|
|
95
117
|
item_index = nil
|
|
96
118
|
@sorted_items.each_with_index do |sorted_item, index|
|
|
97
|
-
if sorted_item.name ==
|
|
119
|
+
if sorted_item.name == item.name
|
|
98
120
|
item_index = index
|
|
99
121
|
break
|
|
100
122
|
end
|
|
@@ -117,9 +139,9 @@ module Cosmos
|
|
|
117
139
|
end
|
|
118
140
|
|
|
119
141
|
# Add to the overall hash of defined items
|
|
120
|
-
@items[
|
|
142
|
+
@items[item.name] = item
|
|
121
143
|
# Update fixed size knowledge
|
|
122
|
-
@fixed_size = false if ((data_type != :DERIVED and bit_size <= 0) or (array_size and array_size <= 0))
|
|
144
|
+
@fixed_size = false if ((item.data_type != :DERIVED and item.bit_size <= 0) or (item.array_size and item.array_size <= 0))
|
|
123
145
|
|
|
124
146
|
# Recalculate the overall defined length of the structure
|
|
125
147
|
update_needed = false
|
|
@@ -178,6 +200,17 @@ module Cosmos
|
|
|
178
200
|
return define_item(name, @defined_length_bits, bit_size, data_type, array_size, endianness, overflow)
|
|
179
201
|
end
|
|
180
202
|
|
|
203
|
+
# Adds an item at the end of the structure. It adds the item to the items
|
|
204
|
+
# hash and resizes the buffer to accomodate the new item.
|
|
205
|
+
#
|
|
206
|
+
# @param item (see #define)
|
|
207
|
+
# @return (see #define)
|
|
208
|
+
def append(item)
|
|
209
|
+
raise ArgumentError, "Can't append an item after a variably sized item" if !@fixed_size
|
|
210
|
+
item.bit_offset = @defined_length_bits
|
|
211
|
+
return define(item)
|
|
212
|
+
end
|
|
213
|
+
|
|
181
214
|
# @param name [String] Name of the item to look up in the items Hash
|
|
182
215
|
# @return [StructureItem] StructureItem or one of its subclasses
|
|
183
216
|
def get_item(name)
|
|
@@ -329,6 +362,28 @@ module Cosmos
|
|
|
329
362
|
end
|
|
330
363
|
end
|
|
331
364
|
|
|
365
|
+
# Make a light weight clone of this structure. This only creates a new buffer
|
|
366
|
+
# of data. The defined structure items are the same.
|
|
367
|
+
#
|
|
368
|
+
# @return [Structure] A copy of the current structure with a new underlying
|
|
369
|
+
# buffer of data
|
|
370
|
+
def clone
|
|
371
|
+
structure = super()
|
|
372
|
+
# Use instance_variable_set since we have overriden buffer= to do
|
|
373
|
+
# additional work that isn't neccessary here
|
|
374
|
+
structure.instance_variable_set("@buffer", @buffer.clone) if @buffer
|
|
375
|
+
return structure
|
|
376
|
+
end
|
|
377
|
+
alias dup clone
|
|
378
|
+
|
|
379
|
+
# Enable the ability to read and write item values as if they were methods
|
|
380
|
+
# to the class
|
|
381
|
+
def enable_method_missing
|
|
382
|
+
extend(MethodMissing)
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
protected
|
|
386
|
+
|
|
332
387
|
# Take the structure mutex to ensure the buffer does not change while you perform activities
|
|
333
388
|
def synchronize
|
|
334
389
|
@mutex ||= Mutex.new
|
|
@@ -365,24 +420,6 @@ module Cosmos
|
|
|
365
420
|
end
|
|
366
421
|
end
|
|
367
422
|
|
|
368
|
-
# Make a light weight clone of this structure. This only creates a new buffer
|
|
369
|
-
# of data. The defined structure items are the same.
|
|
370
|
-
#
|
|
371
|
-
# @return [Structure] A copy of the current structure with a new underlying
|
|
372
|
-
# buffer of data
|
|
373
|
-
def clone
|
|
374
|
-
structure = super()
|
|
375
|
-
@buffer = @buffer.clone if @buffer # Deep Copy @buffer
|
|
376
|
-
return structure
|
|
377
|
-
end
|
|
378
|
-
alias dup clone
|
|
379
|
-
|
|
380
|
-
def enable_method_missing
|
|
381
|
-
extend(MethodMissing)
|
|
382
|
-
end
|
|
383
|
-
|
|
384
|
-
protected
|
|
385
|
-
|
|
386
423
|
module MethodMissing
|
|
387
424
|
# Method missing provides reading/writing item values as if they were methods to the class
|
|
388
425
|
def method_missing(name, value = nil)
|
|
@@ -89,7 +89,7 @@ module Cosmos
|
|
|
89
89
|
raise ArgumentError, "name must be a String but is a #{name.class}" unless String === name
|
|
90
90
|
raise ArgumentError, "name must contain at least one character" if name.empty?
|
|
91
91
|
|
|
92
|
-
@name = name.clone.freeze
|
|
92
|
+
@name = name.upcase.clone.freeze
|
|
93
93
|
verify_overall() if @structure_item_constructed
|
|
94
94
|
end
|
|
95
95
|
|
data/lib/cosmos/script/script.rb
CHANGED
|
@@ -438,7 +438,7 @@ module Cosmos
|
|
|
438
438
|
script_runner.script_set_status(message) if script_runner
|
|
439
439
|
end
|
|
440
440
|
|
|
441
|
-
def ask_string(question, allow_blank = false)
|
|
441
|
+
def ask_string(question, allow_blank = false, password = false)
|
|
442
442
|
answer = ''
|
|
443
443
|
while answer.empty?
|
|
444
444
|
print question + " "
|
|
@@ -449,8 +449,8 @@ module Cosmos
|
|
|
449
449
|
return answer
|
|
450
450
|
end
|
|
451
451
|
|
|
452
|
-
def ask(question, allow_blank = false)
|
|
453
|
-
string = ask_string(question, allow_blank)
|
|
452
|
+
def ask(question, allow_blank = false, password = false)
|
|
453
|
+
string = ask_string(question, allow_blank, password)
|
|
454
454
|
value = string.convert_to_value
|
|
455
455
|
return value
|
|
456
456
|
end
|
|
@@ -1504,8 +1504,7 @@ module Cosmos
|
|
|
1504
1504
|
end
|
|
1505
1505
|
|
|
1506
1506
|
def shutdown_cmd_tlm
|
|
1507
|
-
|
|
1508
|
-
$cmd_tlm_server = nil
|
|
1507
|
+
$cmd_tlm_server.shutdown if $cmd_tlm_server && !$cmd_tlm_disconnect
|
|
1509
1508
|
end
|
|
1510
1509
|
|
|
1511
1510
|
end # module Script
|