meshtastic 0.0.85 → 0.0.87
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/lib/meshtastic/mqtt.rb +5 -158
- data/lib/meshtastic/version.rb +1 -1
- data/lib/meshtastic.rb +160 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0449a6cfbd329bf29d9ab70e979f512b5804c23b042e44489ab295d99f992b43'
|
4
|
+
data.tar.gz: 89aa67df0c714ace91f3404a574e315d0ae1e515451e5f60888c7c49cf8dbc3f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e9307daac9a9237d9ed3a19cf40dc4891a8105b2864bd25d3312e0900a706c1644cc0b49c594e7589e71c7358f1b2207c593bc8383a9c2a1e7420571b09647e
|
7
|
+
data.tar.gz: 395ea2d2475432c098bc8342005f9112bd9b1783692728a6e1ca65d5872457d782747498885fd8bf0ac9c3b3b26045d9d291addd5879d1e280997446ac8b025a
|
data/lib/meshtastic/mqtt.rb
CHANGED
@@ -20,7 +20,7 @@ module Meshtastic
|
|
20
20
|
# port: 'optional - mqtt port (defaults: 1883)',
|
21
21
|
# username: 'optional - mqtt username (default: meshdev)',
|
22
22
|
# password: 'optional - (default: large4cats)',
|
23
|
-
# client_id: 'optional - client ID (default: random
|
23
|
+
# client_id: 'optional - client ID (default: random 4-byte hex string)'
|
24
24
|
# )
|
25
25
|
|
26
26
|
public_class_method def self.connect(opts = {})
|
@@ -29,7 +29,7 @@ module Meshtastic
|
|
29
29
|
port = opts[:port] ||= 1883
|
30
30
|
username = opts[:username] ||= 'meshdev'
|
31
31
|
password = opts[:password] ||= 'large4cats'
|
32
|
-
client_id = opts[:client_id] ||= SecureRandom.random_bytes(
|
32
|
+
client_id = opts[:client_id] ||= SecureRandom.random_bytes(4).unpack1('H*').to_s
|
33
33
|
|
34
34
|
MQTTClient.connect(
|
35
35
|
host: host,
|
@@ -42,137 +42,6 @@ module Meshtastic
|
|
42
42
|
raise e
|
43
43
|
end
|
44
44
|
|
45
|
-
# Supported Method Parameters::
|
46
|
-
# Meshtastic::MQQT.get_cipher_keys(
|
47
|
-
# psks: 'required - hash of channel / pre-shared key value pairs'
|
48
|
-
# )
|
49
|
-
|
50
|
-
private_class_method def self.get_cipher_keys(opts = {})
|
51
|
-
psks = opts[:psks]
|
52
|
-
|
53
|
-
psks.each_key do |key|
|
54
|
-
psk = psks[key]
|
55
|
-
padded_psk = psk.ljust(psk.length + ((4 - (psk.length % 4)) % 4), '=')
|
56
|
-
replaced_psk = padded_psk.gsub('-', '+').gsub('_', '/')
|
57
|
-
psks[key] = replaced_psk
|
58
|
-
end
|
59
|
-
|
60
|
-
psks
|
61
|
-
rescue StandardError => e
|
62
|
-
raise e
|
63
|
-
end
|
64
|
-
|
65
|
-
# Supported Method Parameters::
|
66
|
-
# Meshtastic::MQQT.decode_payload(
|
67
|
-
# payload: 'required - payload to recursively decode',
|
68
|
-
# msg_type: 'required - message type (e.g. :TEXT_MESSAGE_APP)',
|
69
|
-
# gps_metadata: 'optional - include GPS metadata in output (default: false)',
|
70
|
-
# )
|
71
|
-
|
72
|
-
public_class_method def self.decode_payload(opts = {})
|
73
|
-
payload = opts[:payload]
|
74
|
-
msg_type = opts[:msg_type]
|
75
|
-
gps_metadata = opts[:gps_metadata]
|
76
|
-
|
77
|
-
case msg_type
|
78
|
-
when :ADMIN_APP
|
79
|
-
decoder = Meshtastic::AdminMessage
|
80
|
-
when :ATAK_FORWARDER, :ATAK_PLUGIN
|
81
|
-
decoder = Meshtastic::TAKPacket
|
82
|
-
# when :AUDIO_APP
|
83
|
-
# decoder = Meshtastic::Audio
|
84
|
-
when :DETECTION_SENSOR_APP
|
85
|
-
decoder = Meshtastic::DeviceState
|
86
|
-
# when :IP_TUNNEL_APP
|
87
|
-
# decoder = Meshtastic::IpTunnel
|
88
|
-
when :MAP_REPORT_APP
|
89
|
-
decoder = Meshtastic::MapReport
|
90
|
-
# when :MAX
|
91
|
-
# decoder = Meshtastic::Max
|
92
|
-
when :NEIGHBORINFO_APP
|
93
|
-
decoder = Meshtastic::NeighborInfo
|
94
|
-
when :NODEINFO_APP
|
95
|
-
decoder = Meshtastic::User
|
96
|
-
when :PAXCOUNTER_APP
|
97
|
-
decoder = Meshtastic::Paxcount
|
98
|
-
when :POSITION_APP
|
99
|
-
decoder = Meshtastic::Position
|
100
|
-
# when :PRIVATE_APP
|
101
|
-
# decoder = Meshtastic::Private
|
102
|
-
when :RANGE_TEST_APP
|
103
|
-
# Unsure if this is the correct protobuf object
|
104
|
-
decoder = Meshtastic::FromRadio
|
105
|
-
when :REMOTE_HARDWARE_APP
|
106
|
-
decoder = Meshtastic::HardwareMessage
|
107
|
-
# when :REPLY_APP
|
108
|
-
# decoder = Meshtastic::Reply
|
109
|
-
when :ROUTING_APP
|
110
|
-
decoder = Meshtastic::Routing
|
111
|
-
when :SERIAL_APP
|
112
|
-
decoder = Meshtastic::SerialConnectionStatus
|
113
|
-
when :SIMULATOR_APP
|
114
|
-
decoder = Meshtastic::Compressed
|
115
|
-
when :STORE_FORWARD_APP
|
116
|
-
decoder = Meshtastic::StoreAndForward
|
117
|
-
when :TEXT_MESSAGE_APP, :UNKNOWN_APP
|
118
|
-
decoder = Meshtastic::Data
|
119
|
-
when :TELEMETRY_APP
|
120
|
-
decoder = Meshtastic::Telemetry
|
121
|
-
when :TRACEROUTE_APP
|
122
|
-
decoder = Meshtastic::RouteDiscovery
|
123
|
-
when :WAYPOINT_APP
|
124
|
-
decoder = Meshtastic::Waypoint
|
125
|
-
# when :ZPS_APP
|
126
|
-
# decoder = Meshtastic::Zps
|
127
|
-
else
|
128
|
-
puts "WARNING: Can't decode\n#{payload.inspect}\nw/ portnum: #{msg_type}"
|
129
|
-
return payload
|
130
|
-
end
|
131
|
-
|
132
|
-
payload = decoder.decode(payload).to_h
|
133
|
-
|
134
|
-
if payload.keys.include?(:latitude_i)
|
135
|
-
lat = payload[:latitude_i] * 0.0000001
|
136
|
-
payload[:latitude] = lat
|
137
|
-
end
|
138
|
-
|
139
|
-
if payload.keys.include?(:longitude_i)
|
140
|
-
lon = payload[:longitude_i] * 0.0000001
|
141
|
-
payload[:longitude] = lon
|
142
|
-
end
|
143
|
-
|
144
|
-
if payload.keys.include?(:macaddr)
|
145
|
-
mac_raw = payload[:macaddr]
|
146
|
-
mac_hex_arr = mac_raw.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }
|
147
|
-
mac_hex_str = mac_hex_arr.join(':')
|
148
|
-
payload[:macaddr] = mac_hex_str
|
149
|
-
end
|
150
|
-
|
151
|
-
if payload.keys.include?(:time)
|
152
|
-
time_int = payload[:time]
|
153
|
-
if time_int.is_a?(Integer)
|
154
|
-
time_utc = Time.at(time_int).utc.to_s
|
155
|
-
payload[:time_utc] = time_utc
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
if gps_metadata && payload[:latitude] && payload[:longitude]
|
160
|
-
lat = payload[:latitude]
|
161
|
-
lon = payload[:longitude]
|
162
|
-
unless lat.zero? && lon.zero?
|
163
|
-
gps_search_resp = gps_search(lat: lat, lon: lon)
|
164
|
-
payload[:gps_metadata] = gps_search_resp
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
payload
|
169
|
-
rescue Encoding::CompatibilityError,
|
170
|
-
Google::Protobuf::ParseError
|
171
|
-
payload
|
172
|
-
rescue StandardError => e
|
173
|
-
raise e
|
174
|
-
end
|
175
|
-
|
176
45
|
# Supported Method Parameters::
|
177
46
|
# Meshtastic::MQQT.subscribe(
|
178
47
|
# mqtt_obj: 'required - mqtt_obj returned from #connect method'
|
@@ -198,7 +67,7 @@ module Meshtastic
|
|
198
67
|
raise 'ERROR: psks parameter must be a hash of :channel => psk key value pairs' unless psks.is_a?(Hash)
|
199
68
|
|
200
69
|
psks[:LongFast] = public_psk if psks[:LongFast] == 'AQ=='
|
201
|
-
psks = get_cipher_keys(psks: psks)
|
70
|
+
psks = Meshtastic.get_cipher_keys(psks: psks)
|
202
71
|
|
203
72
|
qos = opts[:qos] ||= 0
|
204
73
|
json = opts[:json] ||= false
|
@@ -278,7 +147,7 @@ module Meshtastic
|
|
278
147
|
# payload = Meshtastic::Data.decode(message[:decoded][:payload]).to_h
|
279
148
|
payload = message[:decoded][:payload]
|
280
149
|
msg_type = message[:decoded][:portnum]
|
281
|
-
message[:decoded][:payload] = decode_payload(
|
150
|
+
message[:decoded][:payload] = Meshtastic.decode_payload(
|
282
151
|
payload: payload,
|
283
152
|
msg_type: msg_type,
|
284
153
|
gps_metadata: gps_metadata
|
@@ -361,6 +230,7 @@ module Meshtastic
|
|
361
230
|
topic = opts[:topic] ||= 'msh/US/2/e/LongFast/#'
|
362
231
|
opts[:via] = :mqtt
|
363
232
|
|
233
|
+
# TODO: Implement chunked message to deal with large messages
|
364
234
|
protobuf_text = Meshtastic.send_text(opts)
|
365
235
|
|
366
236
|
mqtt_obj.publish(topic, protobuf_text)
|
@@ -368,24 +238,6 @@ module Meshtastic
|
|
368
238
|
raise e
|
369
239
|
end
|
370
240
|
|
371
|
-
# Supported Method Parameters::
|
372
|
-
# mqtt_obj = Meshtastic.gps_search(
|
373
|
-
# lat: 'required - latitude float (e.g. 37.7749)',
|
374
|
-
# lon: 'required - longitude float (e.g. -122.4194)',
|
375
|
-
# )
|
376
|
-
public_class_method def self.gps_search(opts = {})
|
377
|
-
lat = opts[:lat]
|
378
|
-
lon = opts[:lon]
|
379
|
-
|
380
|
-
raise 'ERROR: Latitude and Longitude are required' unless lat && lon
|
381
|
-
|
382
|
-
gps_arr = [lat.to_f, lon.to_f]
|
383
|
-
|
384
|
-
Geocoder.search(gps_arr).first.data
|
385
|
-
rescue StandardError => e
|
386
|
-
raise e
|
387
|
-
end
|
388
|
-
|
389
241
|
# Supported Method Parameters::
|
390
242
|
# mqtt_obj = Meshtastic.disconnect(
|
391
243
|
# mqtt_obj: 'required - mqtt_obj returned from #connect method'
|
@@ -431,11 +283,6 @@ module Meshtastic
|
|
431
283
|
gps_metadata: 'optional - include GPS metadata in output (default: false)'
|
432
284
|
)
|
433
285
|
|
434
|
-
#{self}.gps_search(
|
435
|
-
lat: 'required - latitude float (e.g. 37.7749)',
|
436
|
-
lon: 'required - longitude float (e.g. -122.4194)',
|
437
|
-
)
|
438
|
-
|
439
286
|
#{self}.send_text(
|
440
287
|
mqtt_obj: 'required - mqtt_obj returned from #connect method',
|
441
288
|
from: ' required - From ID (String or Integer)',
|
data/lib/meshtastic/version.rb
CHANGED
data/lib/meshtastic.rb
CHANGED
@@ -66,12 +66,14 @@ module Meshtastic
|
|
66
66
|
public_class_method def self.send_text(opts = {})
|
67
67
|
# Send a text message to a node
|
68
68
|
from = opts[:from]
|
69
|
-
from_hex = from.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if from.is_a?(String)
|
69
|
+
# from_hex = from.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if from.is_a?(String)
|
70
|
+
from_hex = from.delete('!') if from.is_a?(String)
|
70
71
|
from = from_hex.to_i(16) if from_hex
|
71
72
|
raise 'ERROR: from parameter is required.' unless from
|
72
73
|
|
73
74
|
to = opts[:to] ||= 0xFFFFFFFF
|
74
|
-
to_hex = to.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if to.is_a?(String)
|
75
|
+
# to_hex = to.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if to.is_a?(String)
|
76
|
+
to_hex = to.delete('!') if to.is_a?(String)
|
75
77
|
to = to_hex.to_i(16) if to_hex
|
76
78
|
|
77
79
|
last_packet_id = opts[:last_packet_id] ||= 0
|
@@ -282,6 +284,26 @@ module Meshtastic
|
|
282
284
|
packet_id
|
283
285
|
end
|
284
286
|
|
287
|
+
# Supported Method Parameters::
|
288
|
+
# Meshtastic.get_cipher_keys(
|
289
|
+
# psks: 'required - hash of channel / pre-shared key value pairs'
|
290
|
+
# )
|
291
|
+
|
292
|
+
public_class_method def self.get_cipher_keys(opts = {})
|
293
|
+
psks = opts[:psks]
|
294
|
+
|
295
|
+
psks.each_key do |key|
|
296
|
+
psk = psks[key]
|
297
|
+
padded_psk = psk.ljust(psk.length + ((4 - (psk.length % 4)) % 4), '=')
|
298
|
+
replaced_psk = padded_psk.gsub('-', '+').gsub('_', '/')
|
299
|
+
psks[key] = replaced_psk
|
300
|
+
end
|
301
|
+
|
302
|
+
psks
|
303
|
+
rescue StandardError => e
|
304
|
+
raise e
|
305
|
+
end
|
306
|
+
|
285
307
|
# Supported Method Parameters::
|
286
308
|
# Meshtastic.send_to_radio(
|
287
309
|
# to_radio: 'required - ToRadio Message to Send'
|
@@ -310,6 +332,135 @@ module Meshtastic
|
|
310
332
|
raise e
|
311
333
|
end
|
312
334
|
|
335
|
+
# Supported Method Parameters::
|
336
|
+
# Meshtastic.gps_search(
|
337
|
+
# lat: 'required - latitude float (e.g. 37.7749)',
|
338
|
+
# lon: 'required - longitude float (e.g. -122.4194)',
|
339
|
+
# )
|
340
|
+
public_class_method def self.gps_search(opts = {})
|
341
|
+
lat = opts[:lat]
|
342
|
+
lon = opts[:lon]
|
343
|
+
|
344
|
+
raise 'ERROR: Latitude and Longitude are required' unless lat && lon
|
345
|
+
|
346
|
+
gps_arr = [lat.to_f, lon.to_f]
|
347
|
+
|
348
|
+
Geocoder.search(gps_arr).first.data
|
349
|
+
rescue StandardError => e
|
350
|
+
raise e
|
351
|
+
end
|
352
|
+
|
353
|
+
# Supported Method Parameters::
|
354
|
+
# Meshtastic::MQQT.decode_payload(
|
355
|
+
# payload: 'required - payload to recursively decode',
|
356
|
+
# msg_type: 'required - message type (e.g. :TEXT_MESSAGE_APP)',
|
357
|
+
# gps_metadata: 'optional - include GPS metadata in output (default: false)',
|
358
|
+
# )
|
359
|
+
|
360
|
+
public_class_method def self.decode_payload(opts = {})
|
361
|
+
payload = opts[:payload]
|
362
|
+
msg_type = opts[:msg_type]
|
363
|
+
gps_metadata = opts[:gps_metadata]
|
364
|
+
|
365
|
+
case msg_type
|
366
|
+
when :ADMIN_APP
|
367
|
+
decoder = Meshtastic::AdminMessage
|
368
|
+
when :ATAK_FORWARDER, :ATAK_PLUGIN
|
369
|
+
decoder = Meshtastic::TAKPacket
|
370
|
+
# when :AUDIO_APP
|
371
|
+
# decoder = Meshtastic::Audio
|
372
|
+
when :DETECTION_SENSOR_APP
|
373
|
+
decoder = Meshtastic::DeviceState
|
374
|
+
# when :IP_TUNNEL_APP
|
375
|
+
# decoder = Meshtastic::IpTunnel
|
376
|
+
when :MAP_REPORT_APP
|
377
|
+
decoder = Meshtastic::MapReport
|
378
|
+
# when :MAX
|
379
|
+
# decoder = Meshtastic::Max
|
380
|
+
when :NEIGHBORINFO_APP
|
381
|
+
decoder = Meshtastic::NeighborInfo
|
382
|
+
when :NODEINFO_APP
|
383
|
+
decoder = Meshtastic::User
|
384
|
+
when :PAXCOUNTER_APP
|
385
|
+
decoder = Meshtastic::Paxcount
|
386
|
+
when :POSITION_APP
|
387
|
+
decoder = Meshtastic::Position
|
388
|
+
# when :PRIVATE_APP
|
389
|
+
# decoder = Meshtastic::Private
|
390
|
+
when :RANGE_TEST_APP
|
391
|
+
# Unsure if this is the correct protobuf object
|
392
|
+
decoder = Meshtastic::FromRadio
|
393
|
+
when :REMOTE_HARDWARE_APP
|
394
|
+
decoder = Meshtastic::HardwareMessage
|
395
|
+
# when :REPLY_APP
|
396
|
+
# decoder = Meshtastic::Reply
|
397
|
+
when :ROUTING_APP
|
398
|
+
decoder = Meshtastic::Routing
|
399
|
+
when :SERIAL_APP
|
400
|
+
decoder = Meshtastic::SerialConnectionStatus
|
401
|
+
when :SIMULATOR_APP
|
402
|
+
decoder = Meshtastic::Compressed
|
403
|
+
when :STORE_FORWARD_APP
|
404
|
+
decoder = Meshtastic::StoreAndForward
|
405
|
+
when :TEXT_MESSAGE_APP, :UNKNOWN_APP
|
406
|
+
decoder = Meshtastic::Data
|
407
|
+
when :TELEMETRY_APP
|
408
|
+
decoder = Meshtastic::Telemetry
|
409
|
+
when :TRACEROUTE_APP
|
410
|
+
decoder = Meshtastic::RouteDiscovery
|
411
|
+
when :WAYPOINT_APP
|
412
|
+
decoder = Meshtastic::Waypoint
|
413
|
+
# when :ZPS_APP
|
414
|
+
# decoder = Meshtastic::Zps
|
415
|
+
else
|
416
|
+
puts "WARNING: Can't decode\n#{payload.inspect}\nw/ portnum: #{msg_type}"
|
417
|
+
return payload
|
418
|
+
end
|
419
|
+
|
420
|
+
payload = decoder.decode(payload).to_h
|
421
|
+
|
422
|
+
if payload.keys.include?(:latitude_i)
|
423
|
+
lat = payload[:latitude_i] * 0.0000001
|
424
|
+
payload[:latitude] = lat
|
425
|
+
end
|
426
|
+
|
427
|
+
if payload.keys.include?(:longitude_i)
|
428
|
+
lon = payload[:longitude_i] * 0.0000001
|
429
|
+
payload[:longitude] = lon
|
430
|
+
end
|
431
|
+
|
432
|
+
if payload.keys.include?(:macaddr)
|
433
|
+
mac_raw = payload[:macaddr]
|
434
|
+
mac_hex_arr = mac_raw.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }
|
435
|
+
mac_hex_str = mac_hex_arr.join(':')
|
436
|
+
payload[:macaddr] = mac_hex_str
|
437
|
+
end
|
438
|
+
|
439
|
+
if payload.keys.include?(:time)
|
440
|
+
time_int = payload[:time]
|
441
|
+
if time_int.is_a?(Integer)
|
442
|
+
time_utc = Time.at(time_int).utc.to_s
|
443
|
+
payload[:time_utc] = time_utc
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
if gps_metadata && payload[:latitude] && payload[:longitude]
|
448
|
+
lat = payload[:latitude]
|
449
|
+
lon = payload[:longitude]
|
450
|
+
unless lat.zero? && lon.zero?
|
451
|
+
gps_search_resp = gps_search(lat: lat, lon: lon)
|
452
|
+
payload[:gps_metadata] = gps_search_resp
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
payload
|
457
|
+
rescue Encoding::CompatibilityError,
|
458
|
+
Google::Protobuf::ParseError
|
459
|
+
payload
|
460
|
+
rescue StandardError => e
|
461
|
+
raise e
|
462
|
+
end
|
463
|
+
|
313
464
|
# Author(s):: 0day Inc. <support@0dayinc.com>
|
314
465
|
|
315
466
|
public_class_method def self.authors
|
@@ -322,5 +473,12 @@ module Meshtastic
|
|
322
473
|
|
323
474
|
public_class_method def self.help
|
324
475
|
constants.sort
|
476
|
+
|
477
|
+
# puts "USAGE:
|
478
|
+
# #{self}.gps_search(
|
479
|
+
# lat: 'required - latitude float (e.g. 37.7749)',
|
480
|
+
# lon: 'required - longitude float (e.g. -122.4194)',
|
481
|
+
# )
|
482
|
+
# "
|
325
483
|
end
|
326
484
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
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.87
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 0day Inc.
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-02-03 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bundler
|