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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3fa03c5234c1b6d136fca93a0a37a5c9dd6588b116b6f932f457f4e139eee89c
4
- data.tar.gz: 54d66239895c5989f8f8ee5423e63d05769bdecd6281d59d914b31561177fabd
3
+ metadata.gz: f12d73c0e68d9f1171a2b92d2cfe2277d22e4e78c7c33788cc52924ee6d40778
4
+ data.tar.gz: b0be149633c2a659dcea3ce83546f9a2ea5121f632a90bb3ee9b21a43ae79221
5
5
  SHA512:
6
- metadata.gz: fd7705cf063ef5448b167dc7d3f1664dea20cc25ff1b1791a72de2e4a656afc11ef5717969b4171f65736448616e05f985a9a5c40dc11196559b9767a2b5b286
7
- data.tar.gz: 506c41dfa105d57a5fae6febd3fa9748f30319c1a280f0ebbc5412d1bfd8b9f9330c337aba25033ee06e9fbc10fa4c600a28cecd61baab145422ec02162df238
6
+ metadata.gz: a4d41dbc793a0eb380cbfb815ce9cd15ac98802e80a3903ea7ed765d09c42ff9a4009a2d68ff44338026e553f18fd7d96d4419233018185ff3f733735b033149
7
+ data.tar.gz: d035c8f9c42d536ad97bdefc0de870dff4694ef651c86dd1e7002ada63145f089e9e70a74d73144ebac991d0d9dd8365f5c53ae0b0b6154c466d99f849e4b34a
@@ -28,8 +28,9 @@ Do not open Serial and Bluetooth to the same radio at once. Always `disconnect`
28
28
  ## Feature modules
29
29
 
30
30
  - [Meshtastic::Admin](admin.md)
31
- - [Meshtastic::Channel](channel.md)
32
- - [Meshtastic::Config](config.md)
31
+ - [Meshtastic::Admin::Channel](admin-channel.md)
32
+ - [Meshtastic::Admin::Config](admin-config.md)
33
+ - [Meshtastic::Admin::Firmware](admin-firmware.md)
33
34
  - [Meshtastic::ModuleConfig](module-config.md)
34
35
  - [Meshtastic::Position](position.md)
35
36
  - [Meshtastic::Telemetry](telemetry.md)
