openc3 5.20.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/bin/openc3cli +12 -120
  3. data/data/config/command_modifiers.yaml +13 -1
  4. data/data/config/interface_modifiers.yaml +21 -4
  5. data/data/config/item_modifiers.yaml +1 -1
  6. data/data/config/microservice.yaml +15 -2
  7. data/data/config/param_item_modifiers.yaml +1 -1
  8. data/data/config/parameter_modifiers.yaml +1 -1
  9. data/data/config/table_manager.yaml +2 -2
  10. data/data/config/target.yaml +11 -0
  11. data/data/config/telemetry_modifiers.yaml +17 -1
  12. data/data/config/tool.yaml +12 -0
  13. data/data/config/widgets.yaml +13 -17
  14. data/lib/openc3/accessors/form_accessor.rb +4 -3
  15. data/lib/openc3/accessors/html_accessor.rb +3 -3
  16. data/lib/openc3/accessors/http_accessor.rb +13 -13
  17. data/lib/openc3/accessors/xml_accessor.rb +16 -4
  18. data/lib/openc3/api/target_api.rb +0 -30
  19. data/lib/openc3/config/config_parser.rb +6 -3
  20. data/lib/openc3/core_ext/array.rb +0 -16
  21. data/lib/openc3/core_ext.rb +0 -1
  22. data/lib/openc3/interfaces/file_interface.rb +198 -0
  23. data/lib/openc3/interfaces/http_client_interface.rb +71 -39
  24. data/lib/openc3/interfaces/http_server_interface.rb +0 -7
  25. data/lib/openc3/interfaces/interface.rb +2 -0
  26. data/lib/openc3/interfaces/mqtt_interface.rb +32 -15
  27. data/lib/openc3/interfaces/mqtt_stream_interface.rb +19 -4
  28. data/lib/openc3/interfaces/protocols/crc_protocol.rb +7 -0
  29. data/lib/openc3/interfaces/serial_interface.rb +1 -0
  30. data/lib/openc3/interfaces.rb +2 -4
  31. data/lib/openc3/microservices/multi_microservice.rb +3 -3
  32. data/lib/openc3/migrations/20241208080000_no_critical_cmd.rb +31 -0
  33. data/lib/openc3/migrations/20241208080001_no_trigger_group.rb +46 -0
  34. data/lib/openc3/models/interface_model.rb +9 -3
  35. data/lib/openc3/models/microservice_model.rb +8 -1
  36. data/lib/openc3/models/plugin_model.rb +6 -1
  37. data/lib/openc3/models/python_package_model.rb +6 -1
  38. data/lib/openc3/models/reaction_model.rb +14 -10
  39. data/lib/openc3/models/scope_model.rb +60 -42
  40. data/lib/openc3/models/target_model.rb +17 -1
  41. data/lib/openc3/models/timeline_model.rb +17 -5
  42. data/lib/openc3/models/tool_model.rb +15 -3
  43. data/lib/openc3/models/trigger_group_model.rb +6 -3
  44. data/lib/openc3/operators/microservice_operator.rb +8 -0
  45. data/lib/openc3/packets/commands.rb +17 -6
  46. data/lib/openc3/packets/limits.rb +0 -12
  47. data/lib/openc3/packets/packet.rb +1 -1
  48. data/lib/openc3/packets/packet_item.rb +30 -36
  49. data/lib/openc3/packets/structure_item.rb +2 -2
  50. data/lib/openc3/script/script.rb +0 -10
  51. data/lib/openc3/script/web_socket_api.rb +2 -2
  52. data/lib/openc3/streams/mqtt_stream.rb +41 -33
  53. data/lib/openc3/streams/serial_stream.rb +27 -27
  54. data/lib/openc3/streams/stream.rb +17 -17
  55. data/lib/openc3/streams/tcpip_client_stream.rb +1 -1
  56. data/lib/openc3/streams/tcpip_socket_stream.rb +19 -19
  57. data/lib/openc3/system/system.rb +1 -1
  58. data/lib/openc3/system.rb +2 -3
  59. data/lib/openc3/tools/table_manager/table.rb +2 -2
  60. data/lib/openc3/tools/table_manager/table_parser.rb +1 -1
  61. data/lib/openc3/top_level.rb +0 -5
  62. data/lib/openc3/topics/command_decom_topic.rb +0 -7
  63. data/lib/openc3/utilities/bucket_utilities.rb +1 -1
  64. data/lib/openc3/utilities/cli_generator.rb +0 -1
  65. data/lib/openc3/version.rb +6 -6
  66. data/templates/plugin/README.md +1 -1
  67. data/templates/target/targets/TARGET/lib/target.rb +1 -1
  68. data/templates/tool_angular/package.json +8 -8
  69. data/templates/tool_angular/src/app/app.component.html +4 -13
  70. data/templates/tool_angular/src/app/app.component.scss +5 -13
  71. data/templates/tool_angular/src/app/app.component.ts +5 -4
  72. data/templates/tool_angular/src/app/custom-overlay-container.ts +2 -2
  73. data/templates/tool_angular/src/app/openc3-api.d.ts +1 -1
  74. data/templates/tool_angular/src/main.single-spa.ts +1 -1
  75. data/templates/tool_react/package.json +1 -0
  76. data/templates/tool_react/src/root.component.js +1 -1
  77. data/templates/tool_svelte/package.json +11 -9
  78. data/templates/tool_svelte/rollup.config.js +2 -0
  79. data/templates/tool_svelte/src/App.svelte +2 -2
  80. data/templates/tool_vue/eslint.config.mjs +68 -0
  81. data/templates/tool_vue/jsconfig.json +1 -1
  82. data/templates/tool_vue/package.json +26 -43
  83. data/templates/tool_vue/src/App.vue +3 -5
  84. data/templates/tool_vue/src/main.js +12 -23
  85. data/templates/tool_vue/src/router.js +19 -18
  86. data/templates/tool_vue/src/tools/tool_name/tool_name.vue +2 -2
  87. data/templates/tool_vue/vite.config.js +52 -0
  88. data/templates/widget/package.json +19 -26
  89. data/templates/widget/src/Widget.vue +13 -15
  90. data/templates/widget/vite.config.js +26 -0
  91. metadata +10 -41
  92. data/lib/openc3/core_ext/hash.rb +0 -40
  93. data/lib/openc3/core_ext/httpclient.rb +0 -11
  94. data/lib/openc3/interfaces/linc_interface.rb +0 -480
  95. data/lib/openc3/interfaces/protocols/override_protocol.rb +0 -4
  96. data/lib/openc3/microservices/critical_cmd_microservice.rb +0 -74
  97. data/lib/openc3/microservices/reaction_microservice.rb +0 -607
  98. data/lib/openc3/microservices/timeline_microservice.rb +0 -398
  99. data/lib/openc3/microservices/trigger_group_microservice.rb +0 -698
  100. data/lib/openc3/migrations/20230615000000_autonomic.rb +0 -86
  101. data/lib/openc3/migrations/20240915000000_activity_uuid.rb +0 -28
  102. data/lib/openc3/migrations/20241016000000_scope_critical_cmd.rb +0 -24
  103. data/lib/openc3/system/system_config.rb +0 -413
  104. data/templates/tool_svelte/src/services/api.js +0 -92
  105. data/templates/tool_svelte/src/services/axios.js +0 -85
  106. data/templates/tool_svelte/src/services/cable.js +0 -65
  107. data/templates/tool_svelte/src/services/config-parser.js +0 -198
  108. data/templates/tool_svelte/src/services/openc3-api.js +0 -606
  109. data/templates/tool_vue/.eslintrc.js +0 -43
  110. data/templates/tool_vue/babel.config.json +0 -11
  111. data/templates/tool_vue/vue.config.js +0 -38
  112. data/templates/widget/.eslintrc.js +0 -43
  113. data/templates/widget/babel.config.json +0 -11
  114. data/templates/widget/vue.config.js +0 -28
  115. /data/templates/tool_vue/{.prettierrc.js → .prettierrc.cjs} +0 -0
  116. /data/templates/widget/{.prettierrc.js → .prettierrc.cjs} +0 -0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openc3
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.20.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Melton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-10-30 00:00:00.000000000 Z
12
+ date: 2024-12-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -235,20 +235,6 @@ dependencies:
235
235
  - - "~>"
