meshtastic 0.0.41 → 0.0.42

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94567b95fcf287b1a47b7af7ea3efb4b6f15a5a0daf81137127b6f5dede9a8fd
4
- data.tar.gz: aa07f4271ac1cb1953492ab508f2f8f4f2c7c0c51fb306195b096b950b917c25
3
+ metadata.gz: 3ffe0a1e8528090281aedce5b132f1f57aa82db0c8c46131cff53d00004e4dcd
4
+ data.tar.gz: 56bb82c58cdcbced0c401802180931aa4625e4314e4954ab30349811a614d399
5
5
  SHA512:
6
- metadata.gz: 77093a3977ef63ad7c15d255c679771e5fe02448741147acbc608f19c057d9b9f8f47fe214e0f0a2799cca331726450f978bbda99248fb5d3f592e4d37b09a43
7
- data.tar.gz: 4c617b139c876db4b3fff9f4357fba3785972e47e88e85a9a9a1656db8c5ced40e42699b737aa7b84f3cc86ced3f66480a3def02e6e1a2272bdd23ac70d82858
6
+ metadata.gz: dd84aa7e0607992de00be53a0f8ccb2d69077004dd21ebc2838be38582064a797c0f13317c0abd375ab67199dd494640187895384ea74110c77c9b478a218654
7
+ data.tar.gz: a1135c741f44f38765421ea2020173b40395478fffdbb24da760d75f8483920f99cf2f0d110f7173fb9617e7522a644dc418f937aef79a35f1b04d89ed94737c
data/Gemfile CHANGED
@@ -13,7 +13,7 @@ gemspec
13
13
  # to review these custom flags (e.g. pg, serialport, etc).
14
14
  gem 'bundler', '>=2.5.3'
15
15
  gem 'bundle-audit', '0.1.0'
16
- gem 'geocoder', '1.8.2'
16
+ gem 'geocoder', '1.8.3'
17
17
  gem 'google-protobuf', '3.21.12'
18
18
  gem 'mqtt', '0.6.0'
19
19
  gem 'rake', '13.2.1'
@@ -21,7 +21,7 @@ gem 'rdoc', '6.6.3.1'
21
21
  gem 'rspec', '3.13.0'
22
22
  gem 'rubocop', '1.63.4'
23
23
  gem 'rubocop-rake', '0.6.0'
24
- gem 'rubocop-rspec', '2.29.1'
24
+ gem 'rubocop-rspec', '2.29.2'
25
25
  gem 'rvm', '1.11.3.9'
26
26
  gem 'tty-prompt', '0.23.1'
27
27
  gem 'yard', '0.9.36'
@@ -63,6 +63,125 @@ module Meshtastic
63
63
  raise e
64
64
  end
65
65
 
