meshtastic 0.0.179 → 0.0.180

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/README.md +3 -2
  3. data/documentation/admin-channel.md +33 -0
  4. data/documentation/admin-config.md +28 -0
  5. data/documentation/admin-firmware.md +69 -0
  6. data/documentation/admin.md +2 -1
  7. data/documentation/atak.md +93 -10
  8. data/documentation/channel.md +1 -28
  9. data/documentation/config.md +1 -27
  10. data/documentation/meshtastic.md +2 -2
  11. data/lib/meshtastic/admin/channel.rb +90 -0
  12. data/lib/meshtastic/admin/config.rb +154 -0
  13. data/lib/meshtastic/admin/firmware.rb +173 -0
  14. data/lib/meshtastic/admin.rb +458 -28
  15. data/lib/meshtastic/apponly.rb +19 -7
  16. data/lib/meshtastic/atak.rb +295 -17
  17. data/lib/meshtastic/bluetooth/bluez.rb +20 -1
  18. data/lib/meshtastic/bluetooth.rb +70 -59
  19. data/lib/meshtastic/cannedmessages.rb +13 -6
  20. data/lib/meshtastic/channel.rb +3 -25
  21. data/lib/meshtastic/clientonly.rb +19 -7
  22. data/lib/meshtastic/config.rb +3 -24
  23. data/lib/meshtastic/connection_status.rb +12 -5
  24. data/lib/meshtastic/deviceonly.rb +19 -7
  25. data/lib/meshtastic/localonly.rb +19 -7
  26. data/lib/meshtastic/mesh_interface.rb +11 -0
  27. data/lib/meshtastic/module_config.rb +13 -7
  28. data/lib/meshtastic/mqtt.rb +72 -35
  29. data/lib/meshtastic/paxcount.rb +17 -6
  30. data/lib/meshtastic/portnums.rb +13 -6
  31. data/lib/meshtastic/position.rb +16 -6
  32. data/lib/meshtastic/remote_hardware.rb +27 -11
  33. data/lib/meshtastic/rtttl.rb +17 -8
  34. data/lib/meshtastic/serial.rb +81 -70
  35. data/lib/meshtastic/storeforward.rb +13 -6
  36. data/lib/meshtastic/stream_interface.rb +11 -0
  37. data/lib/meshtastic/tcp.rb +73 -22
  38. data/lib/meshtastic/telemetry.rb +15 -6
  39. data/lib/meshtastic/traceroute.rb +15 -6
  40. data/lib/meshtastic/util.rb +3 -1
  41. data/lib/meshtastic/version.rb +1 -1
  42. data/lib/meshtastic/xmodem.rb +12 -5
  43. data/lib/meshtastic.rb +22 -3
  44. data/spec/conventions_spec.rb +321 -0
  45. data/spec/lib/meshtastic/admin/channel_spec.rb +45 -0
  46. data/spec/lib/meshtastic/admin/config_spec.rb +48 -0
  47. data/spec/lib/meshtastic/admin/firmware_spec.rb +118 -0
  48. data/spec/lib/meshtastic/admin_spec.rb +40 -0
  49. data/spec/lib/meshtastic/apponly_spec.rb +1 -1
  50. data/spec/lib/meshtastic/atak_spec.rb +129 -4
  51. data/spec/lib/meshtastic/bluetooth_spec.rb +1 -1
  52. data/spec/lib/meshtastic/channel_spec.rb +2 -20
  53. data/spec/lib/meshtastic/config_spec.rb +2 -20
  54. data/spec/lib/meshtastic/connection_status_spec.rb +1 -1
  55. data/spec/lib/meshtastic/deviceonly_spec.rb +1 -1
  56. data/spec/lib/meshtastic/localonly_spec.rb +1 -1
  57. data/spec/lib/meshtastic/portnums_spec.rb +2 -2
  58. metadata +11 -1
@@ -4,10 +4,16 @@ require 'meshtastic/admin_pb'
4
4
 
