meshtastic 0.0.41 → 0.0.42

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 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