meshtastic 0.0.178 → 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.
- checksums.yaml +4 -4
- data/README.md +3 -175
- data/documentation/README.md +60 -0
- data/documentation/admin-channel.md +33 -0
- data/documentation/admin-config.md +28 -0
- data/documentation/admin-firmware.md +69 -0
- data/documentation/admin.md +55 -0
- data/documentation/apponly.md +22 -0
- data/documentation/atak.md +110 -0
- data/documentation/bluetooth-bluez.md +35 -0
- data/documentation/bluetooth.md +87 -0
- data/documentation/cannedmessages.md +25 -0
- data/documentation/channel.md +3 -0
- data/documentation/clientonly.md +21 -0
- data/documentation/config.md +3 -0
- data/documentation/connection-status.md +22 -0
- data/documentation/deviceonly.md +22 -0
- data/documentation/localonly.md +21 -0
- data/documentation/mesh-interface.md +52 -0
- data/documentation/meshtastic.md +45 -0
- data/documentation/module-config.md +26 -0
- data/documentation/mqtt.md +101 -0
- data/documentation/paxcount.md +25 -0
- data/documentation/portnums.md +67 -0
- data/documentation/position.md +34 -0
- data/documentation/protobufs.md +162 -0
- data/documentation/remote-hardware.md +33 -0
- data/documentation/rtttl.md +24 -0
- data/documentation/serial.md +78 -0
- data/documentation/storeforward.md +24 -0
- data/documentation/stream-interface.md +15 -0
- data/documentation/tcp.md +43 -0
- data/documentation/telemetry.md +32 -0
- data/documentation/traceroute.md +28 -0
- data/documentation/util.md +27 -0
- data/documentation/xmodem.md +22 -0
- data/lib/meshtastic/admin/channel.rb +90 -0
- data/lib/meshtastic/admin/config.rb +154 -0
- data/lib/meshtastic/admin/firmware.rb +173 -0
- data/lib/meshtastic/admin.rb +495 -7
- data/lib/meshtastic/apponly.rb +26 -8
- data/lib/meshtastic/atak.rb +298 -7
- data/lib/meshtastic/bluetooth/bluez.rb +20 -1
- data/lib/meshtastic/bluetooth.rb +70 -59
- data/lib/meshtastic/cannedmessages.rb +23 -8
- data/lib/meshtastic/channel.rb +3 -21
- data/lib/meshtastic/clientonly.rb +26 -8
- data/lib/meshtastic/config.rb +3 -21
- data/lib/meshtastic/connection_status.rb +13 -8
- data/lib/meshtastic/deviceonly.rb +23 -8
- data/lib/meshtastic/localonly.rb +23 -8
- data/lib/meshtastic/mesh_interface.rb +11 -0
- data/lib/meshtastic/module_config.rb +18 -9
- data/lib/meshtastic/mqtt.rb +72 -35
- data/lib/meshtastic/paxcount.rb +30 -9
- data/lib/meshtastic/portnums.rb +18 -8
- data/lib/meshtastic/position.rb +45 -0
- data/lib/meshtastic/remote_hardware.rb +50 -9
- data/lib/meshtastic/rtttl.rb +26 -8
- data/lib/meshtastic/serial.rb +81 -70
- data/lib/meshtastic/storeforward.rb +23 -8
- data/lib/meshtastic/stream_interface.rb +11 -0
- data/lib/meshtastic/tcp.rb +153 -0
- data/lib/meshtastic/telemetry.rb +27 -9
- data/lib/meshtastic/traceroute.rb +42 -0
- data/lib/meshtastic/util.rb +3 -1
- data/lib/meshtastic/version.rb +1 -1
- data/lib/meshtastic/xmodem.rb +17 -8
- data/lib/meshtastic.rb +46 -6
- data/spec/conventions_spec.rb +321 -0
- data/spec/lib/meshtastic/admin/channel_spec.rb +45 -0
- data/spec/lib/meshtastic/admin/config_spec.rb +48 -0
- data/spec/lib/meshtastic/admin/firmware_spec.rb +118 -0
- data/spec/lib/meshtastic/admin_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/admin_spec.rb +79 -0
- data/spec/lib/meshtastic/apponly_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/apponly_spec.rb +4 -0
- data/spec/lib/meshtastic/atak_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/atak_spec.rb +147 -0
- data/spec/lib/meshtastic/bluetooth_spec.rb +1 -1
- data/spec/lib/meshtastic/cannedmessages_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/cannedmessages_spec.rb +3 -0
- data/spec/lib/meshtastic/channel_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/channel_spec.rb +3 -0
- data/spec/lib/meshtastic/clientonly_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/clientonly_spec.rb +5 -0
- data/spec/lib/meshtastic/config_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/config_spec.rb +4 -1
- data/spec/lib/meshtastic/connection_status_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/connection_status_spec.rb +3 -0
- data/spec/lib/meshtastic/deviceonly_legacy_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/deviceonly_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/deviceonly_spec.rb +3 -0
- data/spec/lib/meshtastic/localonly_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/localonly_spec.rb +3 -0
- data/spec/lib/meshtastic/mesh_beacon_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/mesh_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/module_config_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/module_config_spec.rb +21 -0
- data/spec/lib/meshtastic/mqtt_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/paxcount_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/paxcount_spec.rb +23 -0
- data/spec/lib/meshtastic/portnums_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/portnums_spec.rb +4 -0
- data/spec/lib/meshtastic/position_spec.rb +33 -0
- data/spec/lib/meshtastic/remote_hardware_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/remote_hardware_spec.rb +24 -0
- data/spec/lib/meshtastic/rtttl_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/rtttl_spec.rb +21 -0
- data/spec/lib/meshtastic/storeforward_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/storeforward_spec.rb +21 -0
- data/spec/lib/meshtastic/tcp_spec.rb +48 -0
- data/spec/lib/meshtastic/telemetry_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/telemetry_spec.rb +21 -0
- data/spec/lib/meshtastic/traceroute_spec.rb +27 -0
- data/spec/lib/meshtastic/xmodem_pb_spec.rb +1 -1
- data/spec/lib/meshtastic/xmodem_spec.rb +6 -1
- data/spec/lib/meshtastic_spec.rb +3 -0
- metadata +48 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Generated protobuf types
|
|
2
|
+
|
|
3
|
+
These classes and enums come from `lib/meshtastic/*_pb.rb` (Meshtastic protobufs via `grpc_tools_ruby_protoc`). They live in the `Meshtastic` namespace. Typical API:
|
|
4
|
+
|
|
5
|
+
```ruby
|
|
6
|
+
msg = Meshtastic::User.new(long_name: 'Node', short_name: 'N1')
|
|
7
|
+
bytes = msg.to_proto
|
|
8
|
+
again = Meshtastic::User.decode(bytes)
|
|
9
|
+
msg.to_h
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Enums: `Meshtastic::PortNum::TEXT_MESSAGE_APP`, `Meshtastic::PortNum.lookup(1)`, `Meshtastic::PortNum.resolve(:TEXT_MESSAGE_APP)`.
|
|
13
|
+
|
|
14
|
+
A few generated **classes** are reopened with extra class methods: `Channel`, `Config`, `ModuleConfig`, `Paxcount`, `Position`, `Telemetry`. Do not name those extras `send` or `encode`.
|
|
15
|
+
|
|
16
|
+
First-class wrappers for many of these types: [documentation index](README.md).
|
|
17
|
+
|
|
18
|
+
## admin.proto
|
|
19
|
+
|
|
20
|
+
- Messages: `AdminMessage`, `AdminMessage::InputEvent`, `AdminMessage::OTAEvent`, `LockdownAuth`, `HamParameters`, `NodeRemoteHardwarePinsResponse`, `SharedContact`, `KeyVerificationAdmin`, `SensorConfig`, `SCD4X_config`, `SEN5X_config`, `SEN6X_config`, `SCD30_config`, `SHTXX_config`, `DS248X_config`, `AS3935_config`
|
|
21
|
+
- Enums: `AdminMessage::ConfigType`, `AdminMessage::ModuleConfigType`, `AdminMessage::BackupLocation`, `KeyVerificationAdmin::MessageType`, `OTAMode`
|
|
22
|
+
|
|
23
|
+
See [Admin](admin.md).
|
|
24
|
+
|
|
25
|
+
## apponly.proto
|
|
26
|
+
|
|
27
|
+
- `ChannelSet` — [Apponly](apponly.md)
|
|
28
|
+
|
|
29
|
+
## atak.proto
|
|
30
|
+
|
|
31
|
+
- Messages: `TAKPacket`, `GeoChat`, `Group`, `Status`, `Contact`, `PLI`, `AircraftTrack`, `CotGeoPoint`, `DrawnShape`, `Marker`, `RangeAndBearing`, `Route`, `Route::Link`, `CasevacReport`, `ZMistEntry`, `EmergencyAlert`, `TaskRequest`, `TAKEnvironment`, `SensorFov`, `TakTalkMessage`, `TakTalkRoomData`, `Marti`, `TAKPacketV2`
|
|
32
|
+
- Enums: `GeoChat::ReceiptType`, `DrawnShape::Kind`, `DrawnShape::StyleMode`, `Marker::Kind`, `Route::Method`, `Route::Direction`, `CasevacReport::Precedence`, `CasevacReport::HlzMarking`, `CasevacReport::Security`, `EmergencyAlert::Type`, `TaskRequest::Priority`, `TaskRequest::Status`, `SensorFov::SensorType`, `Team`, `MemberRole`, `CotHow`, `CotType`, `GeoPointSource`
|
|
33
|
+
|
|
34
|
+
See [ATAK](atak.md).
|
|
35
|
+
|
|
36
|
+
## cannedmessages.proto
|
|
37
|
+
|
|
38
|
+
- `CannedMessageModuleConfig` — [Cannedmessages](cannedmessages.md)
|
|
39
|
+
|
|
40
|
+
## channel.proto
|
|
41
|
+
|
|
42
|
+
- `ChannelSettings`, `ModuleSettings`, `Channel`, `Channel::Role` — [Channel](channel.md)
|
|
43
|
+
|
|
44
|
+
## clientonly.proto
|
|
45
|
+
|
|
46
|
+
- `DeviceProfile` — [Clientonly](clientonly.md)
|
|
47
|
+
|
|
48
|
+
## config.proto
|
|
49
|
+
|
|
50
|
+
- `Config` and nested `DeviceConfig`, `PositionConfig`, `PowerConfig`, `NetworkConfig`, `DisplayConfig`, `LoRaConfig`, `BluetoothConfig`, `SecurityConfig`, `SessionkeyConfig` plus their enums — [Config](config.md)
|
|
51
|
+
|
|
52
|
+
## connection_status.proto
|
|
53
|
+
|
|
54
|
+
- `DeviceConnectionStatus`, `WifiConnectionStatus`, `EthernetConnectionStatus`, `NetworkConnectionStatus`, `BluetoothConnectionStatus`, `SerialConnectionStatus` — [ConnectionStatus](connection-status.md)
|
|
55
|
+
|
|
56
|
+
## device_ui.proto
|
|
57
|
+
|
|
58
|
+
- `DeviceUIConfig`, `NodeFilter`, `NodeHighlight`, `GeoPoint`, `Map`
|
|
59
|
+
- Enums: `DeviceUIConfig::GpsCoordinateFormat`, `CompassMode`, `Theme`, `Language`
|
|
60
|
+
|
|
61
|
+
No dedicated wrapper; set via Admin `DEVICEUI_CONFIG` / `Config.device_ui`.
|
|
62
|
+
|
|
63
|
+
## deviceonly.proto / deviceonly_legacy.proto
|
|
64
|
+
|
|
65
|
+
- `PositionLite`, `UserLite`, `NodeInfoLite`, `DeviceState`, `NodePositionEntry`, `NodeTelemetryEntry`, `NodeEnvironmentEntry`, `NodeStatusEntry`, `NodeDatabase`, `ChannelFile`, `BackupPreferences`
|
|
66
|
+
- Legacy: `NodeInfoLite_Legacy`, `NodeDatabase_Legacy`
|
|
67
|
+
|
|
68
|
+
See [Deviceonly](deviceonly.md).
|
|
69
|
+
|
|
70
|
+
## interdevice.proto
|
|
71
|
+
|
|
72
|
+
- `FileTransfer`, `DirectoryListing`, `I2CTransaction`, `SdCardInfo`, `I2CResult`, `InterdeviceMessage`
|
|
73
|
+
- Enums: `SdCardInfo::CardType`, `SdCardInfo::FatType`, `I2CResult::Status`, `InterdeviceVersion`, `FileOperation`, `FileStatus`, `SdCommand`
|
|
74
|
+
|
|
75
|
+
No dedicated wrapper. Encode/decode the generated classes directly.
|
|
76
|
+
|
|
77
|
+
## localonly.proto
|
|
78
|
+
|
|
79
|
+
- `LocalConfig`, `LocalModuleConfig` — [Localonly](localonly.md)
|
|
80
|
+
|
|
81
|
+
## lorawan_bridge.proto
|
|
82
|
+
|
|
83
|
+
- `LoRaWANBridge` plus nested `Uplink`, `Downlink`, `PayloadChunk`, `TxResult`
|
|
84
|
+
|
|
85
|
+
No dedicated wrapper. Port `LORAWAN_BRIDGE` (75).
|
|
86
|
+
|
|
87
|
+
## mesh_beacon.proto
|
|
88
|
+
|
|
89
|
+
- `MeshBeacon` — port `MESH_BEACON_APP` (37)
|
|
90
|
+
|
|
91
|
+
## mesh.proto
|
|
92
|
+
|
|
93
|
+
Core radio types:
|
|
94
|
+
|
|
95
|
+
- `Position` ([Position](position.md)), `User`, `RouteDiscovery` ([Traceroute](traceroute.md)), `Routing`, `Data`, `KeyVerification`, `StoreForwardPlusPlus`, `RemoteShell`, `BoundingBox`, `Waypoint`, `StatusMessage`, `MqttClientProxyMessage`, `MeshPacket`, `NodeInfo`, `MyNodeInfo`, `LogRecord`, `QueueStatus`, `FromRadio`, `LockdownStatus`, `ClientNotification`, `KeyVerificationNumberInform`, `KeyVerificationNumberRequest`, `KeyVerificationFinal`, `DuplicatedPublicKey`, `LowEntropyKey`, `FileInfo`, `ToRadio`, `Compressed`, `NeighborInfo`, `Neighbor`, `DeviceMetadata`, `LoRaPresetGroup`, `LoRaRegionPresets`, `LoRaRegionPresetMap`, `Heartbeat`, `NodeRemoteHardwarePin`, `ChunkedPayload`, `resend_chunks`, `ChunkedPayloadResponse`
|
|
96
|
+
- Enums: `HardwareModel`, `Constants`, `CriticalErrorCode`, `FirmwareEdition`, `ExcludedModules`, plus nested enums on Position, Routing, MeshPacket, LogRecord, LockdownStatus, RemoteShell, StoreForwardPlusPlus
|
|
97
|
+
|
|
98
|
+
Serial/TCP frames carry `ToRadio` / `FromRadio`. MQTT publishes `ServiceEnvelope` wrapping `MeshPacket`.
|
|
99
|
+
|
|
100
|
+
## module_config.proto
|
|
101
|
+
|
|
102
|
+
- `ModuleConfig` and nested MQTT/Serial/StoreForward/Telemetry/… configs — [ModuleConfig](module-config.md)
|
|
103
|
+
- `RemoteHardwarePin`, `RemoteHardwarePinType`
|
|
104
|
+
|
|
105
|
+
## mqtt.proto
|
|
106
|
+
|
|
107
|
+
- `ServiceEnvelope`, `MapReport` — [MQTT](mqtt.md)
|
|
108
|
+
|
|
109
|
+
## paxcount.proto
|
|
110
|
+
|
|
111
|
+
- `Paxcount` — [Paxcount](paxcount.md)
|
|
112
|
+
|
|
113
|
+
## portnums.proto
|
|
114
|
+
|
|
115
|
+
- `PortNum` — [Portnums](portnums.md)
|
|
116
|
+
|
|
117
|
+
## powermon.proto
|
|
118
|
+
|
|
119
|
+
- `PowerMon`, `PowerStressMessage` (and nested enums)
|
|
120
|
+
|
|
121
|
+
No dedicated wrapper. Port `POWERSTRESS_APP` (74).
|
|
122
|
+
|
|
123
|
+
## remote_hardware.proto
|
|
124
|
+
|
|
125
|
+
- `HardwareMessage`, `HardwareMessage::Type` — [RemoteHardware](remote-hardware.md)
|
|
126
|
+
|
|
127
|
+
## rtttl.proto
|
|
128
|
+
|
|
129
|
+
- `RTTTLConfig` — [RTTTL](rtttl.md)
|
|
130
|
+
|
|
131
|
+
## serial_hal.proto
|
|
132
|
+
|
|
133
|
+
- `SerialHalCommand`, `SerialHalResponse`
|
|
134
|
+
|
|
135
|
+
GPIO serial HAL, not USB CDC. See [Serial](serial.md) for the USB Stream API.
|
|
136
|
+
|
|
137
|
+
## storeforward.proto
|
|
138
|
+
|
|
139
|
+
- `StoreAndForward` plus `Statistics`, `History`, `Heartbeat`, `RequestResponse` — [Storeforward](storeforward.md)
|
|
140
|
+
|
|
141
|
+
## telemetry.proto
|
|
142
|
+
|
|
143
|
+
- `Telemetry` ([Telemetry](telemetry.md)), `DeviceMetrics`, `EnvironmentMetrics`, `SoilWaterMetrics`, `PowerMetrics`, `AirQualityMetrics`, `LocalStats`, `TrafficManagementStats`, `HealthMetrics`, `HostMetrics`, `Nau7802Config`, `AS3935Config`, `SEN5XState`, `SEN6XState`, `TelemetrySensorType`
|
|
144
|
+
|
|
145
|
+
## xmodem.proto
|
|
146
|
+
|
|
147
|
+
- `XModem`, `XModem::Control` — [Xmodem](xmodem.md)
|
|
148
|
+
|
|
149
|
+
## nanopb
|
|
150
|
+
|
|
151
|
+
`require 'nanopb_pb'` is loaded with the gem. It is not a `Meshtastic::` module.
|
|
152
|
+
|
|
153
|
+
## Example: inspect a type
|
|
154
|
+
|
|
155
|
+
```ruby
|
|
156
|
+
require 'meshtastic'
|
|
157
|
+
|
|
158
|
+
Meshtastic::AdminMessage.descriptor.each { |f| puts f.name }
|
|
159
|
+
Meshtastic::PortNum.constants.sort
|
|
160
|
+
user = Meshtastic::User.new(long_name: 'Node', short_name: 'N1')
|
|
161
|
+
Meshtastic::User.decode(user.to_proto)
|
|
162
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Meshtastic::RemoteHardware
|
|
2
|
+
|
|
3
|
+
GPIO control on `REMOTE_HARDWARE_APP` (port 2) using `Meshtastic::HardwareMessage`.
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
- `encode(type:, gpio_mask:, gpio_value:)`
|
|
8
|
+
- `send`
|
|
9
|
+
- `read_gpios(gpio_mask:)`
|
|
10
|
+
- `write_gpios(gpio_mask:, gpio_value:)`
|
|
11
|
+
- `watch_gpios(gpio_mask:)`
|
|
12
|
+
- `help` / `authors`
|
|
13
|
+
|
|
14
|
+
`type` values: `:UNSET`, `:WRITE_GPIOS`, `:WATCH_GPIOS`, `:GPIOS_CHANGED`, `:READ_GPIOS`, `:READ_GPIOS_REPLY`.
|
|
15
|
+
|
|
16
|
+
## Example
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
Meshtastic::RemoteHardware.write_gpios(
|
|
20
|
+
serial_obj: serial_obj,
|
|
21
|
+
gpio_mask: 0x01,
|
|
22
|
+
gpio_value: 0x01
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
Meshtastic::RemoteHardware.read_gpios(serial_obj: serial_obj, gpio_mask: 0x01)
|
|
26
|
+
Meshtastic::RemoteHardware.watch_gpios(serial_obj: serial_obj, gpio_mask: 0x01)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Enable the Remote Hardware module on the node and only drive pins the firmware exposes.
|
|
30
|
+
|
|
31
|
+
## Related
|
|
32
|
+
|
|
33
|
+
- [Meshtastic::ModuleConfig](module-config.md)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Meshtastic::RTTTL
|
|
2
|
+
|
|
3
|
+
Ringtone helpers. `encode` builds `RTTTLConfig`. `set` / `get` go through [Admin](admin.md) (`set_ringtone_message` / `get_ringtone_request`).
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
- `encode(ringtone:)`
|
|
8
|
+
- `set(serial_obj:, ringtone:)`
|
|
9
|
+
- `get(serial_obj:)`
|
|
10
|
+
- `help` / `authors`
|
|
11
|
+
|
|
12
|
+
## Example
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
Meshtastic::RTTTL.set(
|
|
16
|
+
serial_obj: serial_obj,
|
|
17
|
+
ringtone: 'Mario:d=4,o=5,b=125:16e6'
|
|
18
|
+
)
|
|
19
|
+
Meshtastic::RTTTL.get(serial_obj: serial_obj)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Related
|
|
23
|
+
|
|
24
|
+
- [Meshtastic::Admin](admin.md)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Meshtastic::Serial
|
|
2
|
+
|
|
3
|
+
USB/UART Stream API. Framing is `[0x94][0xC3][len_hi][len_lo]` plus a `ToRadio` / `FromRadio` protobuf.
|
|
4
|
+
|
|
5
|
+
The radio applies channel crypto. Payloads go out decoded. `channel:` is the device channel index (usually `0`), not an MQTT hash.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
Use the USB CDC port (`/dev/ttyACM*` or `/dev/ttyUSB*`). Enable Radio Configuration → Security → Serial Console (`security.serial_enabled`). That is not Module Configuration → Serial (`TEXTMSG` / `PROTO` on GPIO). Keep “Override Console Serial Port” off.
|
|
10
|
+
|
|
11
|
+
Do not open Serial and Bluetooth to the same radio at once.
|
|
12
|
+
|
|
13
|
+
## Methods
|
|
14
|
+
|
|
15
|
+
- `connect(block_dev:, baud:, data_bits:, stop_bits:, parity:, debug_out:, want_config:)`
|
|
16
|
+
- `wait_for_config(serial_obj:, timeout:)` — raises `Timeout::Error` if handshake never completes
|
|
17
|
+
- `wake_up_device` — writes 32 × `START2`
|
|
18
|
+
- `request` — raw bytes
|
|
19
|
+
- `send_to_radio` — framed `ToRadio`
|
|
20
|
+
- `send_text` / `send_data`
|
|
21
|
+
- `recv_from_radio(timeout:)` — `0` polls, `nil` blocks, default `5`. Closed empty queue → `nil`. Unplug → `IOError`
|
|
22
|
+
- `drain_from_radio`
|
|
23
|
+
- `dump_stdout_data` / `flush_data` / `monitor_stdout` (`:proto` or `:console`)
|
|
24
|
+
- `subscribe` — blocking FromRadio loop
|
|
25
|
+
- `disconnect`
|
|
26
|
+
- `help` / `authors`
|
|
27
|
+
|
|
28
|
+
`send_text` / `send_data` return bytes written, not mesh delivery. `want_ack: true` asks for `ROUTING_APP` (`error_reason: NONE` means the local radio accepted the route). Incoming text is UTF-8 under `message[:packet][:decoded][:payload]`.
|
|
29
|
+
|
|
30
|
+
Call `wait_for_config` before using `my_node_num` or sending. Opening a port is not a completed handshake.
|
|
31
|
+
|
|
32
|
+
## Send / receive
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
require 'meshtastic'
|
|
36
|
+
|
|
37
|
+
serial_obj = nil
|
|
38
|
+
begin
|
|
39
|
+
serial_obj = Meshtastic::Serial.connect(block_dev: '/dev/ttyACM0', baud: 115_200)
|
|
40
|
+
Meshtastic::Serial.wait_for_config(serial_obj: serial_obj, timeout: 10)
|
|
41
|
+
puts "local node: !#{serial_obj[:my_node_num].to_s(16)}"
|
|
42
|
+
|
|
43
|
+
Meshtastic::Serial.send_text(
|
|
44
|
+
serial_obj: serial_obj,
|
|
45
|
+
to: '!aabbccdd', # or '!ffffffff' for the shared channel
|
|
46
|
+
channel: 0,
|
|
47
|
+
text: 'Hello over serial!',
|
|
48
|
+
want_ack: true
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
Meshtastic::Serial.subscribe(
|
|
52
|
+
serial_obj: serial_obj,
|
|
53
|
+
include: 'TEXT_MESSAGE_APP'
|
|
54
|
+
) do |message|
|
|
55
|
+
packet = message[:packet]
|
|
56
|
+
puts "#{packet[:node_id_from]}: #{packet.dig(:decoded, :payload)}"
|
|
57
|
+
end
|
|
58
|
+
ensure
|
|
59
|
+
Meshtastic::Serial.disconnect(serial_obj: serial_obj)
|
|
60
|
+
end
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Drive the loop yourself:
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
from_radio = Meshtastic::Serial.recv_from_radio(serial_obj: serial_obj, timeout: 0)
|
|
67
|
+
msgs = Meshtastic::Serial.drain_from_radio(serial_obj: serial_obj, max: 256)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
If `wait_for_config` times out, the USB path is up but the Stream API is not (wrong port, Serial Console disabled, or firmware not responding).
|
|
71
|
+
|
|
72
|
+
Default `block_dev` is `/dev/ttyUSB0`, baud `115200`, 8N1.
|
|
73
|
+
|
|
74
|
+
## Related
|
|
75
|
+
|
|
76
|
+
- [Meshtastic::TCP](tcp.md) (same framing)
|
|
77
|
+
- [Meshtastic::Bluetooth](bluetooth.md)
|
|
78
|
+
- [Meshtastic::Admin](admin.md)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Meshtastic::Storeforward
|
|
2
|
+
|
|
3
|
+
Sends `Meshtastic::StoreAndForward` on `STORE_FORWARD_APP` (port 65).
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
- `encode(rr:)` — request/response enum, default `:ROUTER_HEARTBEAT`
|
|
8
|
+
- `send`
|
|
9
|
+
- `help` / `authors`
|
|
10
|
+
|
|
11
|
+
`rr` includes values such as `:CLIENT_HISTORY`, `:ROUTER_HEARTBEAT`.
|
|
12
|
+
|
|
13
|
+
## Example
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Meshtastic::Storeforward.send(
|
|
17
|
+
serial_obj: serial_obj,
|
|
18
|
+
rr: :CLIENT_HISTORY
|
|
19
|
+
)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Related
|
|
23
|
+
|
|
24
|
+
- [Meshtastic::ModuleConfig](module-config.md) (`:STOREFORWARD_CONFIG`)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Meshtastic::StreamInterface
|
|
2
|
+
|
|
3
|
+
Abstract UART helper left from the Python client layout. Instantiating it raises unless a subclass sets `@stream` (or `no_proto: true`).
|
|
4
|
+
|
|
5
|
+
Use [Meshtastic::Serial](serial.md) for USB/UART.
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# raises: StreamInterface is now abstract (to update existing code use Meshtastic::Serial instead)
|
|
9
|
+
Meshtastic::StreamInterface.new
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Related
|
|
13
|
+
|
|
14
|
+
- [Meshtastic::Serial](serial.md)
|
|
15
|
+
- [Meshtastic::TCP](tcp.md)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Meshtastic::TCP
|
|
2
|
+
|
|
3
|
+
Same framed Stream API as [Serial](serial.md), over TCP. Firmware default port is `4403`. Use `tcp_obj:` instead of `serial_obj:`. Internally reuses Serial’s RX thread and framing.
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
- `connect(host:, port:, socket:, want_config:, debug_out:)` — `host` default `127.0.0.1`, `port` default `4403`. `socket:` is for tests.
|
|
8
|
+
- `wait_for_config`
|
|
9
|
+
- `send_text` / `send_data` / `send_to_radio`
|
|
10
|
+
- `recv_from_radio` / `drain_from_radio`
|
|
11
|
+
- `subscribe`
|
|
12
|
+
- `disconnect`
|
|
13
|
+
- `help` / `authors`
|
|
14
|
+
|
|
15
|
+
## Send / receive
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
require 'meshtastic'
|
|
19
|
+
|
|
20
|
+
tcp_obj = nil
|
|
21
|
+
begin
|
|
22
|
+
tcp_obj = Meshtastic::TCP.connect(host: '192.0.2.10', port: 4403)
|
|
23
|
+
Meshtastic::TCP.wait_for_config(tcp_obj: tcp_obj, timeout: 10)
|
|
24
|
+
Meshtastic::TCP.send_text(
|
|
25
|
+
tcp_obj: tcp_obj,
|
|
26
|
+
to: '!ffffffff',
|
|
27
|
+
channel: 0,
|
|
28
|
+
text: 'Hello over TCP!'
|
|
29
|
+
)
|
|
30
|
+
Meshtastic::TCP.subscribe(tcp_obj: tcp_obj, include: 'TEXT_MESSAGE_APP') do |message|
|
|
31
|
+
puts message.dig(:packet, :decoded, :payload)
|
|
32
|
+
end
|
|
33
|
+
ensure
|
|
34
|
+
Meshtastic::TCP.disconnect(tcp_obj: tcp_obj)
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Enable TCP in radio network settings. Feature modules accept `tcp_obj:` the same way as `serial_obj:`.
|
|
39
|
+
|
|
40
|
+
## Related
|
|
41
|
+
|
|
42
|
+
- [Meshtastic::Serial](serial.md)
|
|
43
|
+
- [Meshtastic::Admin](admin.md)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Meshtastic::Telemetry
|
|
2
|
+
|
|
3
|
+
Reopens the generated `Meshtastic::Telemetry` protobuf class. Requests metrics on `TELEMETRY_APP` (port 67) with `want_response: true`.
|
|
4
|
+
|
|
5
|
+
Use `build` / `request`, not `send` / `encode`.
|
|
6
|
+
|
|
7
|
+
## Methods
|
|
8
|
+
|
|
9
|
+
- `build(time:)`
|
|
10
|
+
- `request(serial_obj:, to:, ...)`
|
|
11
|
+
- `help` / `authors`
|
|
12
|
+
|
|
13
|
+
## Example
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
Meshtastic::Telemetry.request(
|
|
17
|
+
serial_obj: serial_obj,
|
|
18
|
+
to: '!aabbccdd'
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
Meshtastic::Serial.subscribe(serial_obj: serial_obj, include: 'TELEMETRY_APP') do |message|
|
|
22
|
+
tel = Meshtastic::Telemetry.decode(message.dig(:packet, :decoded, :payload).to_s) rescue nil
|
|
23
|
+
p tel&.device_metrics
|
|
24
|
+
end
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Incoming payloads may include `device_metrics`, `environment_metrics`, `air_quality_metrics`, `power_metrics`, `local_stats`, `health_metrics`, `host_metrics`, `traffic_management_stats`, `soil_water_metrics`.
|
|
28
|
+
|
|
29
|
+
## Related
|
|
30
|
+
|
|
31
|
+
- [Meshtastic::Position](position.md)
|
|
32
|
+
- [Meshtastic::Paxcount](paxcount.md)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Meshtastic::Traceroute
|
|
2
|
+
|
|
3
|
+
Sends `RouteDiscovery` on `TRACEROUTE_APP` (port 70) with `want_response: true`.
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
- `encode(route:)` — optional hop list
|
|
8
|
+
- `send(serial_obj:, to:, ...)`
|
|
9
|
+
- `help` / `authors`
|
|
10
|
+
|
|
11
|
+
## Example
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
Meshtastic::Traceroute.send(
|
|
15
|
+
serial_obj: serial_obj,
|
|
16
|
+
to: '!aabbccdd',
|
|
17
|
+
want_ack: true
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
Meshtastic::Serial.subscribe(serial_obj: serial_obj, include: 'TRACEROUTE_APP') do |message|
|
|
21
|
+
p message.dig(:packet, :decoded)
|
|
22
|
+
end
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Related
|
|
26
|
+
|
|
27
|
+
- [Meshtastic::Serial](serial.md)
|
|
28
|
+
- Protobuf: `RouteDiscovery`, `Routing` in [protobufs.md](protobufs.md)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Meshtastic::Util
|
|
2
|
+
|
|
3
|
+
Small helpers used by [MeshInterface](mesh-interface.md).
|
|
4
|
+
|
|
5
|
+
## `Meshtastic::Util::Acknowledgement`
|
|
6
|
+
|
|
7
|
+
Flags: `received_ack`, `received_nak`, `received_impl_ack`, `received_trace_route`, `received_telemetry`, `received_position`, `received_waypoint`. `#reset` clears them.
|
|
8
|
+
|
|
9
|
+
## `Meshtastic::Util::Timeout`
|
|
10
|
+
|
|
11
|
+
`expire_timeout` (default 20 seconds), `expire_time`, `sleep_interval` (0.1). `#reset` sets `expire_time` from now.
|
|
12
|
+
|
|
13
|
+
## Module methods
|
|
14
|
+
|
|
15
|
+
- `authors` / `help`
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
ack = Meshtastic::Util::Acknowledgement.new
|
|
19
|
+
ack.reset
|
|
20
|
+
|
|
21
|
+
t = Meshtastic::Util::Timeout.new(expire_timeout: 10)
|
|
22
|
+
t.reset
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Related
|
|
26
|
+
|
|
27
|
+
- [Meshtastic::MeshInterface](mesh-interface.md)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Meshtastic::Xmodem
|
|
2
|
+
|
|
3
|
+
Builds `Meshtastic::XModem` packets (`xmodem.proto`). Distinct from the generated class `Meshtastic::XModem`.
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
- `encode(control:, seq:, buffer:)`
|
|
8
|
+
- `help` / `authors`
|
|
9
|
+
|
|
10
|
+
`control` includes `:SOH` and other `XModem::Control` values.
|
|
11
|
+
|
|
12
|
+
## Example
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
packet = Meshtastic::Xmodem.encode(control: :SOH, seq: 1, buffer: 'A')
|
|
16
|
+
packet.control # => :SOH
|
|
17
|
+
packet.seq # => 1
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Related
|
|
21
|
+
|
|
22
|
+
- [Generated protobuf types](protobufs.md)
|
|
@@ -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
|