5
5
  module Meshtastic
6
6
  module Admin
7
- def self.encode(opts = {})
7
+ SKIP = %i[
8
+ message serial_obj bluetooth_obj tcp_obj mqtt_obj to from channel want_ack hop_limit
9
+ want_response port_num data via psks seconds owner long_name short_name index config_type
10
+ module_config_type path node_num lat lon altitude time
11
+ ].freeze
12
+
13
+ public_class_method def self.encode(opts = {})
8
14
  message = opts[:message] || Meshtastic::AdminMessage.new
9
15
  opts.each do |key, value|
10
- next if %i[message serial_obj bluetooth_obj tcp_obj to from channel want_ack hop_limit].include?(key)
16
+ next if SKIP.include?(key)
11
17
  next unless message.respond_to?("#{key}=")
12
18
 
13
19
  message.public_send("#{key}=", value)
@@ -15,68 +21,492 @@ module Meshtastic
15
21
  message
16
22
  end
17
23
 
18
- def self.send(opts = {})
24
+ public_class_method def self.send(opts = {})
19
25
  message = encode(opts)
20
26
  data = Meshtastic::Data.new(
21
27
  portnum: :ADMIN_APP,
22
28
  payload: message.to_proto,
23
- want_response: opts.fetch(:want_response, true)
29
+ want_response: opts[:want_response] != false
24
30
  )
25
31
  Meshtastic.deliver_data(opts.merge(data: data, port_num: Meshtastic::PortNum::ADMIN_APP))
26
32
  end
27
33
 
28
- def self.reboot(opts = {})
29
- send(opts.merge(reboot_seconds: opts.fetch(:seconds, 5)))
34
+ public_class_method def self.reboot(opts = {})
35
+ send(opts.merge(reboot_seconds: opts[:seconds] || 5))
30
36
  end
31
37
 
32
- def self.shutdown(opts = {})
33
- send(opts.merge(shutdown_seconds: opts.fetch(:seconds, 5)))
38
+ public_class_method def self.shutdown(opts = {})
39
+ send(opts.merge(shutdown_seconds: opts[:seconds] || 5))
34
40
  end
35
41
 
36
- def self.set_owner(opts = {})
42
+ public_class_method def self.set_owner(opts = {})
37
43
  user = opts[:owner] || Meshtastic::User.new(long_name: opts[:long_name], short_name: opts[:short_name])
38
44
  send(opts.merge(set_owner: user))
39
45
  end
40
46
 
41
- def self.get_owner(opts = {})
47
+ public_class_method def self.get_owner(opts = {})
42
48
  send(opts.merge(get_owner_request: true))
43
49
  end
44
50
 
