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 +4 -4
- data/Gemfile +2 -2
- data/lib/meshtastic/mqtt.rb +137 -90
- data/lib/meshtastic/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ffe0a1e8528090281aedce5b132f1f57aa82db0c8c46131cff53d00004e4dcd
|
4
|
+
data.tar.gz: 56bb82c58cdcbced0c401802180931aa4625e4314e4954ab30349811a614d399
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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'
|
data/lib/meshtastic/mqtt.rb
CHANGED
@@ -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
|
-
|
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[:
|
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
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
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
|
-
|
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
|
data/lib/meshtastic/version.rb
CHANGED
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
166
|
+
version: 2.29.2
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
168
|
name: rvm
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|