meshtastic 0.0.84 → 0.0.86

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