45
- def self.set_channel(opts = {})
46
- send(opts.merge(set_channel: opts.fetch(:channel_settings)))
51
+ public_class_method def self.set_channel(opts = {})
52
+ send(opts.merge(set_channel: opts[:channel_settings] || opts[:channel_pb]))
53
+ end
54
+
55
+ public_class_method def self.get_channel(opts = {})
56
+ index = opts[:index]
57
+ index = 0 if index.nil?
58
+ send(opts.merge(get_channel_request: index))
59
+ end
60
+
61
+ public_class_method def self.get_config(opts = {})
62
+ send(opts.merge(get_config_request: opts[:config_type] || :DEVICE_CONFIG))
63
+ end
64
+
65
+ public_class_method def self.set_config(opts = {})
66
+ send(opts.merge(set_config: opts[:config]))
67
+ end
68
+
69
+ public_class_method def self.get_module_config(opts = {})
70
+ send(opts.merge(get_module_config_request: opts[:module_config_type] || :MQTT_CONFIG))
71
+ end
72
+
73
+ public_class_method def self.set_module_config(opts = {})
74
+ send(opts.merge(set_module_config: opts[:module_config]))
75
+ end
76
+
77
+ public_class_method def self.get_canned_messages(opts = {})
78
+ send(opts.merge(get_canned_message_module_messages_request: true))
79
+ end
80
+
81
+ public_class_method def self.set_canned_messages(opts = {})
82
+ send(opts.merge(set_canned_message_module_messages: opts[:messages].to_s))
83
+ end
84
+
85
+ public_class_method def self.get_device_metadata(opts = {})
86
+ send(opts.merge(get_device_metadata_request: true))
87
+ end
88
+
89
+ public_class_method def self.get_ringtone(opts = {})
90
+ send(opts.merge(get_ringtone_request: true))
91
+ end
92
+
93
+ public_class_method def self.set_ringtone(opts = {})
94
+ send(opts.merge(set_ringtone_message: opts[:ringtone].to_s))
95
+ end
96
+
97
+ public_class_method def self.get_device_connection_status(opts = {})
98
+ send(opts.merge(get_device_connection_status_request: true))
99
+ end
100
+
101
+ public_class_method def self.get_node_remote_hardware_pins(opts = {})
102
+ send(opts.merge(get_node_remote_hardware_pins_request: true))
103
+ end
104
+
105
+ public_class_method def self.enter_dfu(opts = {})
106
+ send(opts.merge(enter_dfu_mode_request: true))
107
+ end
108
+
109
+ public_class_method def self.delete_file(opts = {})
110
+ send(opts.merge(delete_file_request: opts[:path].to_s))
111
+ end
112
+
113
+ public_class_method def self.set_scale(opts = {})
114
+ send(opts.merge(set_scale: opts[:scale].to_i))
115
+ end
116
+
117
+ public_class_method def self.backup_preferences(opts = {})
118
+ send(opts.merge(backup_preferences: opts[:location] || :FLASH))
119
+ end
120
+
121
+ public_class_method def self.restore_preferences(opts = {})
122
+ send(opts.merge(restore_preferences: opts[:location] || :FLASH))
123
+ end
124
+
125
+ public_class_method def self.remove_backup_preferences(opts = {})
126
+ send(opts.merge(remove_backup_preferences: opts[:location] || :FLASH))
127
+ end
128
+
129
+ public_class_method def self.send_input_event(opts = {})
130
+ event = opts[:event] || Meshtastic::AdminMessage::InputEvent.new(
131
+ event_code: opts[:event_code].to_i,
132
+ kb_char: opts[:kb_char].to_i,
133
+ touch_x: opts[:touch_x].to_i,
134
+ touch_y: opts[:touch_y].to_i
135
+ )
136
+ send(opts.merge(send_input_event: event))
137
+ end
138
+
139
+ public_class_method def self.set_ham_mode(opts = {})
140
+ ham = opts[:ham] || Meshtastic::HamParameters.new(
141
+ call_sign: opts[:call_sign].to_s,
142
+ tx_power: opts[:tx_power].to_i,
143
+ frequency: opts[:frequency].to_f,
144
+ short_name: opts[:short_name].to_s,
145
+ long_name: opts[:long_name].to_s
146
+ )
147
+ send(opts.merge(set_ham_mode: ham))
148
+ end
149
+
150
+ public_class_method def self.remove_by_nodenum(opts = {})
151
+ send(opts.merge(remove_by_nodenum: opts[:node_num].to_i))
152
+ end
153
+
154
+ public_class_method def self.set_favorite_node(opts = {})
155
+ send(opts.merge(set_favorite_node: opts[:node_num].to_i))
156
+ end
157
+
158
+ public_class_method def self.remove_favorite_node(opts = {})
159
+ send(opts.merge(remove_favorite_node: opts[:node_num].to_i))
160
+ end
161
+
162
+ public_class_method def self.set_fixed_position(opts = {})
163
+ position = opts[:position] || Meshtastic::Position.build(lat: opts[:lat], lon: opts[:lon], altitude: opts[:altitude])
164
+ send(opts.merge(set_fixed_position: position))
165
+ end
166
+
167
+ public_class_method def self.remove_fixed_position(opts = {})
168
+ send(opts.merge(remove_fixed_position: true))
169
+ end
170
+
171
+ public_class_method def self.set_time(opts = {})
172
+ send(opts.merge(set_time_only: opts[:time].to_i))
173
+ end
174
+
175
+ public_class_method def self.get_ui_config(opts = {})
176
+ send(opts.merge(get_ui_config_request: true))
177
+ end
178
+
179
+ public_class_method def self.store_ui_config(opts = {})
180
+ send(opts.merge(store_ui_config: opts[:ui_config]))
181
+ end
182
+
183
+ public_class_method def self.set_ignored_node(opts = {})
184
+ send(opts.merge(set_ignored_node: opts[:node_num].to_i))
185
+ end
186
+
187
+ public_class_method def self.remove_ignored_node(opts = {})
188
+ send(opts.merge(remove_ignored_node: opts[:node_num].to_i))
47
189
  end