236
236
  - !ruby/object:Gem::Version
237
237
  version: '0.9'
238
- - !ruby/object:Gem::Dependency
239
- name: httpclient
240
- requirement: !ruby/object:Gem::Requirement
241
- requirements:
242
- - - "~>"
243
- - !ruby/object:Gem::Version
244
- version: '2.8'
245
- type: :runtime
246
- prerelease: false
247
- version_requirements: !ruby/object:Gem::Requirement
248
- requirements:
249
- - - "~>"
250
- - !ruby/object:Gem::Version
251
- version: '2.8'
252
238
  - !ruby/object:Gem::Dependency
253
239
  name: aws-sdk-s3
254
240
  requirement: !ruby/object:Gem::Requirement
@@ -925,8 +911,6 @@ files:
925
911
  - lib/openc3/core_ext/exception.rb
926
912
  - lib/openc3/core_ext/faraday.rb
927
913
  - lib/openc3/core_ext/file.rb
928
- - lib/openc3/core_ext/hash.rb
929
- - lib/openc3/core_ext/httpclient.rb
930
914
  - lib/openc3/core_ext/io.rb
931
915
  - lib/openc3/core_ext/kernel.rb
932
916
  - lib/openc3/core_ext/math.rb
@@ -941,10 +925,10 @@ files:
941
925
  - lib/openc3/core_ext/time.rb
