From 65914b84f1ee8f25807187d60b43ad29dfbaedc3 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Wed, 17 Feb 2021 13:05:46 +0800 Subject: [PATCH] 1.2 WIP moving routing into data --- apponly.proto | 10 +++ docs/docs.md | 114 ++++++++++++++++++----------- mesh.options | 8 +-- mesh.proto | 192 +++++++++++++++++++++++++------------------------ portnums.proto | 5 ++ 5 files changed, 187 insertions(+), 142 deletions(-) diff --git a/apponly.proto b/apponly.proto index 007b9ae..1bfda4b 100644 --- a/apponly.proto +++ b/apponly.proto @@ -26,4 +26,14 @@ message ServiceEnvelope { * the globally trusted nodenum */ string gateway_id = 3; +} + +/* This is the most compact possible representation for a set of channels. It includes only one PRIMARY channel (which must be first) and +any SECONDARY channels. No DISABLED channels are included. + +This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels +as a (long) URL +*/ +message ChannelSet { + repeated ChannelSettings settings = 1; } \ No newline at end of file diff --git a/docs/docs.md b/docs/docs.md index d2c3925..356e8d5 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -4,6 +4,7 @@ ## Table of Contents - [apponly.proto](#apponly.proto) + - [ChannelSet](#.ChannelSet) - [ServiceEnvelope](#.ServiceEnvelope) - [deviceonly.proto](#deviceonly.proto) @@ -22,7 +23,7 @@ - [RadioConfig](#.RadioConfig) - [RadioConfig.UserPreferences](#.RadioConfig.UserPreferences) - [RouteDiscovery](#.RouteDiscovery) - - [SubPacket](#.SubPacket) + - [Routing](#.Routing) - [ToRadio](#.ToRadio) - [User](#.User) @@ -31,12 +32,12 @@ - [ChargeCurrent](#.ChargeCurrent) - [Constants](#.Constants) - [CriticalErrorCode](#.CriticalErrorCode) - - [ErrorReason](#.ErrorReason) - [GpsOperation](#.GpsOperation) - [LocationSharing](#.LocationSharing) - [LogRecord.Level](#.LogRecord.Level) - [MeshPacket.Priority](#.MeshPacket.Priority) - [RegionCode](#.RegionCode) + - [Routing.Error](#.Routing.Error) - [portnums.proto](#portnums.proto) - [PortNum](#.PortNum) @@ -57,6 +58,25 @@ + + +### ChannelSet +This is the most compact possible representation for a set of channels. It includes only one PRIMARY channel (which must be first) and +any SECONDARY channels. No DISABLED channels are included. + +This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels +as a (long) URL + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| settings | [ChannelSettings](#ChannelSettings) | repeated | | + + + + + + ### ServiceEnvelope @@ -158,7 +178,7 @@ A pair of a channel number, mode and the (sharable) settings for that channel | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| index | [uint32](#uint32) | | The index of this channel in the channel table (from 0 to MAX_CHANNELS-1) | +| index | [uint32](#uint32) | | The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1) | | settings | [ChannelSettings](#ChannelSettings) | | The new settings, or NULL to disable that channel | | role | [Channel.Role](#Channel.Role) | | | @@ -214,14 +234,18 @@ remote gpio are managed as an example ### Data -a data message to forward to an external app (or possibly also be consumed -internally in the case of CLEAR_TEXT and CLEAR_READACK) +(Formerly called SubPacket) +The payload portion fo a packet, this is the actual bytes that are sent +inside a radio packet (because from/to are broken out by the comms library) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | portnum | [PortNum](#PortNum) | | Formerly named typ and of type Type | | payload | [bytes](#bytes) | | Required | +| want_response | [bool](#bool) | | Not normally used, but for testing a sender can request that recipient responds in kind (i.e. if it received a position, it should unicast back it's position). Note: that if you set this on a broadcast you will receive many replies. | +| dest | [fixed32](#fixed32) | | The address of the destination node. This field is is filled in by the mesh radio device software, applicaiton layer software should never need it. RouteDiscovery messages _must_ populate this. Other message types might need to if they are doing multihop routing. | +| source | [fixed32](#fixed32) | | The address of the original sender for this message. This field should _only_ be populated for reliable multihop packets (to keep packets small). | @@ -286,12 +310,12 @@ very small, we now assume that there is only _one_ SubPacket in each MeshPacket) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| from | [uint32](#uint32) | | The sending node number. Note: Our crypto implementation uses this field as well. See docs/software/crypto.md for details. FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. | -| to | [uint32](#uint32) | | The (immediatSee Priority description for more details.y should be fixed32 instead, this encoding only hurts the ble link though. | +| from | [fixed32](#fixed32) | | The sending node number. Note: Our crypto implementation uses this field as well. See docs/software/crypto.md for details. FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. | +| to | [fixed32](#fixed32) | | The (immediatSee Priority description for more details.y should be fixed32 instead, this encoding only hurts the ble link though. | | channel_index | [uint32](#uint32) | | If set, this indicates the index in the secondary_channels table that this packet was sent/received on. If unset, packet was on the primary channel. A particular node might know only a subset of channels in use on the mesh. Therefore channel_index is inherently a local concept and meaningless to send between nodes. | -| decoded | [SubPacket](#SubPacket) | | | +| decoded | [Data](#Data) | | | | encrypted | [bytes](#bytes) | | | -| id | [uint32](#uint32) | | A unique ID for this packet. Always 0 for no-ack packets or non broadcast packets (and therefore take zero bytes of space). Otherwise a unique ID for this packet, useful for flooding algorithms. ID only needs to be unique on a _per sender_ basis, and it only needs to be unique for a few minutes (long enough to last for the length of any ACK or the completion of a mesh broadcast flood). Note: Our crypto implementation uses this id as well. See docs/software/crypto.md for details. FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. | +| id | [fixed32](#fixed32) | | A unique ID for this packet. Always 0 for no-ack packets or non broadcast packets (and therefore take zero bytes of space). Otherwise a unique ID for this packet, useful for flooding algorithms. ID only needs to be unique on a _per sender_ basis, and it only needs to be unique for a few minutes (long enough to last for the length of any ACK or the completion of a mesh broadcast flood). Note: Our crypto implementation uses this id as well. See docs/software/crypto.md for details. FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. | | rx_time | [fixed32](#fixed32) | | The time this message was received by the esp32 (secs since 1970). Note: this field is _never_ sent on the radio link itself (to save space) Times are typically not sent over the mesh, but they will be added to any Packet (chain of SubPacket) sent to the phone (so the phone can know exact time of reception) | | rx_snr | [float](#float) | | Never* sent over the radio links. Set during reception to indicate the SNR of this packet. Used to collect statistics on current link waulity. | | hop_limit | [uint32](#uint32) | | If unset treated as zero (no fowarding, send to adjacent nodes only) if 1, allow hopping through one node, etc... For our usecase real world topologies probably have a max of about 3. This field is normally placed into a few of bits in the header. | @@ -488,32 +512,27 @@ A message used in our Dynamic Source Routing protocol (RFC 4728 based) | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| route | [int32](#int32) | repeated | The list of nodes this packet has visited so far | +| route | [fixed32](#fixed32) | repeated | The list of nodenums this packet has visited so far | - + -### SubPacket -The payload portion fo a packet, this is the actual bytes that are sent -inside a radio packet (because from/to are broken out by the comms library) +### Routing +A Routing control Data packet handled by the routing plugin | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| data | [Data](#Data) | | | -| route_request | [RouteDiscovery](#RouteDiscovery) | | A route request going from the requester FIXME - these route messages should be moved into regular data packets and use the regular on device plugin mechanism. | +| route_request | [RouteDiscovery](#RouteDiscovery) | | A route request going from the requester | | route_reply | [RouteDiscovery](#RouteDiscovery) | | A route reply | -| error_reason | [ErrorReason](#ErrorReason) | | A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide details on the type of failure). | -| want_response | [bool](#bool) | | Not normally used, but for testing a sender can request that recipient responds in kind (i.e. if it received a position, it should unicast back it's position). Note: that if you set this on a broadcast you will receive many replies. | -| success_id | [uint32](#uint32) | | This packet is a requested acknoledgement indicating that we have received the specified message ID. This packet type can be used both for immediate (0 hops) messages or can be routed through multiple hops if dest is set. Note: As an optimization, recipients can _also_ populate a field in payload if they think the recipient would appreciate that extra state. | -| fail_id | [uint32](#uint32) | | This is a nak, we failed to deliver this message. | -| dest | [uint32](#uint32) | | The address of the destination node. This field is is filled in by the mesh radio device software, applicaiton layer software should never need it. RouteDiscovery messages _must_ populate this. Other message types might need to if they are doing multihop routing. | -| source | [uint32](#uint32) | | The address of the original sender for this message. This field should _only_ be populated for reliable multihop packets (to keep packets small). | -| original_id | [uint32](#uint32) | | Only used in route_error messages. Indicates the original message ID that this message is reporting failure on. | +| error_reason | [Routing.Error](#Routing.Error) | | A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide details on the type of failure). | +| success_id | [fixed32](#fixed32) | | This is an ack. This packet is a requested acknoledgement indicating that we have received the specified message ID. This packet type can be used both for immediate (0 hops) messages or can be routed through multiple hops if dest is set. Note: As an optimization, recipients can _also_ populate a field in payload if they think the recipient would appreciate that extra state. | +| fail_id | [fixed32](#fixed32) | | This is a nak, we failed to deliver this message. | +| original_id | [fixed32](#fixed32) | | Only used in route_error messages. Indicates the original message ID that this message is reporting failure on. | @@ -533,7 +552,7 @@ Once the write completes the phone can assume it is handled. | want_config_id | [uint32](#uint32) | | phone wants radio to send full node db to the phone, This is typically the first packet sent to the radio when the phone gets a bluetooth connection. The radio will respond by sending back a MyNodeInfo, a owner, a radio config and a series of FromRadio.node_infos, and config_complete the integer you write into this field will be reported back in the config_complete_id response this allows clients to never be confused by a stale old partially sent config. | | set_radio | [RadioConfig](#RadioConfig) | | set the radio provisioning for this node | | set_owner | [User](#User) | | Set the owner for this node | -| set_channel | [Channel](#Channel) | | Set channels (using the new API). A special channel is the "primary channel". The other records are secondary channels. | +| set_channel | [Channel](#Channel) | | Set channels (using the new API). A special channel is the "primary channel". The other records are secondary channels. Note: only one channel can be marked as primary. If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically | @@ -586,7 +605,15 @@ A few nodenums are reserved and will never be requested: ### Channel.Role +How this channel is being used (or not). +Note: this field is an enum to give us options for the future. In particular, someday +we might make a 'SCANNING' option. SCANNING channels could have different frequencies and the radio would +occasionally check that freq to see if anything is being transmitted. + +For devices that have multiple physical radios attached, we could keep multiple PRIMARY/SCANNING channels active at once to allow +cross band routing as needed. If a device has only a single radio (the common case) only one channel can be PRIMARY at a time +(but any number of SECONDARY channels can't be sent received on that common frequency) | Name | Number | Description | | ---- | ------ | ----------- | @@ -673,23 +700,6 @@ post on the meshtastic.discourse.group and we'll try to help. - - -### ErrorReason -A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide -details on the type of failure). - -| Name | Number | Description | -| ---- | ------ | ----------- | -| NONE | 0 | This message is not a failure | -| NO_ROUTE | 1 | Our node doesn't have a route to the requested destination anymore. | -| GOT_NAK | 2 | We received a nak while trying to forward on your behalf | -| TIMEOUT | 3 | | -| NO_INTERFACE | 4 | No suitable interface could be found for delivering this packet | -| MAX_RETRANSMIT | 5 | We reached the max retransmission count (typically for naive flood routing) | - - - ### GpsOperation @@ -790,6 +800,23 @@ old value will be no longer set. | TW | 8 | | + + + +### Routing.Error +A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide +details on the type of failure). + +| Name | Number | Description | +| ---- | ------ | ----------- | +| NONE | 0 | This message is not a failure | +| NO_ROUTE | 1 | Our node doesn't have a route to the requested destination anymore. | +| GOT_NAK | 2 | We received a nak while trying to forward on your behalf | +| TIMEOUT | 3 | | +| NO_INTERFACE | 4 | No suitable interface could be found for delivering this packet | +| MAX_RETRANSMIT | 5 | We reached the max retransmission count (typically for naive flood routing) | + + @@ -840,8 +867,9 @@ Note: this concept has been removed for now. Once READACK is implemented, use th CLEAR_READACK = 2; Reserved for built-in GPIO/example app. See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number | -| POSITION_APP | 3 | The built-in position messaging app. See Position for details on the message sent to this port number. | -| NODEINFO_APP | 4 | The built-in user info app. See User for details on the message sent to this port number. | +| POSITION_APP | 3 | The built-in position messaging app. See Position for details on the message sent to this port number. payload is a Position protobuf | +| NODEINFO_APP | 4 | The built-in user info app. See User for details on the message sent to this port number. payload is a User protobuf | +| ROUTING_APP | 5 | Protocol control packets for mesh protocol use, payload is a Routing protobuf | | REPLY_APP | 32 | Provides a 'ping' service that replies to any packet it receives. Also this serves as a small example plugin. | | IP_TUNNEL_APP | 33 | Used for the python IP tunnel feature | | SERIAL_APP | 64 | Provides a hardware serial interface to send and receive from the Meshtastic network. Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network. Maximum packet size of 240 bytes. diff --git a/mesh.options b/mesh.options index 547eccb..6d56756 100644 --- a/mesh.options +++ b/mesh.options @@ -12,6 +12,7 @@ # FIXME, max out based on total SubPacket size And do fragmentation and reassembly (for larger payloads) at the Android layer, not the esp32 layer. # note: this payload length is ONLY the bytes that are sent inside of the radiohead packet *Data.payload max_size:240 +*Data.payloadVariant anonymous_oneof:true *UserPreferences.wifi_ssid max_size:33 *UserPreferences.wifi_password max_size:64 @@ -32,15 +33,12 @@ *MeshPacket.encrypted max_size:256 *MeshPacket.payloadVariant anonymous_oneof:true -*SubPacket.payloadVariant anonymous_oneof:true - -# We don't want this one anonymous -# *SubPacket.ackVariant anonymous_oneof:true - *ToRadio.payloadVariant anonymous_oneof:true *FromRadio.payloadVariant anonymous_oneof:true +*Routing.variant anonymous_oneof:true + # Max of three ignored nodes for our testing *UserPreferences.ignore_incoming max_count:3 diff --git a/mesh.proto b/mesh.proto index 8e38cbb..eac8191 100644 --- a/mesh.proto +++ b/mesh.proto @@ -57,23 +57,6 @@ message Position { fixed32 time = 9; } -/* - * a data message to forward to an external app (or possibly also be consumed - * internally in the case of CLEAR_TEXT and CLEAR_READACK) - */ -message Data { - - /* - * Formerly named typ and of type Type - */ - PortNum portnum = 1; - - /* - * Required - */ - bytes payload = 2; -} - /* * Broadcast when a newly powered mesh node wants to find a node num it can use * Sent from the phone over bluetooth to set the user id for the owner of this node. @@ -131,70 +114,99 @@ message User { message RouteDiscovery { /* - * The list of nodes this packet has visited so far + * The list of nodenums this packet has visited so far */ - repeated int32 route = 2; + repeated fixed32 route = 2; } -/* + + +/* A Routing control Data packet handled by the routing plugin +*/ +message Routing { + + /* * A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide * details on the type of failure). */ -enum ErrorReason { + enum Error { - /* This message is not a failure */ - NONE = 0; + /* This message is not a failure */ + NONE = 0; + + /* + * Our node doesn't have a route to the requested destination anymore. + */ + NO_ROUTE = 1; + + /* + * We received a nak while trying to forward on your behalf + */ + GOT_NAK = 2; + + TIMEOUT = 3; + + /* No suitable interface could be found for delivering this packet */ + NO_INTERFACE = 4; + + /* We reached the max retransmission count (typically for naive flood routing) */ + MAX_RETRANSMIT = 5; + } + + oneof variant { + /* + * A route request going from the requester + */ + RouteDiscovery route_request = 1; + + /* + * A route reply + */ + RouteDiscovery route_reply = 2; + + /* + * A failure in delivering a message (usually used for routing control messages, but might be provided + * in addition to ack.fail_id to provide details on the type of failure). + */ + Error error_reason = 3; + + /* This is an ack. + * This packet is a requested acknoledgement indicating that we have received + * the specified message ID. This packet type can be used both for immediate + * (0 hops) messages or can be routed through multiple hops if dest is set. + * Note: As an optimization, recipients can _also_ populate a field in payload + * if they think the recipient would appreciate that extra state. + */ + fixed32 success_id = 4; + + /* + * This is a nak, we failed to deliver this message. + */ + fixed32 fail_id = 5; + } /* - * Our node doesn't have a route to the requested destination anymore. + * Only used in route_error messages. Indicates the original message ID that + * this message is reporting failure on. */ - NO_ROUTE = 1; - - /* - * We received a nak while trying to forward on your behalf - */ - GOT_NAK = 2; - - TIMEOUT = 3; - - /* No suitable interface could be found for delivering this packet */ - NO_INTERFACE = 4; - - /* We reached the max retransmission count (typically for naive flood routing) */ - MAX_RETRANSMIT = 5; + fixed32 original_id = 6; } -/* +/* (Formerly called SubPacket) * The payload portion fo a packet, this is the actual bytes that are sent * inside a radio packet (because from/to are broken out by the comms library) */ -message SubPacket { +message Data { /* - * Only one of the following fields can be populated at a time + * Formerly named typ and of type Type */ - oneof payloadVariant { + PortNum portnum = 1; - Data data = 3; - - /* - * A route request going from the requester - * FIXME - these route messages should be moved into regular data packets and use the regular on - * device plugin mechanism. - */ - RouteDiscovery route_request = 6; - - /* - * A route reply - */ - RouteDiscovery route_reply = 7; - - /* - * A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide - * details on the type of failure). - */ - ErrorReason error_reason = 13; - } + /* + * Required + */ + bytes payload = 2; /* * Not normally used, but for testing a sender can request that recipient @@ -203,22 +215,6 @@ message SubPacket { */ bool want_response = 5; - oneof ackVariant { - /* - * This packet is a requested acknoledgement indicating that we have received - * the specified message ID. This packet type can be used both for immediate - * (0 hops) messages or can be routed through multiple hops if dest is set. - * Note: As an optimization, recipients can _also_ populate a field in payload - * if they think the recipient would appreciate that extra state. - */ - uint32 success_id = 10; - - /* - * This is a nak, we failed to deliver this message. - */ - uint32 fail_id = 11; - } - /* * The address of the destination node. * This field is is filled in by the mesh radio device software, applicaiton @@ -226,20 +222,14 @@ message SubPacket { * RouteDiscovery messages _must_ populate this. Other message types might need * to if they are doing multihop routing. */ - uint32 dest = 9; + fixed32 dest = 9; /* * The address of the original sender for this message. * This field should _only_ be populated for reliable multihop packets (to keep * packets small). */ - uint32 source = 12; - - /* - * Only used in route_error messages. Indicates the original message ID that - * this message is reporting failure on. - */ - uint32 original_id = 2; + fixed32 source = 12; } /* @@ -288,13 +278,13 @@ message MeshPacket { * docs/software/crypto.md for details. * FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. */ - uint32 from = 1; + fixed32 from = 1; /* * The (immediatSee Priority description for more details.y should be fixed32 instead, this encoding only * hurts the ble link though. */ - uint32 to = 2; + fixed32 to = 2; /* * If set, this indicates the index in the secondary_channels table that this packet @@ -303,7 +293,6 @@ message MeshPacket { * is inherently a local concept and meaningless to send between nodes. */ uint32 channel_index = 4; - /* * Internally to the mesh radios we will route SubPackets encrypted per @@ -315,7 +304,7 @@ message MeshPacket { */ oneof payloadVariant { - SubPacket decoded = 3; + Data decoded = 3; bytes encrypted = 8; } @@ -330,7 +319,7 @@ message MeshPacket { * FIXME - really should be fixed32 instead, this encoding only * hurts the ble link though. */ - uint32 id = 6; + fixed32 id = 6; /* * The time this message was received by the esp32 (secs since 1970). Note: @@ -552,6 +541,16 @@ message ChannelSettings { /* A pair of a channel number, mode and the (sharable) settings for that channel */ message Channel { + /* How this channel is being used (or not). + + Note: this field is an enum to give us options for the future. In particular, someday + we might make a 'SCANNING' option. SCANNING channels could have different frequencies and the radio would + occasionally check that freq to see if anything is being transmitted. + + For devices that have multiple physical radios attached, we could keep multiple PRIMARY/SCANNING channels active at once to allow + cross band routing as needed. If a device has only a single radio (the common case) only one channel can be PRIMARY at a time + (but any number of SECONDARY channels can't be sent received on that common frequency) + */ enum Role { /* This channel is not in use right now */ DISABLED = 0; @@ -565,7 +564,7 @@ message Channel { SECONDARY = 2; } - /* The index of this channel in the channel table (from 0 to MAX_CHANNELS-1) */ + /* The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1) */ uint32 index = 1; /* The new settings, or NULL to disable that channel */ @@ -1176,6 +1175,9 @@ message LogRecord { */ message FromRadio { + /* In the <1.2 versions packet had ID 2, to prevent confusing old apps with our new packets, we've changed */ + reserved 2; + /* * The packet num, used to allow the phone to request missing read packets from the FIFO, see our bluetooth docs */ @@ -1183,7 +1185,7 @@ message FromRadio { oneof payloadVariant { - MeshPacket packet = 2; + MeshPacket packet = 11; /* * Tells the phone what our node number is, can be -1 if we've not yet joined a mesh. @@ -1233,13 +1235,15 @@ message FromRadio { */ message ToRadio { + /* In the <1.2 versions packet had ID 2, to prevent confusing old apps with our new packets, we've changed */ + reserved 1; oneof payloadVariant { /* * send this packet on the mesh */ - MeshPacket packet = 1; + MeshPacket packet = 2; /* * phone wants radio to send full node db to the phone, This is diff --git a/portnums.proto b/portnums.proto index 81b0a39..e5e2f28 100644 --- a/portnums.proto +++ b/portnums.proto @@ -58,15 +58,20 @@ enum PortNum { /* * The built-in position messaging app. * See Position for details on the message sent to this port number. + * payload is a Position protobuf */ POSITION_APP = 3; /* * The built-in user info app. * See User for details on the message sent to this port number. + * payload is a User protobuf */ NODEINFO_APP = 4; + /* Protocol control packets for mesh protocol use, payload is a Routing protobuf */ + ROUTING_APP = 5; + /* * Provides a 'ping' service that replies to any packet it receives. Also this serves as a small example plugin. */