@@ -0,0 +1,33 @@
1
+ # Meshtastic::Admin::Channel
2
+
3
+ Admin get/set for mesh channels. The generated protobuf remains `Meshtastic::Channel`; this module talks to the node on `ADMIN_APP`.
4
+
5
+ Roles: `:PRIMARY`, `:SECONDARY`, `:DISABLED`.
6
+
7
+ ## Methods
8
+
9
+ - `build_settings` — `ChannelSettings` (name, psk, uplink/downlink, AEAD)
10
+ - `build` — `Channel` (index, role, settings)
11
+ - `get(index:)` — `get_channel_request`
12
+ - `set` — `set_channel` with a Channel protobuf
13
+ - `help` / `authors`
14
+
15
+ Do not pass a Channel protobuf as MeshInterface `channel:` (that field is the numeric channel index). This module strips that key before send.
16
+
17
+ ## Example
18
+
19
+ ```ruby
20
+ settings = Meshtastic::Admin::Channel.build_settings(name: 'LongFast', uplink_enabled: true)
21
+ Meshtastic::Admin::Channel.set(
22
+ serial_obj: serial_obj,
23
+ index: 0,
24
+ role: :PRIMARY,
25
+ settings: settings
26
+ )
27
+ Meshtastic::Admin::Channel.get(serial_obj: serial_obj, index: 0)
28
+ ```
29
+
30
+ ## Related
31
+
32
+ - [Meshtastic::Admin](admin.md)
33
+ - [Meshtastic::Admin::Config](admin-config.md)
@@ -0,0 +1,28 @@
1
+ # Meshtastic::Admin::Config
2
+
3
+ Admin get/set for radio `Meshtastic::Config` sections. The generated protobuf remains `Meshtastic::Config`.
4
+
5
+ ## Methods
6
+
7
+ - `get(config_type:)` — default `:DEVICE_CONFIG`
8
+ - `set(config:)`
9
+ - Named getters: `get_device`, `get_position`, `get_power`, `get_network`, `get_display`, `get_lora`, `get_bluetooth`, `get_security`, `get_sessionkey`, `get_device_ui`
10
+ - `set_device(device:)`, `set_lora(lora:)`
11
+ - `help` / `authors`
12
+
13
+ `config_type` values: `:DEVICE_CONFIG`, `:POSITION_CONFIG`, `:POWER_CONFIG`, `:NETWORK_CONFIG`, `:DISPLAY_CONFIG`, `:LORA_CONFIG`, `:BLUETOOTH_CONFIG`, `:SECURITY_CONFIG`, `:SESSIONKEY_CONFIG`, `:DEVICEUI_CONFIG`.
14
+
15
+ ## Example
16
+
17
+ ```ruby
18
+ Meshtastic::Admin::Config.get_lora(serial_obj: serial_obj)
19
+
20
+ config = Meshtastic::Config.new
21
+ config.device = Meshtastic::Config::DeviceConfig.new(role: :CLIENT)
22
+ Meshtastic::Admin::Config.set(serial_obj: serial_obj, config: config)
23
+ ```
24
+
25
+ ## Related
26
+
27
+ - [Meshtastic::Admin](admin.md)
28
+ - [Meshtastic::Admin::Channel](admin-channel.md)
@@ -0,0 +1,69 @@
1
+ # Meshtastic::Admin::Firmware
2
+
3
+ Install Meshtastic firmware using the PhoneAPI / admin path (not esptool). Nested under [Admin](admin.md) because OTA is an `AdminMessage`.
4
+
5
+ ## What it does
6
+
7
+ 1. SHA-256 the image (`-update.bin` for ESP32 BLE/WiFi OTA).
8
+ 2. Send `ota_request` (`OTAEvent`: 32-byte hash + `:OTA_BLE` or `:OTA_WIFI`) on `ADMIN_APP`.
9
+ 3. On serial / TCP / Bluetooth, stream the image as `ToRadio.xmodemPacket` (SOH 128-byte blocks, CRC16, EOT). MQTT has no PhoneAPI XModem; it only publishes the admin `ota_request` so the node can reboot into OTA.
10
+
11
+ `enter_dfu` sends `enter_dfu_mode_request` (nRF52 USB UF2 / serial DFU). `reboot_ota(seconds:)` is the older `reboot_ota_seconds` field.
12
+
13
+ Use a firmware file that matches the board. Interrupting a flash can brick the radio. Keep battery high.
14
+
15
+ This is not the web flasher / `esptool` USB bootloader path, and not nRF `.zip` via `adafruit-nrfutil`.
16
+
17
+ ## Methods
18
+
19
+ - `install(firmware:, mode:, serial_obj: | tcp_obj: | bluetooth_obj: | mqtt_obj:)`
20
+ - `request_ota` — admin hash + mode only
21
+ - `enter_dfu`
22
+ - `reboot_ota(seconds: 10)`
23
+ - `xmodem_blocks(bytes)` / `send_xmodem(xmodem:)`
24
+ - `sha256`
25
+ - `help` / `authors`
26
+
27
+ `mode:` is `:OTA_BLE` or `:OTA_WIFI`. `firmware:` is a path; `bytes:` is raw image bytes.
28
+
29
+ ## Serial / TCP / Bluetooth
30
+
31
+ ```ruby
32
+ Meshtastic::Admin::Firmware.install(
33
+ serial_obj: serial_obj,
34
+ firmware: 'firmware-heltec-v3-update.bin',
35
+ mode: :OTA_BLE
36
+ )
37
+
38
+ Meshtastic::Admin::Firmware.install(
39
+ tcp_obj: tcp_obj,
40
+ firmware: 'firmware-heltec-v3-update.bin',
41
+ mode: :OTA_WIFI
42
+ )
43
+
44
+ Meshtastic::Admin::Firmware.install(
45
+ bluetooth_obj: bluetooth_obj,
46
+ firmware: 'firmware-heltec-v3-update.bin',
47
+ mode: :OTA_BLE
48
+ )
49
+ ```
50
+
51
+ ## MQTT (remote admin)
52
+
53
+ Publishes one encrypted `ADMIN_APP` envelope. The node must accept remote admin. It does not push XModem over the broker.
54
+
55
+ ```ruby
56
+ Meshtastic::Admin::Firmware.install(
57
+ mqtt_obj: mqtt_obj,
58
+ firmware: 'firmware-heltec-v3-update.bin',
59
+ mode: :OTA_WIFI,
60
+ to: '!aabbccdd',
61
+ psks: { LongFast: 'AQ==' }
62
+ )
63
+ ```
64
+
65
+ ## Related
66
+
67
+ - [Meshtastic::Admin](admin.md)
68
+ - [Meshtastic::Xmodem](xmodem.md)
69
+ - [Meshtastic::MQTT](mqtt.md)
@@ -1,6 +1,6 @@
1
1
  # Meshtastic::Admin