942
926
  - lib/openc3/ext/.keep
943
927
  - lib/openc3/interfaces.rb
928
+ - lib/openc3/interfaces/file_interface.rb
944
929
  - lib/openc3/interfaces/http_client_interface.rb
945
930
  - lib/openc3/interfaces/http_server_interface.rb
946
931
  - lib/openc3/interfaces/interface.rb
947
- - lib/openc3/interfaces/linc_interface.rb
948
932
  - lib/openc3/interfaces/mqtt_interface.rb
949
933
  - lib/openc3/interfaces/mqtt_stream_interface.rb
950
934
  - lib/openc3/interfaces/protocols/burst_protocol.rb
@@ -954,7 +938,6 @@ files:
954
938
  - lib/openc3/interfaces/protocols/fixed_protocol.rb
955
939
  - lib/openc3/interfaces/protocols/ignore_packet_protocol.rb
956
940
  - lib/openc3/interfaces/protocols/length_protocol.rb
957
- - lib/openc3/interfaces/protocols/override_protocol.rb
958
941
  - lib/openc3/interfaces/protocols/preidentified_protocol.rb
959
942
  - lib/openc3/interfaces/protocols/protocol.rb
960
943
  - lib/openc3/interfaces/protocols/slip_protocol.rb
@@ -991,7 +974,6 @@ files:
991
974
  - lib/openc3/logs/stream_log_pair.rb
992
975
  - lib/openc3/logs/text_log_writer.rb
993
976
  - lib/openc3/microservices/cleanup_microservice.rb
994
- - lib/openc3/microservices/critical_cmd_microservice.rb
995
977
  - lib/openc3/microservices/decom_microservice.rb
996
978
  - lib/openc3/microservices/interface_decom_common.rb
997
979
  - lib/openc3/microservices/interface_microservice.rb
@@ -1000,21 +982,17 @@ files:
1000
982
  - lib/openc3/microservices/multi_microservice.rb
1001
983
  - lib/openc3/microservices/periodic_microservice.rb
1002
984
  - lib/openc3/microservices/plugin_microservice.rb
1003
- - lib/openc3/microservices/reaction_microservice.rb
1004
985
  - lib/openc3/microservices/reducer_microservice.rb
1005
986
  - lib/openc3/microservices/router_microservice.rb
1006
987
  - lib/openc3/microservices/scope_cleanup_microservice.rb
1007
988
  - lib/openc3/microservices/text_log_microservice.rb
1008
- - lib/openc3/microservices/timeline_microservice.rb
1009
- - lib/openc3/microservices/trigger_group_microservice.rb
1010
989
  - lib/openc3/migrations/20220420190000_log_stuff.rb
1011
990
  - lib/openc3/migrations/20221202214600_add_target_names.rb
1012
991
  - lib/openc3/migrations/20221210174900_convert_to_multi.rb
1013
- - lib/openc3/migrations/20230615000000_autonomic.rb
1014
992
  - lib/openc3/migrations/20230915000002_no_scope_log_messages.rb
1015
993
  - lib/openc3/migrations/20231022000000_tlm_viewer_config.rb
1016
- - lib/openc3/migrations/20240915000000_activity_uuid.rb
1017
- - lib/openc3/migrations/20241016000000_scope_critical_cmd.rb
994
+ - lib/openc3/migrations/20241208080000_no_critical_cmd.rb
995
+ - lib/openc3/migrations/20241208080001_no_trigger_group.rb
1018
996
  - lib/openc3/models/activity_model.rb
1019
997
  - lib/openc3/models/auth_model.rb
1020
998
  - lib/openc3/models/cvt_model.rb
@@ -1107,7 +1085,6 @@ files:
1107
1085
  - lib/openc3/streams/web_socket_client_stream.rb
1108
1086
  - lib/openc3/system.rb
1109
1087
  - lib/openc3/system/system.rb
