meshtastic 0.0.142 → 0.0.143

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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. metadata +20 -144
  3. data/.github/workflows/main.yml +0 -27
  4. data/.gitignore +0 -29
  5. data/.rspec +0 -3
  6. data/.rubocop.yml +0 -35
  7. data/.rubocop_todo.yml +0 -134
  8. data/.ruby-gemset +0 -1
  9. data/.ruby-version +0 -1
  10. data/AUTOGEN_meshtastic_protobufs.sh +0 -28
  11. data/CHANGELOG_BETWEEN_TAGS.txt +0 -196
  12. data/CODE_OF_CONDUCT.md +0 -84
  13. data/Gemfile +0 -23
  14. data/LICENSE +0 -21
  15. data/README.md +0 -106
  16. data/Rakefile +0 -17
  17. data/bin/meshtastic_autoinc_version +0 -38
  18. data/build_meshtastic_gem.sh +0 -58
  19. data/git_commit.sh +0 -29
  20. data/lib/meshtastic/admin.rb +0 -24
  21. data/lib/meshtastic/admin_pb.rb +0 -31
  22. data/lib/meshtastic/apponly.rb +0 -24
  23. data/lib/meshtastic/apponly_pb.rb +0 -18
  24. data/lib/meshtastic/atak.rb +0 -24
  25. data/lib/meshtastic/atak_pb.rb +0 -22
  26. data/lib/meshtastic/cannedmessages.rb +0 -24
  27. data/lib/meshtastic/cannedmessages_pb.rb +0 -15
  28. data/lib/meshtastic/channel.rb +0 -24
  29. data/lib/meshtastic/channel_pb.rb +0 -18
  30. data/lib/meshtastic/clientonly.rb +0 -24
  31. data/lib/meshtastic/clientonly_pb.rb +0 -18
  32. data/lib/meshtastic/config.rb +0 -24
  33. data/lib/meshtastic/config_pb.rb +0 -42
  34. data/lib/meshtastic/connection_status.rb +0 -24
  35. data/lib/meshtastic/connection_status_pb.rb +0 -20
  36. data/lib/meshtastic/device_ui_pb.rb +0 -23
  37. data/lib/meshtastic/deviceonly.rb +0 -24
  38. data/lib/meshtastic/deviceonly_pb.rb +0 -28
  39. data/lib/meshtastic/interdevice_pb.rb +0 -17
  40. data/lib/meshtastic/localonly.rb +0 -24
  41. data/lib/meshtastic/localonly_pb.rb +0 -19
  42. data/lib/meshtastic/mesh_interface.rb +0 -596
  43. data/lib/meshtastic/mesh_pb.rb +0 -65
  44. data/lib/meshtastic/module_config.rb +0 -24
  45. data/lib/meshtastic/module_config_pb.rb +0 -36
  46. data/lib/meshtastic/mqtt.rb +0 -383
  47. data/lib/meshtastic/mqtt_pb.rb +0 -19
  48. data/lib/meshtastic/paxcount.rb +0 -24
  49. data/lib/meshtastic/paxcount_pb.rb +0 -15
  50. data/lib/meshtastic/portnums.rb +0 -24
  51. data/lib/meshtastic/portnums_pb.rb +0 -15
  52. data/lib/meshtastic/powermon_pb.rb +0 -18
  53. data/lib/meshtastic/remote_hardware.rb +0 -24
  54. data/lib/meshtastic/remote_hardware_pb.rb +0 -16
  55. data/lib/meshtastic/rtttl.rb +0 -24
  56. data/lib/meshtastic/rtttl_pb.rb +0 -15
  57. data/lib/meshtastic/serial_interface.rb +0 -550
  58. data/lib/meshtastic/storeforward.rb +0 -24
  59. data/lib/meshtastic/storeforward_pb.rb +0 -19
  60. data/lib/meshtastic/stream_interface.rb +0 -132
  61. data/lib/meshtastic/telemetry.rb +0 -24
  62. data/lib/meshtastic/telemetry_pb.rb +0 -24
  63. data/lib/meshtastic/util.rb +0 -70
  64. data/lib/meshtastic/version.rb +0 -5
  65. data/lib/meshtastic/xmodem.rb +0 -24
  66. data/lib/meshtastic/xmodem_pb.rb +0 -16
  67. data/lib/meshtastic.rb +0 -71
  68. data/lib/nanopb_pb.rb +0 -19
  69. data/meshtastic.gemspec +0 -73
  70. data/reinstall_meshtastic_gemset.sh +0 -29
  71. data/sig/meshtastic.rbs +0 -4
  72. data/spec/lib/meshtastic/admin_pb_spec.rb +0 -6
  73. data/spec/lib/meshtastic/admin_spec.rb +0 -6
  74. data/spec/lib/meshtastic/apponly_pb_spec.rb +0 -6
  75. data/spec/lib/meshtastic/apponly_spec.rb +0 -6
  76. data/spec/lib/meshtastic/atak_pb_spec.rb +0 -6
  77. data/spec/lib/meshtastic/atak_spec.rb +0 -6
  78. data/spec/lib/meshtastic/cannedmessages_pb_spec.rb +0 -6
  79. data/spec/lib/meshtastic/cannedmessages_spec.rb +0 -6
  80. data/spec/lib/meshtastic/channel_pb_spec.rb +0 -6
  81. data/spec/lib/meshtastic/channel_spec.rb +0 -6
  82. data/spec/lib/meshtastic/clientonly_pb_spec.rb +0 -6
  83. data/spec/lib/meshtastic/clientonly_spec.rb +0 -6
  84. data/spec/lib/meshtastic/config_pb_spec.rb +0 -6
  85. data/spec/lib/meshtastic/config_spec.rb +0 -6
  86. data/spec/lib/meshtastic/connection_status_pb_spec.rb +0 -6
  87. data/spec/lib/meshtastic/connection_status_spec.rb +0 -6
  88. data/spec/lib/meshtastic/device_ui_pb_spec.rb +0 -6
  89. data/spec/lib/meshtastic/deviceonly_pb_spec.rb +0 -6
  90. data/spec/lib/meshtastic/deviceonly_spec.rb +0 -6
  91. data/spec/lib/meshtastic/interdevice_pb_spec.rb +0 -6
  92. data/spec/lib/meshtastic/localonly_pb_spec.rb +0 -6
  93. data/spec/lib/meshtastic/localonly_spec.rb +0 -6
  94. data/spec/lib/meshtastic/mesh_interface_spec.rb +0 -6
  95. data/spec/lib/meshtastic/mesh_pb_spec.rb +0 -6
  96. data/spec/lib/meshtastic/module_config_pb_spec.rb +0 -6
  97. data/spec/lib/meshtastic/module_config_spec.rb +0 -6
  98. data/spec/lib/meshtastic/mqtt_pb_spec.rb +0 -6
  99. data/spec/lib/meshtastic/mqtt_spec.rb +0 -6
  100. data/spec/lib/meshtastic/paxcount_pb_spec.rb +0 -6
  101. data/spec/lib/meshtastic/paxcount_spec.rb +0 -6
  102. data/spec/lib/meshtastic/portnums_pb_spec.rb +0 -6
  103. data/spec/lib/meshtastic/portnums_spec.rb +0 -6
  104. data/spec/lib/meshtastic/powermon_pb_spec.rb +0 -6
  105. data/spec/lib/meshtastic/remote_hardware_pb_spec.rb +0 -6
  106. data/spec/lib/meshtastic/remote_hardware_spec.rb +0 -6
  107. data/spec/lib/meshtastic/rtttl_pb_spec.rb +0 -6
  108. data/spec/lib/meshtastic/rtttl_spec.rb +0 -6
  109. data/spec/lib/meshtastic/serial_interface_spec.rb +0 -6
  110. data/spec/lib/meshtastic/storeforward_pb_spec.rb +0 -6
  111. data/spec/lib/meshtastic/storeforward_spec.rb +0 -6
  112. data/spec/lib/meshtastic/stream_interface_spec.rb +0 -6
  113. data/spec/lib/meshtastic/telemetry_pb_spec.rb +0 -6
  114. data/spec/lib/meshtastic/telemetry_spec.rb +0 -6
  115. data/spec/lib/meshtastic/util_spec.rb +0 -6
  116. data/spec/lib/meshtastic/version_spec.rb +0 -17
  117. data/spec/lib/meshtastic/xmodem_pb_spec.rb +0 -6
  118. data/spec/lib/meshtastic/xmodem_spec.rb +0 -6
  119. data/spec/lib/meshtastic_spec.rb +0 -6
  120. data/spec/lib/nanopb_pb_spec.rb +0 -6
  121. data/spec/spec_helper.rb +0 -15
  122. data/upgrade_Gemfile_gems.sh +0 -21
  123. data/upgrade_gem.sh +0 -4
  124. data/upgrade_meshtastic.sh +0 -13
  125. data/upgrade_ruby.sh +0 -45