48
190
 
49
- def self.get_channel(opts = {})
50
- send(opts.merge(get_channel_request: opts.fetch(:index, 0)))
191
+ public_class_method def self.toggle_muted_node(opts = {})
192
+ send(opts.merge(toggle_muted_node: opts[:node_num].to_i))
51
193
  end
52
194
 
53
- def self.get_config(opts = {})
54
- send(opts.merge(get_config_request: opts.fetch(:config_type, :DEVICE_CONFIG)))
195
+ public_class_method def self.begin_edit(opts = {})
196
+ send(opts.merge(begin_edit_settings: true))
55
197
  end
56
198
 
57
- def self.set_config(opts = {})
58
- send(opts.merge(set_config: opts.fetch(:config)))
199
+ public_class_method def self.commit_edit(opts = {})
200
+ send(opts.merge(commit_edit_settings: true))
59
201
  end
60
202
 
61
- def self.nodedb_reset(opts = {})
203
+ public_class_method def self.add_contact(opts = {})
204
+ send(opts.merge(add_contact: opts[:contact]))
205
+ end
206
+
207
+ public_class_method def self.key_verification(opts = {})
208
+ send(opts.merge(key_verification: opts[:key_verification]))
209
+ end
210
+
211
+ public_class_method def self.factory_reset_device(opts = {})
212
+ send(opts.merge(factory_reset_device: opts[:value] || 1))
213
+ end
214
+
215
+ public_class_method def self.factory_reset_config(opts = {})
216
+ send(opts.merge(factory_reset_config: opts[:value] || 1))
217
+ end
218
+
219
+ public_class_method def self.nodedb_reset(opts = {})
62
220
  send(opts.merge(nodedb_reset: true))
63
221
  end
64
222
 
65
- def self.authors
223
+ public_class_method def self.exit_simulator(opts = {})
224
+ send(opts.merge(exit_simulator: true))
225
+ end
226
+
227
+ public_class_method def self.sensor_config(opts = {})
228
+ send(opts.merge(sensor_config: opts[:sensor_config]))
229
+ end
230
+
231
+ public_class_method def self.lockdown_auth(opts = {})
232
+ send(opts.merge(lockdown_auth: opts[:lockdown_auth]))
233
+ end
234
+
235
+ public_class_method def self.authors
66
236
  "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
67
237
  end
68
238
 
69
- def self.help
239
+ public_class_method def self.help
70
240
  puts "USAGE:
71
- #{self}.reboot(serial_obj: serial_obj, seconds: 5)
72
- #{self}.shutdown(serial_obj: serial_obj, seconds: 5)
73
- #{self}.get_owner(serial_obj: serial_obj)
74
- #{self}.set_owner(serial_obj: serial_obj, long_name: 'Node', short_name: 'N1')
75
- #{self}.get_channel(serial_obj: serial_obj, index: 0)
76
- #{self}.get_config(serial_obj: serial_obj, config_type: :LORA_CONFIG)
77
- #{self}.nodedb_reset(serial_obj: serial_obj)
241
+ # Encode an AdminMessage from matching opts keys.
242
+ #{self}.encode(
243
+ message: 'optional - existing AdminMessage to fill instead of a new one',
244
+ session_passkey: 'optional - bytes from a prior get_*_response to authorize sets'
245
+ )
246
+
247
+ # Send an AdminMessage on ADMIN_APP over a connected transport.
248
+ #{self}.send(
249
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect',
250
+ bluetooth_obj: 'optional - BLE handle from Meshtastic::Bluetooth.connect',
251
+ tcp_obj: 'optional - TCP handle from Meshtastic::TCP.connect',
252
+ mqtt_obj: 'optional - MQTT client from Meshtastic::MQTT.connect',
253
+ want_response: 'optional - request an admin reply (default: true)'
254
+ )
255
+
256
+ # Reboot the node after a delay.
257
+ #{self}.reboot(
258
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect',
259
+ seconds: 'optional - delay before reboot in seconds (default: 5)'
260
+ )
261
+
262
+ # Shut down the node after a delay.
263
+ #{self}.shutdown(
264
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect',
265
+ seconds: 'optional - delay before shutdown in seconds (default: 5)'
266
+ )
267
+
268
+ # Set the node owner User protobuf.
269
+ #{self}.set_owner(
270
+ owner: 'optional - Meshtastic::User protobuf to send as set_owner',
271
+ long_name: 'optional - owner long name when owner is omitted',
272
+ short_name: 'optional - owner short name when owner is omitted'
273
+ )
274
+
275
+ # Request the node owner User protobuf.
276
+ #{self}.get_owner(
277
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
278
+ )
279
+
280
+ # Write a Channel protobuf to the node.
281
+ #{self}.set_channel(
282
+ channel_settings: 'optional - Meshtastic::Channel protobuf to write',
283
+ channel_pb: 'optional - Channel protobuf alias used as set_channel'
284
+ )
285
+
286
+ # Request a channel by index.
287
+ #{self}.get_channel(
288
+ index: 'optional - channel index to request (default: 0)'
289
+ )
290
+
291
+ # Request a radio Config section.
292
+ #{self}.get_config(
293
+ config_type: 'optional - AdminMessage::ConfigType such as :LORA_CONFIG'
294
+ )
295
+
296
+ # Write a Config protobuf to the node.
297
+ #{self}.set_config(
298
+ config: 'required - Meshtastic::Config protobuf to write'
299
+ )
300
+
301
+ # Request a ModuleConfig section.
302
+ #{self}.get_module_config(
303
+ module_config_type: 'optional - ModuleConfigType such as :MQTT_CONFIG'
304
+ )
305
+
306
+ # Write a ModuleConfig protobuf to the node.
307
+ #{self}.set_module_config(
308
+ module_config: 'required - Meshtastic::ModuleConfig protobuf to write'
309
+ )
310
+
311
+ # Request canned-message module strings.
312
+ #{self}.get_canned_messages(
313
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
314
+ )
315
+
316
+ # Set canned-message module strings.
317
+ #{self}.set_canned_messages(
318
+ messages: 'required - newline-separated canned message text'
319
+ )
320
+
321
+ # Request DeviceMetadata (firmware version and hardware).
322
+ #{self}.get_device_metadata(
323
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
324
+ )
325
+
326
+ # Request the RTTTL ringtone string.
327
+ #{self}.get_ringtone(
328
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
329
+ )
330
+
331
+ # Set the RTTTL ringtone string.
332
+ #{self}.set_ringtone(
333
+ ringtone: 'required - RTTTL ringtone text to store on the node'
334
+ )
335
+
336
+ # Request DeviceConnectionStatus.
337
+ #{self}.get_device_connection_status(
338
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
339
+ )
340
+
341
+ # Request remote-hardware pin definitions.
342
+ #{self}.get_node_remote_hardware_pins(
343
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
344
+ )
345
+
346
+ # Ask the node to enter DFU / UF2 mode.
347
+ #{self}.enter_dfu(
348
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
349
+ )
350
+
351
+ # Delete a file on the node filesystem.
352
+ #{self}.delete_file(
353
+ path: 'required - filesystem path on the node to delete'
354
+ )
355
+
356
+ # Set the NAU7802 scale calibration value.
357
+ #{self}.set_scale(
358
+ scale: 'required - integer scale factor for the NAU7802 module'
359
+ )
360
+
361
+ # Backup preferences to flash or SD.
362
+ #{self}.backup_preferences(
363
+ location: 'optional - :FLASH or :SD backup location (default: :FLASH)'
364
+ )
365
+
366
+ # Restore preferences from flash or SD.
367
+ #{self}.restore_preferences(
368
+ location: 'optional - :FLASH or :SD backup location (default: :FLASH)'
369
+ )
370
+
371
+ # Remove a preferences backup from flash or SD.
372
+ #{self}.remove_backup_preferences(
373
+ location: 'optional - :FLASH or :SD backup location (default: :FLASH)'
374
+ )
375
+
376
+ # Inject a device-UI input event.
377
+ #{self}.send_input_event(
378
+ event: 'optional - AdminMessage::InputEvent protobuf to send',
379
+ event_code: 'optional - input event code when event is omitted',
380
+ kb_char: 'optional - keyboard character code when event is omitted',
381
+ touch_x: 'optional - touch X coordinate when event is omitted',
382
+ touch_y: 'optional - touch Y coordinate when event is omitted'
383
+ )
384
+
385
+ # Enable ham-radio identity parameters.
386
+ #{self}.set_ham_mode(
387
+ ham: 'optional - HamParameters protobuf to send',
388
+ call_sign: 'optional - amateur callsign when ham is omitted',
389
+ tx_power: 'optional - transmit power when ham is omitted',
390
+ frequency: 'optional - frequency in MHz when ham is omitted',
391
+ short_name: 'optional - short name when ham is omitted',
392
+ long_name: 'optional - long name when ham is omitted'
393
+ )
394
+
395
+ # Remove a node from the local nodedb by number.
396
+ #{self}.remove_by_nodenum(
397
+ node_num: 'required - node number to remove from the nodedb'
398
+ )
399
+
400
+ # Mark a node as a favorite.
401
+ #{self}.set_favorite_node(
402
+ node_num: 'required - node number to mark as favorite'
403
+ )
404
+
405
+ # Clear favorite status for a node.
406
+ #{self}.remove_favorite_node(
407
+ node_num: 'required - node number to unfavorite'
408
+ )
409
+
410
+ # Set a fixed GPS position on the node.
411
+ #{self}.set_fixed_position(
412
+ position: 'optional - Meshtastic::Position protobuf to store',
413
+ lat: 'optional - latitude in decimal degrees when position is omitted',
414
+ lon: 'optional - longitude in decimal degrees when position is omitted',
415
+ altitude: 'optional - altitude in meters when position is omitted'
416
+ )
417
+
418
+ # Clear the fixed GPS position on the node.
419
+ #{self}.remove_fixed_position(
420
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
421
+ )
422
+
423
+ # Set node wall-clock time.
424
+ #{self}.set_time(
425
+ time: 'required - unix timestamp to set on the node'
426
+ )
427
+
428
+ # Request DeviceUIConfig.
429
+ #{self}.get_ui_config(
430
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
431
+ )
432
+
433
+ # Store DeviceUIConfig on the node.
434
+ #{self}.store_ui_config(
435
+ ui_config: 'required - Meshtastic::DeviceUIConfig protobuf to store'
436
+ )
437
+
438
+ # Ignore a node number.
439
+ #{self}.set_ignored_node(
440
+ node_num: 'required - node number to ignore'
441
+ )
442
+
443
+ # Stop ignoring a node number.
444
+ #{self}.remove_ignored_node(
445
+ node_num: 'required - node number to stop ignoring'
446
+ )
447
+
448
+ # Toggle mute for a node number.
449
+ #{self}.toggle_muted_node(
450
+ node_num: 'required - node number whose mute flag should toggle'
451
+ )
452
+
453
+ # Open a settings edit transaction.
454
+ #{self}.begin_edit(
455
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
456
+ )
457
+
458
+ # Commit a settings edit transaction.
459
+ #{self}.commit_edit(
460
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
461
+ )
462
+
463
+ # Add a SharedContact to the node.
464
+ #{self}.add_contact(
465
+ contact: 'required - Meshtastic::SharedContact protobuf to add'
466
+ )
467
+
468
+ # Send a KeyVerificationAdmin protobuf.
469
+ #{self}.key_verification(
470
+ key_verification: 'required - KeyVerificationAdmin protobuf to send'
471
+ )
472
+
473
+ # Factory-reset device state including BLE bonds.
474
+ #{self}.factory_reset_device(
475
+ value: 'optional - int32 factory_reset_device field (default: 1)'
476
+ )
477
+
478
+ # Factory-reset configuration only.
479
+ #{self}.factory_reset_config(
480
+ value: 'optional - int32 factory_reset_config field (default: 1)'
481
+ )
482
+
483
+ # Clear the node database.
484
+ #{self}.nodedb_reset(
485
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
486
+ )
487
+
488
+ # Exit the firmware simulator if running.
489
+ #{self}.exit_simulator(
490
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
491
+ )
492
+
493
+ # Write a SensorConfig protobuf.
494
+ #{self}.sensor_config(
495
+ sensor_config: 'required - Meshtastic::SensorConfig protobuf to write'
496
+ )
497
+
498
+ # Send lockdown authentication material.
499
+ #{self}.lockdown_auth(
500
+ lockdown_auth: 'required - Meshtastic::LockdownAuth protobuf to send'
501
+ )
502
+
503
+ # Print the AUTHOR(S) string for this module.
78
504
  #{self}.authors