1110
- - lib/openc3/system/system_config.rb
1111
1088
  - lib/openc3/system/target.rb
1112
1089
  - lib/openc3/tools/cmd_tlm_server/api.rb
1113
1090
  - lib/openc3/tools/cmd_tlm_server/interface_thread.rb
@@ -1244,37 +1221,29 @@ files:
1244
1221
  - templates/tool_svelte/rollup.config.js
1245
1222
  - templates/tool_svelte/src/App.svelte
1246
1223
  - templates/tool_svelte/src/App.test.js
1247
- - templates/tool_svelte/src/services/api.js
1248
- - templates/tool_svelte/src/services/axios.js
1249
- - templates/tool_svelte/src/services/cable.js
1250
- - templates/tool_svelte/src/services/config-parser.js
1251
- - templates/tool_svelte/src/services/openc3-api.js
1252
1224
  - templates/tool_svelte/src/theme/_smui-theme.scss
1253
1225
  - templates/tool_svelte/src/tool_name.js
1254
1226
  - templates/tool_vue/.browserslistrc
1255
1227
  - templates/tool_vue/.env.standalone
1256
- - templates/tool_vue/.eslintrc.js
1257
1228
  - templates/tool_vue/.gitignore
1258
1229
  - templates/tool_vue/.nycrc
1259
- - templates/tool_vue/.prettierrc.js
1260
- - templates/tool_vue/babel.config.json
1230
+ - templates/tool_vue/.prettierrc.cjs
1231
+ - templates/tool_vue/eslint.config.mjs
1261
1232
  - templates/tool_vue/jsconfig.json
1262
1233
  - templates/tool_vue/package.json
1263
1234
  - templates/tool_vue/src/App.vue
1264
1235
  - templates/tool_vue/src/main.js
1265
1236
  - templates/tool_vue/src/router.js
1266
1237
  - templates/tool_vue/src/tools/tool_name/tool_name.vue
1267
- - templates/tool_vue/vue.config.js
1238
+ - templates/tool_vue/vite.config.js
1268
1239
  - templates/widget/.browserslistrc
1269
- - templates/widget/.eslintrc.js
1270
1240
  - templates/widget/.nycrc
1271
- - templates/widget/.prettierrc.js
1241
+ - templates/widget/.prettierrc.cjs
1272
1242
  - templates/widget/LICENSE.txt
1273
1243
  - templates/widget/Rakefile
1274
- - templates/widget/babel.config.json
1275
1244
  - templates/widget/package.json
1276
1245
  - templates/widget/src/Widget.vue
1277
- - templates/widget/vue.config.js
1246
+ - templates/widget/vite.config.js
1278
1247
  homepage: https://github.com/OpenC3/cosmos
1279
1248
  licenses:
1280
1249
  - AGPL-3.0-only