2
2
 
3
- Builds `Meshtastic::AdminMessage` and sends it on `ADMIN_APP` (port 6) through [Meshtastic.deliver_data](meshtastic.md). Pass a connected `serial_obj`, `bluetooth_obj`, or `tcp_obj`.
3
+ Builds `Meshtastic::AdminMessage` and sends it on `ADMIN_APP` (port 6) through [Meshtastic.deliver_data](meshtastic.md). Pass a connected `serial_obj`, `bluetooth_obj`, `tcp_obj`, or `mqtt_obj`.
4
4
 
5
5
  Responses come back as `FromRadio` packets on the same transport (`subscribe` / `recv_from_radio`).
6
6
 
@@ -48,6 +48,7 @@ Meshtastic::Admin.send(
48
48
 
49
49
  ## Related
50
50
 
51
+ - [Meshtastic::Admin::Firmware](admin-firmware.md)
51
52
  - [Meshtastic::Channel](channel.md)
52
53
  - [Meshtastic::Config](config.md)
53
54
  - [Meshtastic::ModuleConfig](module-config.md)
@@ -1,27 +1,110 @@
1
1
  # Meshtastic::ATAK
2
2
 
3
- Encodes `Meshtastic::TAKPacket` and sends it on `ATAK_PLUGIN` (port 72).
3
+ TAK / ATAK over Meshtastic. Three wire formats, same as the official clients:
4
+
5
+ | Format | Port | Payload |
6
+ | --- | --- | --- |
7
+ | V1 `ATAK_PLUGIN` | 72 | Bare `TAKPacket` (PLI, GeoChat, optional `detail` bytes) |
8
+ | V2 `ATAK_PLUGIN_V2` | 78 | `[flags][TAKPacketV2]`. This gem emits uncompressed frames (`flags=0xFF`) |
9
+ | V1 `ATAK_FORWARDER` | 257 | zlib-compressed CoT XML (single packet, max `DATA_PAYLOAD_LEN`) |
10
+
11
+ V2 typed payloads: GeoChat, aircraft, shapes, markers, range-and-bearing, routes, CASEVAC, emergency, task, TAKTALK, raw detail. Contact / group / status on V1; callsign / team / role / lat-lon on V2.
12
+
13
+ Firmware ≥ 2.8.0 speaks V2. Older radios use V1 PLI/chat, and generic CoT on the forwarder port.
14
+
15
+ Compressed V2 (zstd dictionary id 0 or 1) is not unpacked here; `decode_v2` raises unless `flags=0xFF`.
4
16
 
5
17
  ## Methods
6
18
 
7
- - `encode(is_compressed:, chat:, message:)` — `message:` builds a `GeoChat`
8
- - `send`
19
+ - `encode` / `encode_v1` — `TAKPacket`
20
+ - `send` / `send_v1` / `send_chat` / `send_pli` — port 72
21
+ - `build_v2` / `encode_v2` / `wrap_v2` / `decode_v2` / `send_v2` — port 78
22
+ - `compress_cot` / `decompress_cot` / `send_cot` — port 257 (`cot:` XML string)
23
+ - `decode(payload:, portnum:)` — dispatches on port
9
24
  - `help` / `authors`
10
25
 
11
- ## Example
26
+ `lat` / `lon` are decimal degrees (stored × 1e7). Pass a connected `serial_obj`, `bluetooth_obj`, or `tcp_obj`.
27
+
28
+ ## V1 GeoChat and PLI
12
29
 
13
30
  ```ruby
14
- Meshtastic::ATAK.send(
31
+ Meshtastic::ATAK.send_chat(
32
+ serial_obj: serial_obj,
33
+ message: 'ATAK chat',
34
+ to: 'ANDROID-aabbccdd',
35
+ callsign: 'ALPHA',
36
+ device_callsign: 'RADIO-1',
37
+ team: :Cyan,
38
+ role: :TeamMember,
39
+ battery: 87
40
+ )
41
+
42
+ Meshtastic::ATAK.send_pli(
43
+ serial_obj: serial_obj,
44
+ lat: 37.7749,
45
+ lon: -122.4194,
46
+ altitude: 10,
47
+ speed: 0,
48
+ course: 90,
49
+ callsign: 'ALPHA',
50
+ team: :Cyan
51
+ )
52
+ ```
53
+
54
+ ## V2 typed events
55
+
56
+ ```ruby
57
+ Meshtastic::ATAK.send_v2(serial_obj: serial_obj, message: 'v2 chat', callsign: 'ALPHA')
58
+
59
+ Meshtastic::ATAK.send_v2(
15
60
  serial_obj: serial_obj,
16
- message: 'ATAK chat'
61
+ callsign: 'ALPHA',
62
+ lat: 37.7749,
63
+ lon: -122.4194,
64
+ aircraft: Meshtastic::AircraftTrack.new(icao: 'ABC123', flight: 'N1')
17
65
  )
18
66
 
19
- packet = Meshtastic::ATAK.encode(message: 'ATAK chat')
20
- packet.chat.message # => "ATAK chat"
67
+ Meshtastic::ATAK.send_v2(serial_obj: serial_obj, shape: Meshtastic::DrawnShape.new(kind: :Kind_Circle, major_cm: 1000))
68
+ Meshtastic::ATAK.send_v2(serial_obj: serial_obj, marker: Meshtastic::Marker.new(kind: :Kind_Spot))
69
+ Meshtastic::ATAK.send_v2(serial_obj: serial_obj, route: Meshtastic::Route.new(prefix: 'R1'))
70
+ Meshtastic::ATAK.send_v2(serial_obj: serial_obj, casevac: Meshtastic::CasevacReport.new(title: 'CASEVAC'))
71
+ Meshtastic::ATAK.send_v2(serial_obj: serial_obj, emergency: Meshtastic::EmergencyAlert.new(type: :Type_Alert911))
72
+ Meshtastic::ATAK.send_v2(serial_obj: serial_obj, task: Meshtastic::TaskRequest.new(task_type: 'recon'))
73
+ Meshtastic::ATAK.send_v2(serial_obj: serial_obj, taktalk: Meshtastic::TakTalkMessage.new(text: 'hi', chatroom_id: 'room1'))
21
74
  ```
22
75
 
23
- Related protobufs: `TAKPacket`, `GeoChat`, `Contact`, `Group`, `PLI`, `TAKPacketV2`. See [protobufs.md](protobufs.md).
76
+ Receive V2:
77
+
78
+ ```ruby
79
+ Meshtastic::Serial.subscribe(serial_obj: serial_obj, include: 'ATAK_PLUGIN') do |message|
80
+ port = message.dig(:packet, :decoded, :portnum)
81
+ payload = message.dig(:packet, :decoded, :payload)
82
+ decoded = Meshtastic::ATAK.decode(payload: payload, portnum: port)
83
+ p decoded
84
+ end
85
+ ```
86
+
87
+ ## Generic CoT (forwarder)
88
+
89
+ ```ruby
90
+ Meshtastic::ATAK.send_cot(
91
+ serial_obj: serial_obj,
92
+ cot: '<event type="b-m-p-s-m" uid="marker-1"><point lat="37.77" lon="-122.41"/></event>'
93
+ )
94
+ ```
95
+
96
+ Raises if zlib output exceeds `Meshtastic::Constants::DATA_PAYLOAD_LEN`. Multi-packet fountain (FTN) is not implemented; keep CoT small or use V2 typed payloads.
97
+
98
+ ## Radio TAK module
99
+
100
+ Device role `TAK` / `TAK_TRACKER` and Module Config → TAK (`team` / `role`) are [Admin](admin.md) / [ModuleConfig](module-config.md), not this client:
101
+
102
+ ```ruby
103
+ Meshtastic::ModuleConfig.get(serial_obj: serial_obj, module_config_type: :TAK_CONFIG)
104
+ ```
24
105
 
25
106
  ## Related
26
107
 
27
- - [Meshtastic::ModuleConfig](module-config.md) (`:TAK_CONFIG`)
108
+ - [Meshtastic::ModuleConfig](module-config.md)
109
+ - [Generated protobuf types](protobufs.md)
110
+ - [TAK wire formats](https://meshtastic.org/docs/software/apple/developer/tak-protocol/)
@@ -1,30 +1,3 @@
1
1
  # Meshtastic::Channel
2
2
 
3
- Reopens the generated `Meshtastic::Channel` protobuf class with get/set helpers that call [Admin](admin.md).
4
-
5
- This is a protobuf class, not a Ruby module. Do not add class methods named `send` or `encode`.
6
-
7
- ## Methods
8
-
9
- - `get(serial_obj:, index:)` — `get_channel_request`
10
- - `set(serial_obj:, channel:)` — `set_channel`
11
- - `help` / `authors`
12
-
13
- Also all protobuf instance fields: `index`, `settings` (`ChannelSettings`), `role` (`:DISABLED`, `:PRIMARY`, `:SECONDARY`).
14
-
15
- ## Example
16
-
17
- ```ruby
18
- Meshtastic::Channel.get(serial_obj: serial_obj, index: 0)
19
-
20
- settings = Meshtastic::ChannelSettings.new(name: 'LongFast', psk: "\x01")
21
- channel = Meshtastic::Channel.new(index: 0, settings: settings, role: :PRIMARY)
22
- Meshtastic::Channel.set(serial_obj: serial_obj, channel: channel)
23
- ```
24
-
25
- Listen for `ADMIN_APP` replies on the same transport.
26
-
27
- ## Related
28
-
29
- - [Meshtastic::Admin](admin.md)
30
- - [Meshtastic::Apponly](apponly.md) (`ChannelSet`)
3
+ Generated protobuf (`index`, `settings`, `role`). Get/set on a live node is [Meshtastic::Admin::Channel](admin-channel.md).
@@ -1,29 +1,3 @@
1
1
  # Meshtastic::Config
2
2
 
3
- Reopens the generated `Meshtastic::Config` protobuf class. Get/set go through [Admin](admin.md).
4
-
5
- ## Methods
6
-
7
- - `get(serial_obj:, config_type: :DEVICE_CONFIG)`
8
- - `set(serial_obj:, config:)` — `config` is a `Meshtastic::Config`
9
- - `help` / `authors`
10
-
11
- Protobuf oneofs include `device`, `position`, `power`, `network`, `display`, `lora`, `bluetooth`, `security`, `sessionkey`, `device_ui`.
12
-
13
- ## Example
14
-
15
- ```ruby
16
- Meshtastic::Config.get(serial_obj: serial_obj, config_type: :LORA_CONFIG)
17
-
18
- config = Meshtastic::Config.new
19
- config.device = Meshtastic::Config::DeviceConfig.new(role: :CLIENT)
20
- Meshtastic::Config.set(serial_obj: serial_obj, config: config)
21
- ```
22
-
23
- `config_type` list: [Admin](admin.md).
24
-
25
- ## Related
26
-
27
- - [Meshtastic::Admin](admin.md)
28
- - [Meshtastic::ModuleConfig](module-config.md)
29
- - [Meshtastic::Localonly](localonly.md)
3
+ Generated protobuf (device, position, power, network, display, lora, bluetooth, security, sessionkey, device_ui). Get/set on a live node is [Meshtastic::Admin::Config](admin-config.md).
@@ -31,13 +31,13 @@ Routes a `Meshtastic::Data` payload to a connected radio.
31
31
 
32
32
  ```ruby
33
33
  Meshtastic.deliver_data(
34
- serial_obj: serial_obj, # or bluetooth_obj: or tcp_obj:
34
+ serial_obj: serial_obj, # or bluetooth_obj: / tcp_obj: / mqtt_obj:
35
35
  data: Meshtastic::Data.new(portnum: :TEXT_MESSAGE_APP, payload: 'hi'),
36
36
  port_num: Meshtastic::PortNum::TEXT_MESSAGE_APP
37
37
  )
38
38
  ```
39
39
 
40
- Raises `ArgumentError` unless `data` is a `Meshtastic::Data` and one of `serial_obj`, `bluetooth_obj`, or `tcp_obj` is present.
40
+ Raises `ArgumentError` unless `data` is a `Meshtastic::Data` and one of `serial_obj`, `bluetooth_obj`, `tcp_obj`, or `mqtt_obj` is present.
41
41
 
42
42
  ## Related
43
43
 
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'meshtastic/channel_pb'
4
+
5
+ module Meshtastic
6
+ module Admin
7
+ module Channel
8
+ public_class_method def self.build_settings(opts = {})
9
+ settings = opts[:settings] || Meshtastic::ChannelSettings.new
10
+ settings.name = opts[:name].to_s if opts[:name]
11
+ settings.psk = opts[:psk] if opts[:psk]
12
+ settings.channel_num = opts[:channel_num].to_i if opts[:channel_num]
13
+ settings.id = opts[:id].to_i if opts[:id]
14
+ settings.uplink_enabled = opts[:uplink_enabled] unless opts[:uplink_enabled].nil?
15
+ settings.downlink_enabled = opts[:downlink_enabled] unless opts[:downlink_enabled].nil?
16
+ settings.module_settings = opts[:module_settings] if opts[:module_settings]
17
+ settings.use_aead = opts[:use_aead] unless opts[:use_aead].nil?
18
+ settings
19
+ end
20
+
21
+ public_class_method def self.build(opts = {})
22
+ channel = opts[:channel] || Meshtastic::Channel.new
23
+ channel.index = opts[:index].to_i if opts[:index]
24
+ channel.role = opts[:role] if opts[:role]
25
+ channel.settings = opts[:settings] || build_settings(opts.merge({}))
26
+ channel
27
+ end
28
+
29
+ public_class_method def self.get(opts = {})
30
+ index = opts[:index]
31
+ index = 0 if index.nil?
32
+ Admin.get_channel(opts.merge(index: index))
33
+ end
34
+
35
+ public_class_method def self.set(opts = {})
36
+ channel = opts[:channel] || build(opts.merge({}))
37
+ merged = opts.merge(channel_settings: channel)
38
+ merged.delete(:channel)
39
+ Admin.set_channel(merged)
40
+ end
41
+
42
+ public_class_method def self.authors
43
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
44
+ end
45
+
46
+ public_class_method def self.help
47
+ puts "USAGE:
48
+ # Build ChannelSettings for a mesh channel.
49
+ #{self}.build_settings(
50
+ settings: 'optional - existing ChannelSettings protobuf to fill',
51
+ name: 'optional - channel name such as LongFast',
52
+ psk: 'optional - raw PSK bytes for the channel',
53
+ channel_num: 'optional - LoRa channel number',
54
+ id: 'optional - channel hash id',
55
+ uplink_enabled: 'optional - whether MQTT uplink is enabled',
56
+ downlink_enabled: 'optional - whether MQTT downlink is enabled',
57
+ module_settings: 'optional - ModuleSettings protobuf',
58
+ use_aead: 'optional - whether AEAD crypto is enabled'
59
+ )
60
+
61
+ # Build a Channel protobuf with index, role, and settings.
62
+ #{self}.build(
63
+ channel: 'optional - existing Channel protobuf to fill',
64
+ index: 'optional - channel slot index on the node',
65
+ role: 'optional - :PRIMARY, :SECONDARY, or :DISABLED',
66
+ settings: 'optional - ChannelSettings protobuf to attach'
67
+ )
68
+
69
+ # Request a channel slot from the node.
70
+ #{self}.get(
71
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect',
72
+ index: 'optional - channel slot index to request (default: 0)'
73
+ )
74
+
75
+ # Write a channel slot on the node.
76
+ #{self}.set(
77
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect',
78
+ channel: 'optional - Channel protobuf to write',
79
+ index: 'optional - channel slot index when building a channel',
80
+ role: 'optional - :PRIMARY, :SECONDARY, or :DISABLED',
81
+ settings: 'optional - ChannelSettings protobuf to attach'
82
+ )
83
+
84
+ # Print the AUTHOR(S) string for this module.
85
+ #{self}.authors
86
+ "
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'meshtastic/config_pb'
4
+
5
+ module Meshtastic
6
+ module Admin
7
+ module Config
8
+ public_class_method def self.get(opts = {})
9
+ Admin.get_config(opts.merge(config_type: opts[:config_type] || :DEVICE_CONFIG))
10
+ end
11
+
12
+ public_class_method def self.set(opts = {})
13
+ Admin.set_config(opts.merge(config: opts[:config]))
14
+ end
15
+
16
+ public_class_method def self.get_device(opts = {})
17
+ get(opts.merge(config_type: :DEVICE_CONFIG))
18
+ end
19
+
20
+ public_class_method def self.get_position(opts = {})
21
+ get(opts.merge(config_type: :POSITION_CONFIG))
22
+ end
23
+
24
+ public_class_method def self.get_power(opts = {})
25
+ get(opts.merge(config_type: :POWER_CONFIG))
26
+ end
27
+
28
+ public_class_method def self.get_network(opts = {})
29
+ get(opts.merge(config_type: :NETWORK_CONFIG))
30
+ end
31
+
32
+ public_class_method def self.get_display(opts = {})
33
+ get(opts.merge(config_type: :DISPLAY_CONFIG))
34
+ end
35
+
36
+ public_class_method def self.get_lora(opts = {})
37
+ get(opts.merge(config_type: :LORA_CONFIG))
38
+ end
39
+
40
+ public_class_method def self.get_bluetooth(opts = {})
41
+ get(opts.merge(config_type: :BLUETOOTH_CONFIG))
42
+ end
43
+
44
+ public_class_method def self.get_security(opts = {})
45
+ get(opts.merge(config_type: :SECURITY_CONFIG))
46
+ end
47
+
48
+ public_class_method def self.get_sessionkey(opts = {})
49
+ get(opts.merge(config_type: :SESSIONKEY_CONFIG))
50
+ end
51
+
52
+ public_class_method def self.get_device_ui(opts = {})
53
+ get(opts.merge(config_type: :DEVICEUI_CONFIG))
54
+ end
55
+
56
+ public_class_method def self.set_device(opts = {})
57
+ config = Meshtastic::Config.new
58
+ config.device = opts[:device]
59
+ set(opts.merge(config: config))
60
+ end
61
+
62
+ public_class_method def self.set_lora(opts = {})
63
+ config = Meshtastic::Config.new
64
+ config.lora = opts[:lora]
65
+ set(opts.merge(config: config))
66
+ end
67
+
68
+ public_class_method def self.authors
69
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n "
70
+ end
71
+
72
+ public_class_method def self.help
73
+ puts "USAGE:
74
+ # Request a radio Config section by ConfigType.
75
+ #{self}.get(
76
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect',
77
+ config_type: 'optional - :DEVICE_CONFIG or another ConfigType (default: :DEVICE_CONFIG)'
78
+ )
79
+
80
+ # Write a Config protobuf to the node.
81
+ #{self}.set(
82
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect',
83
+ config: 'required - Meshtastic::Config protobuf to write'
84
+ )
85
+
86
+ # Request DEVICE_CONFIG from the node.
87
+ #{self}.get_device(
88
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
89
+ )
90
+
91
+ # Request POSITION_CONFIG from the node.
92
+ #{self}.get_position(
93
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
94
+ )
95
+
96
+ # Request POWER_CONFIG from the node.
97
+ #{self}.get_power(
98
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
99
+ )
100
+
101
+ # Request NETWORK_CONFIG from the node.
102
+ #{self}.get_network(
103
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
104
+ )
105
+
106
+ # Request DISPLAY_CONFIG from the node.
107
+ #{self}.get_display(
108
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
109
+ )
110
+
111
+ # Request LORA_CONFIG from the node.
112
+ #{self}.get_lora(
113
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
114
+ )
115
+
116
+ # Request BLUETOOTH_CONFIG from the node.
117
+ #{self}.get_bluetooth(
118
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
119
+ )
120
+
121
+ # Request SECURITY_CONFIG from the node.
122
+ #{self}.get_security(
123
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
124
+ )
125
+
126
+ # Request SESSIONKEY_CONFIG from the node.
127
+ #{self}.get_sessionkey(
128
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
129
+ )
130
+
131
+ # Request DEVICEUI_CONFIG from the node.
132
+ #{self}.get_device_ui(
133
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect'
134
+ )
135
+
136
+ # Write DeviceConfig wrapped in a Config protobuf.
137
+ #{self}.set_device(
138
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect',
139
+ device: 'required - Meshtastic::Config::DeviceConfig protobuf to write'
140
+ )
141
+
142
+ # Write LoRaConfig wrapped in a Config protobuf.
143
+ #{self}.set_lora(
144
+ serial_obj: 'optional - serial handle from Meshtastic::Serial.connect',
145
+ lora: 'required - Meshtastic::Config::LoRaConfig protobuf to write'
146
+ )
147
+
148
+ # Print the AUTHOR(S) string for this module.
149
+ #{self}.authors
150
+ "
151
+ end
152
+ end
153
+ end
154
+ end