@@ -1,596 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'meshtastic/mesh_pb'
4
-
5
- # Plugin used to interact with Meshtastic nodes
6
- module Meshtastic
7
- class MeshInterface
8
- attr_accessor :acknowledgment,
9
- :config_id,
10
- :current_packet_id,
11
- :debug_out,
12
- :got_response,
13
- :failure,
14
- :heartbeat_timer,
15
- :is_connected,
16
- :is_proto,
17
- :local_channels,
18
- :mask,
19
- :metadata,
20
- :my_info,
21
- :no_nodes,
22
- :nodes,
23
- :nodes_by_num,
24
- :queue,
25
- :queue_status,
26
- :response_handlers,
27
- :timeout
28
-
29
- def initialize(opts = {})
30
- @acknowledgment = Meshtastic::Util::Acknowledgement.new
31
-
32
- @current_packet_id = generate_packet_id
33
-
34
- @debug_out = opts[:debug_out]
35
-
36
- @failure = nil
37
-
38
- @got_response = false
39
-
40
- @heartbeat_timer = nil
41
-
42
- @is_connected = true if opts[:is_connected]
43
- @is_connected = false unless opts[:is_connected] # TODO: threading.Event = threading.Event()
44
-
45
- @is_proto = true if opts[:is_proto]
46
- @is_proto = false unless opts[:is_proto]
47
-
48
- @local_channels = nil
49
-
50
- @mask = nil
51
-
52
- @metadata = Meshtastic::DeviceMetadata.new
53
-
54
- @my_info = Meshtastic::MyNodeInfo
55
-
56
- @no_nodes = true if opts[:no_nodes]
57
- @no_nodes = false unless opts[:no_nodes]
58
-
59
- @nodes = { nodes: {} }
60
-
61
- @nodes_by_num = {}
62
-
63
- @queue = {}
64
- @queue_status = Meshtastic::QueueStatus.new
65
-
66
- @response_handlers = {}
67
-
68
- @timeout = Meshtastic::Util::Timeout.new
69
-
70
- @config_id = NODELESS_WANT_CONFIG_ID if no_nodes
71
- @config_id = nil unless no_nodes
72
- rescue StandardError => e
73
- raise e
74
- end
75
-
76
- # Supported Method Parameters::
77
- # packet_id = Meshtastic.generate_packet_id(
78
- # last_packet_id: 'optional - Last Packet ID (Default: 0)'
79
- # )
80
- def generate_packet_id(opts = {})
81
- last_packet_id = opts[:last_packet_id] ||= 0
82
- last_packet_id = 0 if last_packet_id.negative?
83
-
84
- packet_id = Random.rand(0xffffffff) if last_packet_id.zero?
85
- packet_id = (last_packet_id + 1) & 0xffffffff if last_packet_id.positive?
86
-
87
- packet_id
88
- end
89
-
90
- # Supported Method Parameters::
91
- # Meshtastic.get_cipher_keys(
92
- # psks: 'required - hash of channel / pre-shared key value pairs'
93
- # )
94
-
95
- def get_cipher_keys(opts = {})
96
- psks = opts[:psks]
97
-
98
- psks.each_key do |key|
99
- psk = psks[key]
100
- padded_psk = psk.ljust(psk.length + ((4 - (psk.length % 4)) % 4), '=')
101
- replaced_psk = padded_psk.gsub('-', '+').gsub('_', '/')
102
- psks[key] = replaced_psk
103
- end
104
-
105
- psks
106
- rescue StandardError => e
107
- raise e
108
- end
109
-
110
- # Supported Method Parameters::
111
- # Meshtastic.gps_search(
112
- # lat: 'required - latitude float (e.g. 37.7749)',
113
- # lon: 'required - longitude float (e.g. -122.4194)'
114
- # )
115
- def gps_search(opts = {})
116
- lat = opts[:lat]
117
- lon = opts[:lon]
118
-
119
- raise 'ERROR: Latitude and Longitude are required' unless lat && lon
120
-
121
- gps_arr = [lat.to_f, lon.to_f]
122
-
123
- Geocoder.search(gps_arr).first.data
124
- rescue StandardError => e
125
- raise e
126
- end
127
-
128
- # Meshtastic::MeshInterface.send_to_radio(
129
- # payload: 'required - ToRadio Message to Send'
130
- # )
131
- def send_to_radio(opts = {})
132
- payload = opts[:payload]
133
-
134
- raise 'ERROR: Invalid ToRadio Message' unless payload.is_a?(Meshtastic::ToRadio)
135
-
136
- payload.to_proto
137
- rescue StandardError => e
138
- raise e
139
- end
140
-
141
- # Supported Method Parameters::
142
- # Meshtastic::MeshInterface.send_to_mqtt(
143
- # service_envelope: 'required - ServiceEnvelope Message to Send'
144
- # )
145
- def send_to_mqtt(opts = {})
146
- service_envelope = opts[:service_envelope]
147
-
148
- raise 'ERROR: Invalid ServiceEnvelope Message' unless service_envelope.is_a?(Meshtastic::ServiceEnvelope)
149
-
150
- service_envelope.to_proto
151
- rescue StandardError => e
152
- raise e
153
- end
154
-
155
- # Supported Method Parameters::
156
- # Meshtastic::Mesh.start_config(
157
- # )
158
- def start_config
159
- @my_info = nil
160
- @nodes = {}
161
- @nodes_by_num = {}
162
- @local_channels = []
163
-
164
- to_radio_start_config = Meshtastic::ToRadio.new
165
- if @config_id.nil? || !@no_nodes
166
- @config_id = Random.rand(0xFFFFFFFF)
167
- @config_id += 1 if @config_id == NODELESS_WANT_CONFIG_ID
168
- end
169
- to_radio_start_config.want_config_id = @config_id
170
- send_to_radio(payload: to_radio_start_config)
171
- rescue StandardError => e
172
- raise e
173
- end
174
-
175
- # Supported Method Parameters::
176
- # Meshtastic::Mesh.my_node_info
177
- def my_node_info
178
- mni = Meshtastic::MyNodeInfo.new
179
- mni.to_h
180
- rescue StandardError => e
181
- raise e
182
- end
183
-
184
- # Supported Method Parameters::
185
- # Meshtastic::MeshInterface.send_packet(
186
- # mesh_packet: 'required - Mesh Packet to Send',
187
- # from: 'required - From ID (String or Integer) (Default: "!00000b0b")',
188
- # to: 'optional - Destination ID (Default: "!ffffffff")',
189
- # last_packet_id: 'optional - Last Packet ID (Default: 0)',
190
- # via: 'optional - :radio || :mqtt (Default: :radio)',
191
- # channel: 'optional - Channel (Default: 0)',
192
- # want_ack: 'optional - Want Acknowledgement (Default: false)',
193
- # hop_limit: 'optional - Hop Limit (Default: 3)',
194
- # psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: "AQ==" })'
195
- # )
196
- def send_packet(opts = {})
197
- mesh_packet = opts[:mesh_packet]
198
- from = opts[:from] ||= '!00000b0b'
199
- # from_hex = from.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if from.is_a?(String)
200
- from_hex = from.delete('!') if from.is_a?(String)
201
- from = from_hex.to_i(16) if from_hex
202
- raise 'ERROR: from parameter is required.' unless from
203
-
204
- to = opts[:to] ||= '!ffffffff'
205
- # to_hex = to.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if to.is_a?(String)
206
- to_hex = to.delete('!') if to.is_a?(String)
207
- to = to_hex.to_i(16) if to_hex
208
-
209
- last_packet_id = opts[:last_packet_id] ||= 0
210
- via = opts[:via] ||= :radio
211
- channel = opts[:channel] ||= 0
212
- want_ack = opts[:want_ack] ||= false
213
- hop_limit = opts[:hop_limit] ||= 3
214
-
215
- public_psk = '1PG7OiApB1nwvP+rz05pAQ=='
216
- psks = opts[:psks] ||= { LongFast: public_psk }
217
- raise 'ERROR: psks parameter must be a hash of :channel => psk key value pairs' unless psks.is_a?(Hash)
218
-
219
- psks[:LongFast] = public_psk if psks[:LongFast] == 'AQ=='
220
-
221
- # my_info = Meshtastic::FromRadio.my_info
222
- # wait_connected if to != my_info.my_node_num && my_info.is_a(Meshtastic::Deviceonly::MyInfo)
223
-
224
- mesh_packet.from = from
225
- mesh_packet.to = to
226
- mesh_packet.channel = channel
227
- mesh_packet.want_ack = want_ack
228
- mesh_packet.hop_limit = hop_limit
229
- mesh_packet.id = generate_packet_id(last_packet_id: last_packet_id)
230
-
231
- if psks
232
- nonce_packet_id = [mesh_packet.id].pack('V').ljust(8, "\x00")
233
- nonce_from_node = [from].pack('V').ljust(8, "\x00")
234
- nonce = "#{nonce_packet_id}#{nonce_from_node}"
235
-
236
- psk = psks[psks.keys.first]
237
- dec_psk = Base64.strict_decode64(psk)
238
- cipher = OpenSSL::Cipher.new('AES-128-CTR')
239
- cipher = OpenSSL::Cipher.new('AES-256-CTR') if dec_psk.length == 32
240
- cipher.encrypt
241
- cipher.key = dec_psk
242
- cipher.iv = nonce
243
-
244
- decrypted_payload = mesh_packet.decoded.to_proto
245
- encrypted_payload = cipher.update(decrypted_payload) + cipher.final
246
-
247
- mesh_packet.encrypted = encrypted_payload
248
- end
249
- # puts mesh_packet.to_h
250
-
251
- # puts "Sending Packet via: #{via}"
252
- case via
253
- when :radio
254
- payload = Meshtastic::ToRadio.new
255
- payload.packet = mesh_packet
256
- send_to_radio(payload: payload)
257
- when :mqtt
258
- service_envelope = Meshtastic::ServiceEnvelope.new
259
- service_envelope.packet = mesh_packet
260
- # TODO: Add support for multiple PSKs by accepting channel_id
261
- service_envelope.channel_id = psks.keys.first
262
- service_envelope.gateway_id = "!#{from.to_s(16).downcase}"
263
- send_to_mqtt(service_envelope: service_envelope)
264
- else
265
- raise "ERROR: Invalid via parameter: #{via}"
266
- end
267
- rescue StandardError => e
268
- raise e
269
- end
270
-
271
- # Supported Method Parameters::
272
- # Meshtastic::MeshInterface.send_data(
273
- # from: 'required - From ID (String or Integer) (Default: "!00000b0b")',
274
- # to: 'optional - Destination ID (Default: "!ffffffff")',
275
- # last_packet_id: 'optional - Last Packet ID (Default: 0)',
276
- # via: 'optional - :radio || :mqtt (Default: :radio)',
277
- # channel: 'optional - Channel (Default: 0)',
278
- # data: 'required - Data to Send',
279
- # want_ack: 'optional - Want Acknowledgement (Default: false)',
280
- # hop_limit: 'optional - Hop Limit (Default: 3)',
281
- # port_num: 'optional - (Default: Meshtastic::PortNum::PRIVATE_APP)',
282
- # psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: "AQ==" })'
283
- # )
284
- def send_data(opts = {})
285
- # Send a text message to a node
286
- from = opts[:from] ||= '!00000b0b'
287
- # from_hex = from.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if from.is_a?(String)
288
- from_hex = from.delete('!') if from.is_a?(String)
289
- from = from_hex.to_i(16) if from_hex
290
- raise 'ERROR: from parameter is required.' unless from
291
-
292
- to = opts[:to] ||= '!ffffffff'
293
- # to_hex = to.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if to.is_a?(String)
294
- to_hex = to.delete('!') if to.is_a?(String)
295
- to = to_hex.to_i(16) if to_hex
296
-
297
- last_packet_id = opts[:last_packet_id] ||= 0
298
- via = opts[:via] ||= :radio
299
- channel = opts[:channel] ||= 0
300
- data = opts[:data]
301
- want_ack = opts[:want_ack] ||= false
302
- hop_limit = opts[:hop_limit] ||= 3
303
- port_num = opts[:port_num] ||= Meshtastic::PortNum::PRIVATE_APP
304
- max_port_num = Meshtastic::PortNum::MAX
305
- raise "ERROR: Invalid port_num" unless port_num.positive? && port_num < max_port_num
306
-
307
- public_psk = '1PG7OiApB1nwvP+rz05pAQ=='
308
- psks = opts[:psks] ||= { LongFast: public_psk }
309
- raise 'ERROR: psks parameter must be a hash of :channel => psk key value pairs' unless psks.is_a?(Hash)
310
-
311
- psks[:LongFast] = public_psk if psks[:LongFast] == 'AQ=='
312
-
313
- data_len = data.payload.length
314
- max_len = Meshtastic::Constants::DATA_PAYLOAD_LEN
315
- raise "ERROR: Data Length > #{max_len} Bytes" if data_len > max_len
316
-
317
- mesh_packet = Meshtastic::MeshPacket.new
318
- mesh_packet.decoded = data
319
-
320
- send_packet(
321
- mesh_packet: mesh_packet,
322
- from: from,
323
- to: to,
324
- last_packet_id: last_packet_id,
325
- via: via,
326
- channel: channel,
327
- want_ack: want_ack,
328
- hop_limit: hop_limit,
329
- psks: psks
330
- )
331
- rescue StandardError => e
332
- raise e
333
- end
334
-
335
- # Supported Method Parameters::
336
- # Meshtastic::MeshInterface.send_text(
337
- # from: 'required - From ID (String or Integer) (Default: "!00000b0b")',
338
- # to: 'optional - Destination ID (Default: "!ffffffff")',
339
- # last_packet_id: 'optional - Last Packet ID (Default: 0)',
340
- # via: 'optional - :radio || :mqtt (Default: :radio)',
341
- # channel: 'optional - Channel (Default: 6)',
342
- # text: 'optional - Text Message (Default: SYN)',
343
- # want_ack: 'optional - Want Acknowledgement (Default: false)',
344
- # want_response: 'optional - Want Response (Default: false)',
345
- # hop_limit: 'optional - Hop Limit (Default: 3)',
346
- # on_response: 'optional - Callback on Response',
347
- # psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: "AQ==" })'
348
- # )
349
- def send_text(opts = {})
350
- # Send a text message to a node
351
- from = opts[:from] ||= '!00000b0b'
352
- # from_hex = from.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if from.is_a?(String)
353
- from_hex = from.delete('!') if from.is_a?(String)
354
- from = from_hex.to_i(16) if from_hex
355
- raise 'ERROR: from parameter is required.' unless from
356
-
357
- to = opts[:to] ||= '!ffffffff'
358
- # to_hex = to.delete('!').bytes.map { |b| b.to_s(16).rjust(2, '0') }.join if to.is_a?(String)
359
- to_hex = to.delete('!') if to.is_a?(String)
360
- to = to_hex.to_i(16) if to_hex
361
-
362
- last_packet_id = opts[:last_packet_id] ||= 0
363
- via = opts[:via] ||= :radio
364
- channel = opts[:channel] ||= 6
365
- text = opts[:text] ||= 'SYN'
366
- want_ack = opts[:want_ack] ||= false
367
- want_response = opts[:want_response] ||= false
368
- hop_limit = opts[:hop_limit] ||= 3
369
- on_response = opts[:on_response]
370
-
371
- public_psk = '1PG7OiApB1nwvP+rz05pAQ=='
372
- psks = opts[:psks] ||= { LongFast: public_psk }
373
- raise 'ERROR: psks parameter must be a hash of :channel => psk key value pairs' unless psks.is_a?(Hash)
374
-
375
- psks[:LongFast] = public_psk if psks[:LongFast] == 'AQ=='
376
-
377
- # TODO: verify text length validity
378
- max_txt_len = Meshtastic::Constants::DATA_PAYLOAD_LEN
379
- raise "ERROR: Text Length > #{max_txt_len} Bytes" if text.length > max_txt_len
380
-
381
- port_num = Meshtastic::PortNum::TEXT_MESSAGE_APP
382
-
383
- data = Meshtastic::Data.new
384
- data.payload = text.force_encoding('ASCII-8BIT')
385
- data.portnum = port_num
386
- data.want_response = want_response
387
- # puts data.to_h
388
-
389
- send_data(
390
- from: from,
391
- to: to,
392
- last_packet_id: last_packet_id,
393
- via: via,
394
- channel: channel,
395
- data: data,
396
- want_ack: want_ack,
397
- want_response: want_response,
398
- hop_limit: hop_limit,
399
- port_num: port_num,
400
- on_response: on_response,
401
- psks: psks
402
- )
403
- rescue StandardError => e
404
- raise e
405
- end
406
-
407
- # Supported Method Parameters::
408
- # Meshtastic::MQQT.decode_payload(
409
- # payload: 'required - payload to recursively decode',
410
- # msg_type: 'required - message type (e.g. :TEXT_MESSAGE_APP)',
411
- # gps_metadata: 'optional - include GPS metadata in output (default: false)',
412
- # )
413
-
414
- def decode_payload(opts = {})
415
- payload = opts[:payload]
416
- msg_type = opts[:msg_type]
417
- gps_metadata = opts[:gps_metadata]
418
-
419
- case msg_type
420
- when :ADMIN_APP
421
- decoder = Meshtastic::AdminMessage
422
- when :ATAK_FORWARDER, :ATAK_PLUGIN
423
- decoder = Meshtastic::TAKPacket
424
- # when :AUDIO_APP
425
- # decoder = Meshtastic::Audio
426
- when :DETECTION_SENSOR_APP
427
- decoder = Meshtastic::DeviceState
428
- # when :IP_TUNNEL_APP
429
- # decoder = Meshtastic::IpTunnel
430
- when :MAP_REPORT_APP
431
- decoder = Meshtastic::MapReport
432
- # when :MAX
433
- # decoder = Meshtastic::Max
434
- when :NEIGHBORINFO_APP
435
- decoder = Meshtastic::NeighborInfo
436
- when :NODEINFO_APP
437
- decoder = Meshtastic::User
438
- when :PAXCOUNTER_APP
439
- decoder = Meshtastic::Paxcount
440
- when :POSITION_APP
441
- decoder = Meshtastic::Position
442
- # when :PRIVATE_APP
443
- # decoder = Meshtastic::Private
444
- when :RANGE_TEST_APP
445
- # Unsure if this is the correct protobuf object
446
- decoder = Meshtastic::FromRadio
447
- when :REMOTE_HARDWARE_APP
448
- decoder = Meshtastic::HardwareMessage
449
- # when :REPLY_APP
450
- # decoder = Meshtastic::Reply
451
- when :ROUTING_APP
452
- decoder = Meshtastic::Routing
453
- when :SERIAL_APP
454
- decoder = Meshtastic::SerialConnectionStatus
455
- when :SIMULATOR_APP
456
- decoder = Meshtastic::Compressed
457
- when :STORE_FORWARD_APP
458
- decoder = Meshtastic::StoreAndForward
459
- when :TELEMETRY_APP
460
- decoder = Meshtastic::Telemetry
461
- when :TEXT_MESSAGE_APP, :UNKNOWN_APP
462
- decoder = Meshtastic::Data
463
- when :TRACEROUTE_APP
464
- decoder = Meshtastic::RouteDiscovery
465
- when :WAYPOINT_APP
466
- decoder = Meshtastic::Waypoint
467
- # when :ZPS_APP
468
- # decoder = Meshtastic::Zps
469
- else
470
- puts "WARNING: Can't decode\n#{payload.inspect}\nw/ portnum: #{msg_type}"
471
- return payload
472
- end
473
-
474
- payload = decoder.decode(payload).to_h
475
-
476
- if payload.keys.include?(:latitude_i)
477
- lat = payload[:latitude_i] * 0.0000001
478
- payload[:latitude] = lat
479
- end
480
-
481
- if payload.keys.include?(:longitude_i)
482
- lon = payload[:longitude_i] * 0.0000001
483
- payload[:longitude] = lon
484
- end
485
-
486
- if payload.keys.include?(:macaddr)
487
- mac_raw = payload[:macaddr]
488
- mac_hex_arr = mac_raw.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }
489
- mac_hex_str = mac_hex_arr.join(':')
490
- payload[:macaddr] = mac_hex_str
491
- end
492
-
493
- if payload.keys.include?(:public_key)
494
- public_key_raw = payload[:public_key]
495
- payload[:public_key] = Base64.strict_encode64(public_key_raw)
496
- end
497
-
498
- if payload.keys.include?(:time)
499
- time_int = payload[:time]
500
- if time_int.is_a?(Integer)
501
- time_utc = Time.at(time_int).utc.to_s
502
- payload[:time_utc] = time_utc
503
- end
504
- end
505
-
506
- if gps_metadata && payload[:latitude] && payload[:longitude]
507
- lat = payload[:latitude]
508
- lon = payload[:longitude]
509
- unless lat.zero? && lon.zero?
510
- gps_search_resp = gps_search(lat: lat, lon: lon)
511
- payload[:gps_metadata] = gps_search_resp
512
- end
513
- end
514
-
515
- payload
516
- rescue Encoding::CompatibilityError,
517
- Google::Protobuf::ParseError
518
- payload
519
- rescue StandardError => e
520
- raise e
521
- end
522
-
523
- # Author(s):: 0day Inc. <support@0dayinc.com>
524
-
525
- def authors
526
- "AUTHOR(S):
527
- 0day Inc. <support@0dayinc.com>
528
- "
529
- end
530
-
531
- # Display Usage for this Module
532
-
533
- def help
534
- puts "USAGE:
535
- #{self}.send_to_radio(
536
- payload: 'required - ToRadio Message to Send'
537
- )
538
-
539
- #{self}.send_to_mqtt(
540
- service_envelope: 'required - ServiceEnvelope Message to Send'
541
- )
542
-
543
- #{self}.start_config
544
-
545
- #{self}.my_node_info
546
-
547
- #{self}.send_packet(
548
- mesh_packet: 'required - Mesh Packet to Send',
549
- from: 'required - From ID (String or Integer) (Default: \"!00000b0b\")',
550
- to: 'optional - Destination ID (Default: \"!ffffffff\")',
551
- last_packet_id: 'optional - Last Packet ID (Default: 0)',
552
- via: 'optional - :radio || :mqtt (Default: :radio)',
553
- channel: 'optional - Channel (Default: 0)',
554
- want_ack: 'optional - Want Acknowledgement (Default: false)',
555
- hop_limit: 'optional - Hop Limit (Default: 3)',
556
- psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: \"AQ==\" })'
557
- )
558
-
559
- #{self}.send_data(
560
- from: 'required - From ID (String or Integer) (Default: \"!00000b0b\")',
561
- to: 'optional - Destination ID (Default: \"!ffffffff\")',
562
- last_packet_id: 'optional - Last Packet ID (Default: 0)',
563
- via: 'optional - :radio || :mqtt (Default: :radio)',
564
- channel: 'optional - Channel (Default: 0)',
565
- data: 'required - Data to Send',
566
- want_ack: 'optional - Want Acknowledgement (Default: false)',
567
- hop_limit: 'optional - Hop Limit (Default: 3)',
568
- port_num: 'optional - (Default: Meshtastic::PortNum::PRIVATE_APP)',
569
- psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: \"AQ==\" })'
570
- )
571
-
572
- #{self}.send_text(
573
- from: 'required - From ID (String or Integer) (Default: \"!00000b0b\")',
574
- to: 'optional - Destination ID (Default: \"!ffffffff\")',
575
- last_packet_id: 'optional - Last Packet ID (Default: 0)',
576
- via: 'optional - :radio || :mqtt (Default: :radio)',
577
- channel: 'optional - Channel (Default: 6)',
578
- text: 'optional - Text Message (Default: SYN)',
579
- want_ack: 'optional - Want Acknowledgement (Default: false)',
580
- want_response: 'optional - Want Response (Default: false)',
581
- hop_limit: 'optional - Hop Limit (Default: 3)',
582
- on_response: 'optional - Callback on Response',
583
- psks: 'optional - hash of :channel => psk key value pairs (default: { LongFast: \"AQ==\" })'
584
- )
585
-
586
- #{self}.decode_payload(
587
- payload: 'required - payload to recursively decode',
588
- msg_type: 'required - message type (e.g. :TEXT_MESSAGE_APP)',
589
- gps_metadata: 'optional - include GPS metadata in output (default: false)',
590
- )
591
-
592
- #{self}.authors
593
- "
594
- end
595
- end
596
- end