66
+ # Supported Method Parameters::
67
+ # Meshtastic::MQQT.recursively_decode_payloads(
68
+ # object: 'required - object to recursively decode',
69
+ # msg_type: 'required - message type (e.g. :TEXT_MESSAGE_APP)',
70
+ # gps_metadata: 'optional - include GPS metadata in output (default: false)'
71
+ # )
72
+
73
+ private_class_method def self.recursively_decode_payloads(opts = {})
74
+ object = opts[:object]
75
+ msg_type = opts[:msg_type]
76
+ gps_metadata = opts[:gps_metadata]
77
+
78
+ # puts "OBJECT: #{object.inspect}"
79
+ object = Meshtastic::Data.decode(object).to_h if object.is_a?(String)
80
+
81
+ object.each do |key, value|
82
+ if value.is_a?(Hash)
83
+ # Recursive call if the value is a hash
84
+ recursively_decode_payloads(object: value)
85
+ elsif value.is_a?(Array)
86
+ # Process each element if it's an array
87
+ value.each do |item|
88
+ recursively_decode_payloads(object: item) if item.is_a?(Hash)
89
+ end
90
+ end
91
+ # Check if the key matches 'payload' and decode
92
+ case key
93
+ when :latitude_i
94
+ object[:latitude] = object[:latitude_i] * 0.0000001
95
+ when :longitude_i
96
+ object[:longitude] = object[:longitude_i] * 0.0000001
97
+ when :macaddr
98
+ object[key] = object[key].bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join(':')
99
+ when :payload
100
+ case msg_type
101
+ when :ADMIN_APP
102
+ decoder = Meshtastic::AdminMessage.decode(payload)
103
+ when :ATAK_FORWARDER, :ATAK_PLUGIN
104
+ decoder = Meshtastic::TAKPacket
105
+ # when :AUDIO_APP
106
+ # decoder = Meshtastic::Audio
107
+ when :DETECTION_SENSOR_APP
108
+ decoder = Meshtastic::DeviceState
109
+ # when :IP_TUNNEL_APP
110
+ # decoder = Meshtastic::IpTunnel
111
+ when :MAP_REPORT_APP
112
+ decoder = Meshtastic::MapReport
113
+ # when :MAX
114
+ # decoder = Meshtastic::Max
115
+ when :NEIGHBORINFO_APP
116
+ decoder = Meshtastic::NeighborInfo
117
+ when :NODEINFO_APP
118
+ decoder = Meshtastic::User
119
+ when :PAXCOUNTER_APP
120
+ decoder = Meshtastic::Paxcount
121
+ when :POSITION_APP
122
+ decoder = Meshtastic::Position
123
+ # when :PRIVATE_APP
124
+ # decoder = Meshtastic::Private
125
+ when :RANGE_TEST_APP
126
+ # Unsure if this is the correct protobuf object
127
+ decoder = Meshtastic::FromRadio
128
+ when :REMOTE_HARDWARE_APP
129
+ decoder = Meshtastic::HardwareMessage
130
+ # when :REPLY_APP
131
+ # decoder = Meshtastic::Reply
132
+ when :ROUTING_APP
133
+ decoder = Meshtastic::Routing
134
+ when :SERIAL_APP
135
+ decoder = Meshtastic::SerialConnectionStatus
136
+ when :SIMULATOR_APP
137
+ decoder = Meshtastic::Compressed
138
+ when :STORE_FORWARD_APP
139
+ decoder = Meshtastic::StoreAndForward
140
+ when :TEXT_MESSAGE_APP
141
+ # Unsure if this is the correct protobuf object
142
+ # decoder = Meshtastic::MqttClientProxyMessage
143
+ decoder = Meshtastic::Data
144
+ when :TELEMETRY_APP
145
+ decoder = Meshtastic::Telemetry
146
+ when :TRACEROUTE_APP
147
+ decoder = Meshtastic::RouteDiscovery
148
+ when :UNKNOWN_APP
149
+ decoder = Meshtastic::Data.decode
150
+ when :WAYPOINT_APP
151
+ decoder = Meshtastic::Waypoint
152
+ # when :ZPS_APP
153
+ # decoder = Meshtastic::Zps
154
+ else
155
+ puts "WARNING: Unknown message type: #{msg_type}"
156
+ decoder = Meshtastic::Data.decode
157
+ end
158
+
159
+ # begin
160
+ # # If the value is base64 encoded, base64 decode and then decode
161
+ # base64_decoded_value = Base64.strict_decode64(value)
162
+ # object[key] = decoder.decode(base64_decoded_value).to_h
163
+ # rescue ArgumentError => e
164
+ # # Otherwise, just decode the value
165
+ object[key] = decoder.decode(value).to_h
166
+ # end
167
+
168
+ end
169
+
170
+ next unless gps_metadata && object[:latitude] && object[:longitude]
171
+
172
+ object[:gps_metadata] = gps_search(
173
+ lat: object[:latitude],
174
+ lon: object[:longitude]
175
+ ).first.data
176
+ end
177
+
178
+ object
179
+ rescue Google::Protobuf::ParseError
180
+ object
181
+ rescue StandardError => e
182
+ raise e
183
+ end
184
+
66
185
  # Supported Method Parameters::
67
186
  # Meshtastic::MQQT.subscribe(
68
187
  # mqtt_obj: 'required - mqtt_obj returned from #connect method'
@@ -72,7 +191,8 @@ module Meshtastic
72
191
  # psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: "AQ==" })',
73
192
  # qos: 'optional - quality of service (default: 0)',
74
193
  # filter: 'optional - comma-delimited string(s) to filter on in message (default: nil)',
75
- # gps_metadata: 'optional - include GPS metadata in output (default: false)'
194
+ # gps_metadata: 'optional - include GPS metadata in output (default: false)',
195
+ # include_raw: 'optional - include raw packet data in output (default: false)'
76
196
  # )
77
197
 
78
198
  public_class_method def self.subscribe(opts = {})