79
505
  "
80
506
  end
81
507
  end
82
508
  end
509
+
510
+ require 'meshtastic/admin/firmware'
511
+ require 'meshtastic/admin/channel'
512
+ require 'meshtastic/admin/config'
@@ -4,26 +4,38 @@ require 'meshtastic/apponly_pb'
4
4
 
5
5
  module Meshtastic
6
6
  module Apponly
7
- def self.encode(opts = {})
7
+ public_class_method def self.encode(opts = {})
8
8
  set = Meshtastic::ChannelSet.new
9
9
  Array(opts[:settings]).each { |channel| set.settings << channel }
10
10
  set.lora_config = opts[:lora_config] if opts[:lora_config]
11
11
  set
12
12
  end
13
13
 
14
- def self.decode(bytes)
14
+ public_class_method def self.decode(opts = {})
15
+ bytes = opts[:bytes]
15
16
  Meshtastic::ChannelSet.decode(bytes)
16
17
  end
17
18
 
18
- def self.authors
19
+ public_class_method def self.authors
19
20
  "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
20
21
  end
21
22
 
22
- def self.help
23
- puts "USAGE:
24
- #{self}.encode(settings: [Meshtastic::ChannelSettings.new])
25
- #{self}.decode(bytes)
23
+ public_class_method def self.help
24
+ puts " USAGE:
25
+ # Run the encode class method for this module.
26
+ #{self}.encode(
27
+ settings: 'optional - value for settings passed into encode',
28
+ lora_config: 'optional - value for lora_config passed into encode'
29
+ )
30
+
31
+ # Run the decode class method for this module.
32
+ #{self}.decode(
33
+ bytes: 'optional - value for bytes passed into decode'
34
+ )
35
+
36
+ # Run the authors class method for this module.
26
37
  #{self}.authors
38
+
27
39
  "
28
40
  end
29
41
  end