@@ -1,40 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2022 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 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
- # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
18
- # All Rights Reserved
19
- #
20
- # This file may also be used under the terms of a commercial license
21
- # if purchased from OpenC3, Inc.
22
-
23
- # OpenC3 specific additions to the Ruby Hash class
24
- class Hash
25
- # Redefine inspect to only print for small numbers of
26
- # items. Prevents exceptions taking forever to be raised with
27
- # large objects. See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/105145
28
- alias old_inspect inspect
29
-
30
- # @param max_elements [Integer] The maximum number of elements in the Hash to
31
- # print out before simply displaying the Hash class and object id
32
- # @return [String] String representation of the hash
33
- def inspect(max_elements = 10)
34
- if self.length <= max_elements
35
- old_inspect()
36
- else
37
- '#<' + self.class.to_s + ':' + self.object_id.to_s + '>'
38
- end
39
- end
40
- end
@@ -1,11 +0,0 @@
1
- require 'httpclient'
2
-
3
- class HTTPClient
4
- alias original_initialize initialize
5
-
6
- def initialize(*args, &block)
7
- original_initialize(*args, &block)
8
- # Force use of the default system CA certs (instead of the 6 year old bundled ones)
9
- @session_manager&.ssl_config&.set_default_paths
10
- end
11
- end
@@ -1,480 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2022 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 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
- # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
18
- # All Rights Reserved
19
- #
20
- # This file may also be used under the terms of a commercial license
21
- # if purchased from OpenC3, Inc.
22
-
23
- require 'openc3/interfaces/tcpip_client_interface'
24
- require 'uuidtools'
25
-
26
- module OpenC3
27
- # TODO: Deprecated ... Will remove in next major version of COSMOS (COSMOS 6)
28
-
29
- # Interface for connecting to Ball Aerospace LINC Labview targets
30
- class LincInterface < TcpipClientInterface
31
- # The maximum number of asynchronous commands we can wait for at a time.
32
- # We don't ever expect to get close to this but we need to limit it
33
- # to ensure the Array doesn't grow out of control.
34
- MAX_CONCURRENT_HANDSHAKES = 1000
35
-
36
- def initialize(
37
- hostname,
38
- port,
39
- handshake_enabled = true,
40
- response_timeout = 5.0,
41
- read_timeout = nil,
42
- write_timeout = 5.0,
43
- length_bitoffset = 0,
44
- length_bitsize = 16,
45
- length_value_offset = 4,
46
- fieldname_guid = 'HDR_GUID',
47
- endianness = 'BIG_ENDIAN',
48
- fieldname_cmd_length = 'HDR_LENGTH'
49
- )
50
- # Initialize Super Class
51
- super(hostname, port, port, write_timeout, read_timeout, 'LENGTH',
52
- length_bitoffset, length_bitsize, length_value_offset, 1, endianness, 0, nil, nil)
53
-
54
- # Configuration Settings
55
- @handshake_enabled = ConfigParser.handle_true_false(handshake_enabled)
56
- @handshake_enableds = nil
57
- @response_timeout = response_timeout.to_f
58
- @length_value_offset = Integer(length_value_offset)
59
- @fieldname_guid = ConfigParser.handle_nil(fieldname_guid)
60
- @fieldname_cmd_length = ConfigParser.handle_nil(fieldname_cmd_length)
61
-
62
- # Other instance variables
63
- @ignored_error_codes = {}
64
- @handshake_cmds = []
65
- @handshakes_mutex = Mutex.new
66
-
67
- # Call this once now because the first time is slow
68
- UUIDTools::UUID.random_create.raw
69
- end # def initialize
70
-
71
- def connect
72
- # Packet definitions need to be retrieved here because @target_names is not filled in until after initialize
73
- unless @handshake_enableds
74
- @handshake_enableds = {}
75
- @target_names.each do |target_name|
76
- @handshake_enableds[target_name] = @handshake_enabled
77
- @ignored_error_codes[target_name] = []
78
- end
79
- end
80
- @handshake_packets = []
81
- @error_packets = []
82
- @error_ignore_commands = nil
83
- @error_handle_commands = nil
84
- @handshake_enable_commands = nil
85
- @handshake_disable_commands = nil
86
-
87
- @target_names.each do |target_name|
88
- @handshake_packets << System.telemetry.packet(target_name, 'HANDSHAKE')
89
- @error_packets << System.telemetry.packet(target_name, 'ERROR')
90
-
91
- # Handle not defining the interface configuration commands (Targets may not want to support this functionality)
92
- begin
93
- command = System.commands.packet(target_name, 'OPENC3_ERROR_IGNORE')
94
- @error_ignore_commands ||= []
95
- @error_ignore_commands << command
96
- rescue
97
- end
98
- begin
99
- command = System.commands.packet(target_name, 'OPENC3_ERROR_HANDLE')
100
- @error_handle_commands ||= []
101
- @error_handle_commands << command
102
- rescue
103
- end
104
- begin
105
- command = System.commands.packet(target_name, 'OPENC3_HANDSHAKE_EN')
106
- @handshake_enable_commands ||= []
107
- @handshake_enable_commands << command
108
- rescue
109
- end
110
- begin
111
- command = System.commands.packet(target_name, 'OPENC3_HANDSHAKE_DS')
112
- @handshake_disable_commands ||= []
113
- @handshake_disable_commands << command
114
- rescue
115
- end
116
- end
117
-
118
- @handshakes_mutex.synchronize do
119
- @handshake_cmds = []
120
- end
121
-
122
- # Actually connect
123
- super()
124
- end
125
-
126
- def write(packet)
127
- return if linc_interface_command(packet)
128
- raise "Interface not connected" unless connected?()
129
-
130
- # Add a GUID to the GUID field if its defined
131
- # A GUID means it's an asynchronous packet type.
132
- if @fieldname_guid
133
- guid = get_guid(packet)
134
- else
135
- # If @fieldname_guid is not defined (synchronous) we don't care what the
136
- # GUID is because we're not trying to match it up with anything.
137
- # As soon as we get a response we free the command.
138
- guid = 0
139
- end
140
-
141
- # Fix the length field to handle the cases where a variable length packet
142
- # is defined. OpenC3 does not do this automatically.
143
- update_length_field(packet) if @fieldname_cmd_length
144
-
145
- # Always take the mutex (even if we aren't handshaking)
146
- # We do not want any incoming telemetry to be missed because
147
- # it could be the handshake to this command.
148
- @handshakes_mutex.synchronize do
149
- super(packet) # Send the command
150
- wait_for_response(packet, guid) if @handshake_enableds[packet.target_name]
151
- end
152
- end
153
-
154
- def linc_interface_command(packet)
155
- if @error_ignore_commands
156
- @error_ignore_commands.each do |error_ignore_command|
157
- if error_ignore_command.identify?(packet.buffer(false))
158
- linc_cmd = error_ignore_command.clone
159
- linc_cmd.buffer = packet.buffer
160
- code = linc_cmd.read('CODE')
161
- @ignored_error_codes[error_ignore_command.target_name] << code unless @ignored_error_codes[error_ignore_command.target_name].include? code
162
- return true
163
- end
164
- end
165
- end
166
-
167
- if @error_handle_commands
168
- @error_handle_commands.each do |error_handle_command|
169
- if error_handle_command.identify?(packet.buffer(false))
170
- linc_cmd = error_handle_command.clone
171
- linc_cmd.buffer = packet.buffer
172
- code = linc_cmd.read('CODE')
173
- @ignored_error_codes[error_handle_command.target_name].delete(code) if @ignored_error_codes[error_handle_command.target_name].include? code
174
- return true
175
- end
176
- end
177
- end
178
-
179
- if @handshake_enable_commands
180
- @handshake_enable_commands.each do |handshake_enable_command|
181
- if handshake_enable_command.identify?(packet.buffer(false))
182
- @handshake_enabled = true
183
- @handshake_enableds[handshake_enable_command.target_name] = true
184
- return true
185
- end
186
- end
187
- end
188
-
189
- if @handshake_disable_commands
190
- @handshake_disable_commands.each do |handshake_disable_command|
191
- if handshake_disable_command.identify?(packet.buffer(false))
192
- @handshake_enabled = false
193
- @handshake_enableds[handshake_disable_command.target_name] = false
194
- return true
195
- end
196
- end
197
- end
198
-
199
- return false
200
- end
201
-
202
- def get_guid(packet)
203
- if not packet.read(@fieldname_guid) =~ /[\x01-\xFF]/
204
- # The GUID has not been set already (it has all \x00 values), so make a new one.
205
- # This enables a router GUI to make the GUIDs so it can process handshakes too.
206
- guid = UUIDTools::UUID.random_create.raw
207
- packet.write(@fieldname_guid, guid, :RAW)
208
- else
209
- guid = packet.read(@fieldname_guid)
210
- end
211
- return guid
212
- end
213
-
214
- def update_length_field(packet)
215
- length = packet.length - @length_value_offset
216
- packet.write(@fieldname_cmd_length, length, :RAW)
217
- end
218
-
219
- def wait_for_response(packet, guid)
220
- # Check the number of commands waiting for handshakes. This is just for sanity
221
- # If the number of commands waiting for handshakes is very large then it can't be real
222
- # So raise an error. Something has gone horribly wrong.
223
- if @handshake_cmds.length > MAX_CONCURRENT_HANDSHAKES
224
- len = @handshake_cmds.length
225
- @handshake_cmds = []
226
- raise "The number of commands waiting for handshakes to #{len}. Clearing all commands!"
227
- end
228
-
229
- # Create a handshake command object and add it to the list of commands waiting
230
- handshake_cmd = LincHandshakeCommand.new(@handshakes_mutex, guid)
231
- @handshake_cmds.push(handshake_cmd)
232
-
233
- # wait for that handshake. This releases the mutex so that the telemetry and other commands can start running again.
234
- timed_out = handshake_cmd.wait_for_handshake(@response_timeout)
235
- # We now have the mutex again. This interface is blocked for the rest of the command handling,
236
- # which should be quick because it's just checking variables and logging.
237
- # We want to hold the mutex during that so that the commands get logged in order of handshake from here.
238
-
239
- if timed_out
240
- # Clean this command out of the array of items that require handshakes.
241
- @handshake_cmds.delete_if { |hsc| hsc == handshake_cmd }
242
- raise "Timeout waiting for handshake from #{System.commands.format(packet, System.targets[packet.target_name].ignored_parameters)}"
243
- end
244
-
245
- process_handshake_results(handshake_cmd)
246
- rescue Exception => e
247
- # If anything goes wrong after successfully writing the packet to the LINC target
248
- # ensure that the packet gets updated in the CVT and logged to the packet log writer.
249
- # OpenC3 normally only does this if write returns successfully
250
- if packet.identified?
251
- command = System.commands.packet(packet.target_name, packet.packet_name)
252
- else
253
- command = System.commands.packet('UNKNOWN', 'UNKNOWN')
254
- end
255
- command.buffer = packet.buffer
256
-
257
- @packet_log_writer_pairs.each do |packet_log_writer_pair|
258
- packet_log_writer_pair.cmd_log_writer.write(packet)
259
- end
260
-
261
- raise e
262
- end
263
-
264
- def process_handshake_results(handshake_cmd)
265
- status = handshake_cmd.handshake.handshake.read('STATUS')
266
- code = handshake_cmd.handshake.handshake.read('CODE')
267
- source = handshake_cmd.handshake.error_source
268
-
269
- # Handle handshake warnings and errors
270
- if status == "OK" and code != 0
271
- unless @ignored_error_codes[handshake_cmd.handshake.handshake.target_name].include? code
272
- Logger.warn "#{@name}: Warning sending command (#{code}): #{source}"
273
- end
274
- elsif status == "ERROR"
275
- unless @ignored_error_codes[handshake_cmd.handshake.handshake.target_name].include? code
276
- raise "Error sending command (#{code}): #{source}"
277
- end
278
- end
279
- end
280
-
281
- def read
282
- packet = super()
283
- if packet
284
- @handshake_packets.each do |handshake_packet|
285
- if handshake_packet.identify?(packet.buffer(false))
286
- handshake_packet = handshake_packet.clone
287
- handshake_packet.buffer = packet.buffer
288
- linc_handshake = LincHandshake.new(handshake_packet, handshake_packet.target_name)
289
-
290
- # Check for a local handshake
291
- if handshake_packet.read('origin') == "LCL"
292
- handle_local_handshake(linc_handshake)
293
- else
294
- handle_remote_handshake(linc_handshake) if @handshake_enableds[handshake_packet.target_name]
295
- end # if handshake_packet.read('origin') == "LCL"
296
- end # @handshake_packet.identify?(packet.buffer(false))
297
- end
298
- end # if packet
299
-
300
- return packet
301
- end
302
-
303
- def handle_local_handshake(linc_handshake)
304
- # Update the current value table for this command
305
- command = System.commands.packet(linc_handshake.identified_command.target_name, linc_handshake.identified_command.packet_name)
306
- command.received_time = linc_handshake.identified_command.received_time
307
- command.buffer = linc_handshake.identified_command.buffer
308
- command.received_count += 1
309
-
310
- # Put a log of the command onto the server for the user to see
311
- Logger.info("#{@name}: External Command: " + System.commands.format(linc_handshake.identified_command, System.targets[linc_handshake.identified_command.target_name].ignored_parameters))
312
-
313
- # Log the command to the command log(s)
314
- @packet_log_writer_pairs.each do |packet_log_writer_pair|
315
- packet_log_writer_pair.cmd_log_writer.write(linc_handshake.identified_command)
316
- end
317
- end
318
-
319
- def handle_remote_handshake(linc_handshake)
320
- # This is a remote packet (sent from here).
321
- # Add to the array of handshake packet responses
322
- # The mutex is required by the command task due to the way it
323
- # first looks up the handshake before removing it.
324
- @handshakes_mutex.synchronize do
325
- if @fieldname_guid
326
- # A GUID means it's an asynchronous packet type.
327
- # So look at the list of incoming handshakes and pick off (deleting)
328
- # the handshake from the list if it's for this command.
329
- #
330
- # The mutex is required because the telemetry task
331
- # could enqueue a response between the index lookup and the slice
332
- # function which would remove the wrong response. FAIL!
333
-
334
- # Loop through all waiting commands to see if this handshake belongs to them
335
- this_handshake_guid = linc_handshake.get_cmd_guid(@fieldname_guid)
336
- handshake_cmd_index = @handshake_cmds.index { |hsc| hsc.get_cmd_guid == this_handshake_guid }
337
-
338
- # If command was waiting (ie the loop above found one), then remove it from waiters and signal it
339
- if handshake_cmd_index
340
- handshake_cmd = @handshake_cmds.slice!(handshake_cmd_index)
341
- handshake_cmd.got_your_handshake(linc_handshake)
342
- else
343
- # No command match found! Either it gave up and timed out or this wasn't originated from here.
344
- # Ignore this typically. This case here for clarity.
345
- end
346
-
347
- else
348
- # Synchronous version: just pop the array (pull the command off) and send it the handshake
349
- handshake_cmd = @handshakes_cmds.pop
350
- handshake_cmd.got_your_handshake(linc_handshake)
351
- end # of handshaking type check
352
- end
353
- end
354
- end # class LincInterface
355
-
356
- # The LincHandshakeCommand class is used only by the LincInterface.
357
- # It is the command with other required items that is passed to the telemetry
358
- # thread so it can match it with the handshake.
359
- class LincHandshakeCommand
360
- attr_accessor :handshake
361
-
362
- def initialize(handshakes_mutex, cmd_guid)
363
- @cmd_guid = cmd_guid
364
- @handshakes_mutex = handshakes_mutex
365
- @resource = ConditionVariable.new
366
- @handshake = nil
367
- end
368
-
369
- def wait_for_handshake(response_timeout)
370
- timed_out = false
371
-
372
- @resource.wait(@handshakes_mutex, response_timeout)
373
- if @handshake
374
- timed_out = false
375
- else
376
- Logger.warn "#{@name}: No handshake - must be timeout."
377
- timed_out = true
378
- end
379
-
380
- return timed_out
381
- end
382
-
383
- def got_your_handshake(handshake)
384
- @handshake = handshake
385
- @resource.signal
386
- end
387
-
388
- def get_cmd_guid
389
- return @cmd_guid
390
- end
391
- end # class LincHandshakeCommand
392
-
393
- # The LincHandshake class is used only by the LincInterface. It processes the handshake and
394
- # helps with finding the information regarding the internal command.
395
- class LincHandshake
396
- attr_accessor :handshake
397
- attr_accessor :identified_command
398
- attr_accessor :error_source
399
-
400
- def initialize(handshake, interface_target_name)
401
- @handshake = handshake
402
-
403
- # Interpret the command field of the handshake packet
404
- # Where DATA is defined as:
405
- # 1 byte target name length
406
- # X byte target name
407
- # 1 byte packet name length
408
- # X byte packet name
409
- # 4 byte packet data length
410
- # X byte packet data
411
- # 4 byte error source length
412
- # X byte error source
413
- data = handshake.read('DATA')
414
- raise "Data field too short for target name length" if data.length == 0
415
-
416
- # Get target name length
417
- target_name_length = data[0..0].unpack('C')[0]
418
- raise "Invalid target name length" if target_name_length == 0
419
-
420
- data = data[1..-1]
421
-
422
- # get target name
423
- raise "Data field too short for target name" if data.length < target_name_length
424
-
425
- # target_name = data[0..(target_name_length - 1)] # Unused
426
- data = data[target_name_length..-1]
427
-
428
- # get packet name length
429
- raise "Data field too short for packet name length" if data.length == 0
430
-
431
- packet_name_length = data[0..0].unpack('C')[0]
432
- raise "Invalid packet name length" if packet_name_length == 0
433
-
434
- data = data[1..-1]
435
-
436
- # get packet name
437
- raise "Data field too short for packet name" if data.length < packet_name_length
438
-
439
- packet_name = data[0..(packet_name_length - 1)]
440
- data = data[packet_name_length..-1]
441
-
442
- # get packet data length
443
- raise "Data field too short for packet data length" if data.length < 4
444
-
445
- packet_data_length = data[0..3].unpack('N')[0]
446
- raise "Invalid data length" if packet_data_length == 0
447
-
448
- data = data[4..-1]
449
-
450
- # get packet data
451
- raise "Data field too short for packet data" if data.length < packet_data_length
452
-
453
- packet_data = data[0..(packet_data_length - 1)]
454
- data = data[packet_data_length..-1]
455
-
456
- # get error source length
457
- raise "Data field too short for error source length" if data.length < 4
458
-
459
- error_source_length = data[0..3].unpack('N')[0]
460
- # note it is OK to have a 0 source length
461
- data = data[4..-1]
462
-
463
- # get error source - store on object
464
- if error_source_length > 0
465
- @error_source = data[0..(error_source_length - 1)]
466
- else
467
- @error_source = ''
468
- end
469
-
470
- # make packet - store on object as a defined packet of type command that this handshakes
471
- @identified_command = System.commands.packet(interface_target_name, packet_name).clone
472
- @identified_command.buffer = packet_data
473
- @identified_command.received_time = Time.at(handshake.read('TIME_SECONDS'), handshake.read('TIME_MICROSECONDS')).sys
474
- end
475
-
476
- def get_cmd_guid(fieldname_guid)
477
- return @identified_command.read(fieldname_guid)
478
- end
479
- end
480
- end
@@ -1,4 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- # This class is deprecated and this file exists only to satisfy existing code requiring it
4
- # TODO: Remove this in a future release