@@ -93,6 +213,7 @@ module Meshtastic
93
213
  json = opts[:json] ||= false
94
214
  filter = opts[:filter]
95
215
  gps_metadata = opts[:gps_metadata] ||= false
216
+ include_raw = opts[:include_raw] ||= false
96
217
 
97
218
  # NOTE: Use MQTT Explorer for topic discovery
98
219
  full_topic = "#{root_topic}/#{region}/#{channel}"
@@ -101,7 +222,7 @@ module Meshtastic
101
222
 
102
223
  filter_arr = filter.to_s.split(',').map(&:strip)
103
224
  mqtt_obj.get_packet do |packet_bytes|
104
- # raw_packet = packet_bytes.to_s.b
225
+ raw_packet = packet_bytes.to_s.b if include_raw
105
226
  raw_topic = packet_bytes.topic ||= ''
106
227
  raw_payload = packet_bytes.payload ||= ''
107
228
 
@@ -123,10 +244,10 @@ module Meshtastic
123
244
  message[:node_id_from] = "!#{message[:from].to_i.to_s(16)}"
124
245
  message[:node_id_to] = "!#{message[:to].to_i.to_s(16)}"
125
246
 
247
+ # If encrypted_message is not nil, then decrypt
248
+ # the message prior to decoding.
126
249
  encrypted_message = message[:encrypted]
127
- # If encrypted_message is not nil, then decrypt the message
128
250
  if encrypted_message.to_s.length.positive?
129
-
130
251
  packet_id = message[:id]
131
252
  packet_from = message[:from]
132
253
 
@@ -146,99 +267,22 @@ module Meshtastic
146
267
  cipher.iv = nonce
147
268
 
148
269
  decrypted = cipher.update(encrypted_message) + cipher.final
149
- message[:decrypted] = decrypted
270
+ message[:decoded] = Meshtastic::Data.decode(decrypted).to_h
271
+ message[:encrypted] = :decrypted
150
272
  end
151
273
 
152
274
  if message[:decoded]
275
+ # payload = Meshtastic::Data.decode(message[:decoded][:payload]).to_h
153
276
  payload = message[:decoded][:payload]
154
-
155
277
  msg_type = message[:decoded][:portnum]
