meshtastic 0.0.50 → 0.0.52
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 +4 -2
- data/lib/meshtastic/version.rb +1 -1
- data/lib/meshtastic.rb +85 -46
- 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: 5656d74b5db708a5326543863dcbedc9fa101d7a61e8fd3d0136f095ab108ab4
|
4
|
+
data.tar.gz: f18672f97ef7721d575ab07bd5e7cf019c38b11bf6486a132b35264ab8fdc978
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3eb1b0c0484564d25a9eafba5ab9a281bbab340e09472d9e3e9a173f9bea7d3d1cd65f173af5397cb54e6705b2d576638f80c3c96d5b95e958317e4ec5b751b
|
7
|
+
data.tar.gz: 5a8f975dd695e868569daa7d45c954f422d970becbfd42ed2ebc96b038b3056d9638c4c14f56ea1db2f72e7bea22d589026b17973027816f6b212a1a4526f7f0
|
data/lib/meshtastic/mqtt.rb
CHANGED
@@ -248,7 +248,9 @@ module Meshtastic
|
|
248
248
|
# If encrypted_message is not nil, then decrypt
|
249
249
|
# the message prior to decoding.
|
250
250
|
encrypted_message = message[:encrypted]
|
251
|
-
if encrypted_message.to_s.length.positive?
|
251
|
+
if encrypted_message.to_s.length.positive? &&
|
252
|
+
message[:topic]
|
253
|
+
|
252
254
|
packet_id = message[:id]
|
253
255
|
packet_from = message[:from]
|
254
256
|
|
@@ -257,7 +259,7 @@ module Meshtastic
|
|
257
259
|
nonce = "#{nonce_packet_id}#{nonce_from_node}".b
|
258
260
|
|
259
261
|
psk = psks[:LongFast]
|
260
|
-
target_channel =
|
262
|
+
target_channel = message[:topic].split('/')[-2].to_sym
|
261
263
|
psk = psks[target_channel] if psks.keys.include?(target_channel)
|
262
264
|
dec_psk = Base64.strict_decode64(psk)
|
263
265
|
|
data/lib/meshtastic/version.rb
CHANGED
data/lib/meshtastic.rb
CHANGED
@@ -51,26 +51,40 @@ module Meshtastic
|
|
51
51
|
|
52
52
|
# Supported Method Parameters::
|
53
53
|
# Meshtastic.send_text(
|
54
|
-
#
|
55
|
-
#
|
54
|
+
# from: 'required - From ID (String or Integer)',
|
55
|
+
# to: 'optional - Destination ID (Default: 0xFFFFFFFF)',
|
56
|
+
# channel: 'optional - Channel ID (Default: 0)',
|
56
57
|
# text: 'optional - Text Message (Default: SYN)',
|
57
58
|
# want_ack: 'optional - Want Acknowledgement (Default: false)',
|
58
59
|
# want_response: 'optional - Want Response (Default: false)',
|
59
60
|
# hop_limit: 'optional - Hop Limit (Default: 3)',
|
60
61
|
# on_response: 'optional - Callback on Response',
|
61
|
-
#
|
62
|
+
# psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: "AQ==" })'
|
62
63
|
# )
|
63
64
|
public_class_method def self.send_text(opts = {})
|
64
65
|
# Send a text message to a node
|
65
|
-
|
66
|
-
|
66
|
+
from = opts[:from]
|
67
|
+
from_hex = from.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if from.is_a?(String)
|
68
|
+
from = from_hex.to_i(16) if from_hex
|
69
|
+
raise 'ERROR: from parameter is required.' unless from
|
70
|
+
|
71
|
+
to = opts[:to] ||= 0xFFFFFFFF
|
72
|
+
to_hex = to.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if to.is_a?(String)
|
73
|
+
to = to_hex.to_i(16) if to_hex
|
74
|
+
|
75
|
+
channel = opts[:channel] ||= 0
|
67
76
|
text = opts[:text] ||= 'SYN'
|
68
77
|
want_ack = opts[:want_ack] ||= false
|
69
78
|
want_response = opts[:want_response] ||= false
|
70
79
|
hop_limit = opts[:hop_limit] ||= 3
|
71
80
|
on_response = opts[:on_response]
|
72
|
-
|
73
|
-
|
81
|
+
|
82
|
+
public_psk = '1PG7OiApB1nwvP+rz05pAQ=='
|
83
|
+
psks = opts[:psks] ||= { LongFast: public_psk }
|
84
|
+
raise 'ERROR: psks parameter must be a hash of :channel => psk key value pairs' unless psks.is_a?(Hash)
|
85
|
+
|
86
|
+
psks[:LongFast] = public_psk if psks[:LongFast] == 'AQ=='
|
87
|
+
|
74
88
|
# TODO: verify text length validity
|
75
89
|
max_txt_len = Meshtastic::Constants::DATA_PAYLOAD_LEN
|
76
90
|
raise "ERROR: Text Length > #{max_txt_len} Bytes" if text.length > max_txt_len
|
@@ -84,15 +98,16 @@ module Meshtastic
|
|
84
98
|
puts data.to_h
|
85
99
|
|
86
100
|
send_data(
|
87
|
-
|
88
|
-
|
101
|
+
from: from,
|
102
|
+
to: to,
|
103
|
+
channel: channel,
|
89
104
|
data: data,
|
90
105
|
want_ack: want_ack,
|
91
106
|
want_response: want_response,
|
92
107
|
hop_limit: hop_limit,
|
93
108
|
port_num: port_num,
|
94
109
|
on_response: on_response,
|
95
|
-
|
110
|
+
psks: psks
|
96
111
|
)
|
97
112
|
rescue StandardError => e
|
98
113
|
raise e
|
@@ -100,18 +115,27 @@ module Meshtastic
|
|
100
115
|
|
101
116
|
# Supported Method Parameters::
|
102
117
|
# Meshtastic.send_data(
|
103
|
-
#
|
104
|
-
#
|
118
|
+
# from: 'required - From ID (String or Integer)',
|
119
|
+
# to: 'optional - Destination ID (Default: 0xFFFFFFFF)',
|
120
|
+
# channel: 'optional - Channel ID (Default: 0)',
|
105
121
|
# data: 'required - Data to Send',
|
106
122
|
# want_ack: 'optional - Want Acknowledgement (Default: false)',
|
107
123
|
# hop_limit: 'optional - Hop Limit (Default: 3)',
|
108
124
|
# port_num: 'optional - (Default: Meshtastic::PortNum::PRIVATE_APP)',
|
109
|
-
#
|
125
|
+
# psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: "AQ==" })'
|
110
126
|
# )
|
111
127
|
public_class_method def self.send_data(opts = {})
|
112
128
|
# Send a text message to a node
|
113
|
-
|
114
|
-
|
129
|
+
from = opts[:from]
|
130
|
+
from_hex = from.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if from.is_a?(String)
|
131
|
+
from = from_hex.to_i(16) if from_hex
|
132
|
+
raise 'ERROR: from parameter is required.' unless from
|
133
|
+
|
134
|
+
to = opts[:to] ||= 0xFFFFFFFF
|
135
|
+
to_hex = to.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if to.is_a?(String)
|
136
|
+
to = to_hex.to_i(16) if to_hex
|
137
|
+
|
138
|
+
channel = opts[:channel] ||= 0
|
115
139
|
data = opts[:data]
|
116
140
|
want_ack = opts[:want_ack] ||= false
|
117
141
|
hop_limit = opts[:hop_limit] ||= 3
|
@@ -119,7 +143,11 @@ module Meshtastic
|
|
119
143
|
max_port_num = Meshtastic::PortNum::MAX
|
120
144
|
raise "ERROR: Invalid port_num" unless port_num.positive? && port_num < max_port_num
|
121
145
|
|
122
|
-
|
146
|
+
public_psk = '1PG7OiApB1nwvP+rz05pAQ=='
|
147
|
+
psks = opts[:psks] ||= { LongFast: public_psk }
|
148
|
+
raise 'ERROR: psks parameter must be a hash of :channel => psk key value pairs' unless psks.is_a?(Hash)
|
149
|
+
|
150
|
+
psks[:LongFast] = public_psk if psks[:LongFast] == 'AQ=='
|
123
151
|
|
124
152
|
data_len = data.payload.length
|
125
153
|
max_len = Meshtastic::Constants::DATA_PAYLOAD_LEN
|
@@ -130,11 +158,12 @@ module Meshtastic
|
|
130
158
|
|
131
159
|
send_packet(
|
132
160
|
mesh_packet: mesh_packet,
|
133
|
-
|
134
|
-
|
161
|
+
from: from,
|
162
|
+
to: to,
|
163
|
+
channel: channel,
|
135
164
|
want_ack: want_ack,
|
136
165
|
hop_limit: hop_limit,
|
137
|
-
|
166
|
+
psks: psks
|
138
167
|
)
|
139
168
|
rescue StandardError => e
|
140
169
|
raise e
|
@@ -143,39 +172,52 @@ module Meshtastic
|
|
143
172
|
# Supported Method Parameters::
|
144
173
|
# Meshtastic.send_packet(
|
145
174
|
# mesh_packet: 'required - Mesh Packet to Send',
|
146
|
-
#
|
147
|
-
#
|
175
|
+
# from: 'required - From ID (String or Integer)',
|
176
|
+
# to: 'optional - Destination ID (Default: 0xFFFFFFFF)',
|
177
|
+
# channel: 'optional - Channel ID (Default: 0)',
|
148
178
|
# want_ack: 'optional - Want Acknowledgement (Default: false)',
|
149
179
|
# hop_limit: 'optional - Hop Limit (Default: 3)',
|
150
|
-
#
|
180
|
+
# psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: "AQ==" })'
|
151
181
|
# )
|
152
182
|
public_class_method def self.send_packet(opts = {})
|
153
183
|
mesh_packet = opts[:mesh_packet]
|
154
|
-
|
155
|
-
|
184
|
+
from = opts[:from]
|
185
|
+
from_hex = from.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if from.is_a?(String)
|
186
|
+
from = from_hex.to_i(16) if from_hex
|
187
|
+
raise 'ERROR: from parameter is required.' unless from
|
188
|
+
|
189
|
+
to = opts[:to] ||= 0xFFFFFFFF
|
190
|
+
to_hex = to.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if to.is_a?(String)
|
191
|
+
to = to_hex.to_i(16) if to_hex
|
192
|
+
|
193
|
+
channel = opts[:channel] ||= 0
|
156
194
|
want_ack = opts[:want_ack] ||= false
|
157
195
|
hop_limit = opts[:hop_limit] ||= 3
|
158
|
-
|
196
|
+
|
197
|
+
public_psk = '1PG7OiApB1nwvP+rz05pAQ=='
|
198
|
+
psks = opts[:psks] ||= { LongFast: public_psk }
|
199
|
+
raise 'ERROR: psks parameter must be a hash of :channel => psk key value pairs' unless psks.is_a?(Hash)
|
200
|
+
|
201
|
+
psks[:LongFast] = public_psk if psks[:LongFast] == 'AQ=='
|
159
202
|
|
160
203
|
# my_info = Meshtastic::FromRadio.my_info
|
161
|
-
# wait_connected if
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
mesh_packet.from = from_id
|
168
|
-
mesh_packet.to = node_num
|
204
|
+
# wait_connected if to != my_info.my_node_num && my_info.is_a(Meshtastic::Deviceonly::MyInfo)
|
205
|
+
|
206
|
+
mesh_packet.from = from
|
207
|
+
mesh_packet.to = to
|
208
|
+
mesh_packet.channel = channel
|
169
209
|
mesh_packet.want_ack = want_ack
|
170
210
|
mesh_packet.hop_limit = hop_limit
|
171
|
-
|
172
211
|
mesh_packet.id = generate_packet_id if mesh_packet.id.zero?
|
212
|
+
# mesh_packet.channel_id = psks.keys.first
|
213
|
+
# mesh_packet.gateway_id = "!#{from.to_s(16).downcase}"
|
173
214
|
|
174
|
-
if
|
215
|
+
if psks
|
175
216
|
nonce_packet_id = [mesh_packet.id].pack('V').ljust(8, "\x00")
|
176
|
-
nonce_from_node = [
|
217
|
+
nonce_from_node = [from].pack('V').ljust(8, "\x00")
|
177
218
|
nonce = "#{nonce_packet_id}#{nonce_from_node}".b
|
178
219
|
|
220
|
+
psk = psks[psks.keys.first]
|
179
221
|
dec_psk = Base64.strict_decode64(psk)
|
180
222
|
cipher = OpenSSL::Cipher.new('AES-128-CTR')
|
181
223
|
cipher = OpenSSL::Cipher.new('AES-256-CTR') if dec_psk.length == 32
|
@@ -183,18 +225,17 @@ module Meshtastic
|
|
183
225
|
cipher.key = dec_psk
|
184
226
|
cipher.iv = nonce
|
185
227
|
|
186
|
-
decrypted_payload = mesh_packet.decoded.
|
228
|
+
decrypted_payload = mesh_packet.decoded.to_proto
|
187
229
|
encrypted_payload = cipher.update(decrypted_payload) + cipher.final
|
188
230
|
|
189
231
|
mesh_packet.encrypted = encrypted_payload
|
190
232
|
end
|
191
|
-
|
233
|
+
puts mesh_packet.to_h
|
192
234
|
|
193
|
-
|
194
|
-
|
195
|
-
# send_to_radio(to_radio: to_radio)
|
235
|
+
to_radio = Meshtastic::ToRadio.new
|
236
|
+
to_radio.packet = mesh_packet
|
196
237
|
|
197
|
-
|
238
|
+
send_to_radio(to_radio: to_radio)
|
198
239
|
rescue StandardError => e
|
199
240
|
raise e
|
200
241
|
end
|
@@ -205,11 +246,9 @@ module Meshtastic
|
|
205
246
|
# )
|
206
247
|
public_class_method def self.generate_packet_id(opts = {})
|
207
248
|
last_packet_id = opts[:last_packet_id] ||= 0
|
249
|
+
last_packet_id = 0 if last_packet_id.negative?
|
208
250
|
|
209
|
-
|
210
|
-
packet_id = rand(2**32) if last_packet_id.zero?
|
211
|
-
|
212
|
-
packet_id
|
251
|
+
(last_packet_id + 1) & 0xffffffff
|
213
252
|
end
|
214
253
|
|
215
254
|
# Supported Method Parameters::
|
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.52
|
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-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|