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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42efdc0a59eb1689c3af8632b8191e6dc8d51b9f77002b55d4d19ca24e4bede3
4
- data.tar.gz: 922d1701b6c2a21ecae7d722980630af3b811516df17db57e4611367a1576fec
3
+ metadata.gz: '0449a6cfbd329bf29d9ab70e979f512b5804c23b042e44489ab295d99f992b43'
4
+ data.tar.gz: 89aa67df0c714ace91f3404a574e315d0ae1e515451e5f60888c7c49cf8dbc3f
5
5
  SHA512:
6
- metadata.gz: d9dcb14d2c91bd9f89edef65450b2f2f638efd61a4803ff801753f4d15a153c572f22686ed093c51c4f12d291553a115dbde568398dda46401554383ca0c0e80
7
- data.tar.gz: a12152be4af332268f73072201b391711ad4762730fae08845f26d3947feea8a63dcb527bfb1c734e64a6ba80a4ea38dec7bc1a2a4b804a9c3e1d3cf09348935
6
+ metadata.gz: 6e9307daac9a9237d9ed3a19cf40dc4891a8105b2864bd25d3312e0900a706c1644cc0b49c594e7589e71c7358f1b2207c593bc8383a9c2a1e7420571b09647e
7
+ data.tar.gz: 395ea2d2475432c098bc8342005f9112bd9b1783692728a6e1ca65d5872457d782747498885fd8bf0ac9c3b3b26045d9d291addd5879d1e280997446ac8b025a
@@ -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 8-byte hex string)'
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(8).unpack1('H*')
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)',
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Meshtastic
4
- VERSION = '0.0.85'
4
+ VERSION = '0.0.87'
5
5
  end
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.85
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-01-31 00:00:00.000000000 Z
10
+ date: 2025-02-03 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bundler