156
- case msg_type
157
- when :ADMIN_APP
158
- pb_obj = Meshtastic::AdminMessage.decode(payload)
159
- when :ATAK_FORWARDER, :ATAK_PLUGIN
160
- pb_obj = Meshtastic::TAKPacket.decode(payload)
161
- # when :AUDIO_APP
162
- # pb_obj = Meshtastic::Audio.decode(payload)
163
- when :DETECTION_SENSOR_APP
164
- pb_obj = Meshtastic::DeviceState.decode(payload)
165
- # when :IP_TUNNEL_APP
166
- # pb_obj = Meshtastic::IpTunnel.decode(payload)
167
- when :MAP_REPORT_APP
168
- pb_obj = Meshtastic::MapReport.decode(payload)
169
- # when :MAX
170
- # pb_obj = Meshtastic::Max.decode(payload)
171
- when :NEIGHBORINFO_APP
172
- pb_obj = Meshtastic::NeighborInfo.decode(payload)
173
- when :NODEINFO_APP
174
- pb_obj = Meshtastic::User.decode(payload)
175
- when :PAXCOUNTER_APP
176
- pb_obj = Meshtastic::Paxcount.decode(payload)
177
- when :POSITION_APP
178
- pb_obj = Meshtastic::Position.decode(payload)
179
- # when :PRIVATE_APP
180
- # pb_obj = Meshtastic::Private.decode(payload)
181
- when :RANGE_TEST_APP
182
- # Unsure if this is the correct protobuf object
183
- pb_obj = Meshtastic::FromRadio.decode(payload)
184
- when :REMOTE_HARDWARE_APP
185
- pb_obj = Meshtastic::HardwareMessage.decode(payload)
186
- # when :REPLY_APP
187
- # pb_obj = Meshtastic::Reply.decode(payload)
188
- when :ROUTING_APP
189
- pb_obj = Meshtastic::Routing.decode(payload)
190
- when :SERIAL_APP
191
- pb_obj = Meshtastic::SerialConnectionStatus.decode(payload)
192
- when :SIMULATOR_APP,
193
- :TEXT_MESSAGE_COMPRESSED_APP
194
- # Unsure if this is the correct protobuf object
195
- # for TEXT_MESSAGE_COMPRESSED_APP
196
- pb_obj = Meshtastic::Compressed.decode(payload)
197
- when :STORE_FORWARD_APP
198
- pb_obj = Meshtastic::StoreAndForward.decode(payload)
199
- when :TEXT_MESSAGE_APP
200
- # Unsure if this is the correct protobuf object
201
- # pb_obj = Meshtastic::MqttClientProxyMessage.decode(payload)
202
- pb_obj = Meshtastic::Data.decode(payload)
203
- when :TELEMETRY_APP
204
- pb_obj = Meshtastic::Telemetry.decode(payload)
205
- when :TRACEROUTE_APP
206
- pb_obj = Meshtastic::RouteDiscovery.decode(payload)
207
- # when :UNKNOWN_APP
208
- # pb_obj = Meshtastic.Unknown.decode(payload)
209
- when :WAYPOINT_APP
210
- pb_obj = Meshtastic::Waypoint.decode(payload)
211
- # when :ZPS_APP
212
- # pb_obj = Meshtastic::Zps.decode(payload)
213
- else
214
- puts "WARNING: Unknown message type: #{msg_type}"
215
- end
216
- # Overwrite the payload with the decoded protobuf object
217
- # message[:decoded][:payload] = pb_obj.to_h unless msg_type == :TRACEROUTE_APP
218
- message[:decoded][:payload] = pb_obj.to_h
219
- if message[:decoded][:payload].keys.include?(:latitude_i) &&
220
- message[:decoded][:payload].keys.include?(:longitude_i) &&
221
- gps_metadata
222
-
223
- latitude = pb_obj.to_h[:latitude_i] * 0.0000001
224
- longitude = pb_obj.to_h[:longitude_i] * 0.0000001
225
- message[:decoded][:payload][:gps_metadata] = gps_search(
226
- lat: latitude,
227
- lon: longitude
228
- ).first.data
229
- end
230
-
231
- # If we there's a mac address, make it look like one.
232
- if message[:decoded][:payload].keys.include?(:macaddr)
233
- macaddr = message[:decoded][:payload][:macaddr]
234
- macaddr_fmt = macaddr.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join(':')
235
- message[:decoded][:payload][:macaddr] = macaddr_fmt
236
- end
237
- # puts pb_obj.public_methods
238
- # message[:decoded][:pb_obj] = pb_obj
278
+ message[:decoded][:payload] = recursively_decode_payloads(
279
+ object: payload,
280
+ msg_type: msg_type,
281
+ gps_metadata: gps_metadata
282
+ )
239
283
  end
240
284
 
241
- # message[:raw_packet] = raw_packet if block_given?
285
+ message[:raw_packet] = raw_packet if include_raw
242
286
  decoded_payload_hash[:packet] = message
243
287
  unless block_given?
244
288
  message[:stdout] = 'pretty'
@@ -249,8 +293,11 @@ module Meshtastic
249
293
  ArgumentError => e
250
294
 
251
295
  message[:decrypted] = e.message if e.message.include?('key must be')
296
+ message[:decrypted] = 'unable to decrypt - psk?' if e.message.include?('occurred during parsing')
252
297
  decoded_payload_hash[:packet] = message
253
298
  unless block_given?
299
+ puts "WARNING: #{e.inspect} - MSG IS >>>"
300
+ # puts e.backtrace
254
301
  message[:stdout] = 'inspect'
255
302
  stdout_message = decoded_payload_hash.inspect
256
303
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Meshtastic
4
- VERSION = '0.0.41'
4
+ VERSION = '0.0.42'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meshtastic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.41
4
+ version: 0.0.42
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-02 00:00:00.000000000 Z
11
+ date: 2024-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 1.8.2
47
+ version: 1.8.3
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 1.8.2
54
+ version: 1.8.3
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: google-protobuf
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -156,14 +156,14 @@ dependencies:
156
156
  requirements:
157
157
  - - '='
158
158
  - !ruby/object:Gem::Version
159
- version: 2.29.1
159
+ version: 2.29.2
160
160
  type: :runtime
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - '='
165
165
  - !ruby/object:Gem::Version
166
- version: 2.29.1
166
+ version: 2.29.2
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: rvm
169
169
  requirement: !ruby/object:Gem::Requirement