2020-03-02 17:47:10 +00:00
|
|
|
syntax = "proto3";
|
|
|
|
// per https://developers.google.com/protocol-buffers/docs/proto3
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
// We are not placing any of these defs inside a package, because if you do the
|
|
|
|
// resulting nanopb version is super verbose package mesh;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
|
|
|
option java_package = "com.geeksville.mesh";
|
|
|
|
option java_outer_classname = "MeshProtos";
|
|
|
|
|
|
|
|
/**
|
|
|
|
MESH RADIO PROTOCOL
|
|
|
|
|
|
|
|
Old TODO notes on the mesh radio protocol, merge into real docs below...
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
for each named group we have a pre-shared key known by all group members and
|
|
|
|
wrapped around the device. you can only be in one group at a time (FIXME?!) To
|
|
|
|
join the group we read a qr code with the preshared key and ParamsCodeEnum. that
|
|
|
|
gets sent via bluetooth to the device. ParamsCodeEnum maps to a set of various
|
|
|
|
radio params (regulatory region, center freq, SF, bandwidth, bitrate, power
|
|
|
|
etc...) so all members of the mesh can have their radios set the same way.
|
2020-03-02 17:47:10 +00:00
|
|
|
|
|
|
|
once in that group, we can talk between 254 node numbers.
|
2020-03-24 20:12:25 +00:00
|
|
|
to get our node number (and announce our presence in the channel) we pick a
|
|
|
|
random node number and broadcast as that node with WANT-NODENUM(my globally
|
|
|
|
unique name). If anyone on the channel has seen someone _else_ using that name
|
|
|
|
within the last 24 hrs(?) they reply with DENY-NODENUM. Note: we might receive
|
|
|
|
multiple denies. Note: this allows others to speak up for some other node that
|
|
|
|
might be saving battery right now. Any time we hear from another node (for any
|
|
|
|
message type), we add that node number to the unpickable list. To dramatically
|
|
|
|
decrease the odds a node number we request is already used by someone. If no one
|
|
|
|
denies within TBD seconds, we assume that we have that node number. As long as
|
|
|
|
we keep talking to folks at least once every 24 hrs, others should remember we
|
|
|
|
have it.
|
|
|
|
|
|
|
|
Once we have a node number we can broadcast POSITION-UPDATE(my globally unique
|
|
|
|
name, lat, lon, alt, amt battery remaining). All receivers will use this to a)
|
|
|
|
update the mapping of who is at what node nums, b) the time of last rx, c)
|
|
|
|
position. If we haven't heard from that node in a while we reply to that node
|
|
|
|
(only) with our current POSITION_UPDATE state - so that node (presumably just
|
2020-03-02 17:47:10 +00:00
|
|
|
rejoined the network) can build a map of all participants.
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
We will periodically broadcast POSITION-UPDATE as needed based on distance moved
|
|
|
|
or a periodic minimum heartbeat.
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
If user wants to send a text they can SEND_TEXT(dest user, short text message).
|
|
|
|
Dest user is a node number, or 0xff for broadcast.
|
2020-03-02 17:47:10 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Protobuf build instructions:
|
|
|
|
|
|
|
|
protoc -I=. --java_out /tmp mesh.proto
|
|
|
|
|
|
|
|
To generate Nanopb c code
|
2020-03-24 20:12:25 +00:00
|
|
|
/home/kevinh/packages/nanopb-0.4.0-linux-x86/generator-bin/protoc
|
|
|
|
--nanopb_out=/tmp -I=app/src/main/proto mesh.proto
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
Nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb
|
|
|
|
0.4.0
|
2020-03-02 17:47:10 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
// a gps position
|
|
|
|
message Position {
|
2020-05-04 14:43:15 +00:00
|
|
|
|
|
|
|
/** The new preferred location encoding, divide by 10e-7 to get degrees in
|
|
|
|
* floating point */
|
2020-05-04 18:18:33 +00:00
|
|
|
sint32 latitude_i = 7;
|
|
|
|
sint32 longitude_i = 8;
|
2020-05-04 14:43:15 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
int32 altitude = 3;
|
|
|
|
int32 battery_level = 4; // 1-100 (0 means not provided)
|
|
|
|
|
|
|
|
/// This is usually not sent over the mesh (to save space), but it is sent
|
|
|
|
/// from the phone so that the local device can set its RTC If it is sent over
|
|
|
|
/// the mesh (because there are devices on the mesh without GPS), it will only
|
|
|
|
/// be sent by devices which has a hardware GPS clock.
|
2020-05-10 21:14:35 +00:00
|
|
|
fixed32 time = 9; // seconds since 1970
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
// a data message to forward to an external app (or possibly also be consumed
|
|
|
|
// internally in the case of CLEAR_TEXT and CLEAR_READACK
|
2020-03-02 17:47:10 +00:00
|
|
|
message Data {
|
2020-03-24 20:12:25 +00:00
|
|
|
enum Type {
|
|
|
|
/// A message sent from a device outside of the mesh, in a form the mesh
|
|
|
|
/// does not understand
|
2020-04-28 16:19:19 +00:00
|
|
|
OPAQUE = 0; // NOTE: This must be 0, because it is documented in
|
2020-05-30 23:03:35 +00:00
|
|
|
// IMeshService.aidl to be so
|
2020-03-24 20:12:25 +00:00
|
|
|
|
|
|
|
/// a simple UTF-8 text message, which even the little micros in the mesh
|
|
|
|
/// can understand and show on their screen eventually in some circumstances
|
|
|
|
/// even signal might send messages in this form (see below)
|
|
|
|
CLEAR_TEXT = 1;
|
|
|
|
|
|
|
|
/// a message receive acknowledgement, sent in cleartext - allows radio to
|
|
|
|
/// show user that a message has been read by the recipient, optional
|
|
|
|
CLEAR_READACK = 2;
|
|
|
|
|
2020-05-19 00:03:16 +00:00
|
|
|
/// Apps will eventually be able to register their own handlers for
|
|
|
|
/// particular payload type codes so multiple apps can share the same radio
|
|
|
|
/// (this will replace OPAQUE)
|
2020-03-24 20:12:25 +00:00
|
|
|
}
|
|
|
|
|
2020-06-03 20:56:54 +00:00
|
|
|
Type typ = 1; // required
|
2020-03-24 20:12:25 +00:00
|
|
|
bytes payload = 2; // required
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Broadcast when a newly powered mesh node wants to find a node num it can use
|
2020-03-24 20:12:25 +00:00
|
|
|
// Sent from the phone over bluetooth to set the user id for the owner of this
|
|
|
|
node.
|
|
|
|
// Also sent from nodes to each other when a new node signs on (so all clients
|
|
|
|
can have this info)
|
2020-03-02 17:47:10 +00:00
|
|
|
|
|
|
|
The algorithm is as follows:
|
2020-03-24 20:12:25 +00:00
|
|
|
* when a node starts up, it broadcasts their user and the normal flow is for all
|
|
|
|
other nodes to reply with their User as well (so the new node can build its node
|
|
|
|
db)
|
|
|
|
* If a node ever receives a User (not just the first broadcast) message where
|
|
|
|
the sender node number equals our node number, that indicates a collision has
|
|
|
|
occurred and the following steps should happen:
|
|
|
|
|
|
|
|
If the receiving node (that was already in the mesh)'s macaddr is LOWER than the
|
|
|
|
new User who just tried to sign in: it gets to keep its nodenum. We send a
|
|
|
|
broadcast message of OUR User (we use a broadcast so that the other node can
|
|
|
|
receive our message, considering we have the same id - it also serves to let
|
|
|
|
observers correct their nodedb) - this case is rare so it should be okay.
|
|
|
|
|
|
|
|
If any node receives a User where the macaddr is GTE than their local macaddr,
|
|
|
|
they have been vetoed and should pick a new random nodenum (filtering against
|
|
|
|
whatever it knows about the nodedb) and rebroadcast their User.
|
2020-03-02 17:47:10 +00:00
|
|
|
|
|
|
|
A few nodenums are reserved and will never be requested:
|
|
|
|
0xff - broadcast
|
|
|
|
0 through 3 - for future use
|
|
|
|
|
|
|
|
*/
|
|
|
|
message User {
|
2020-03-24 20:12:25 +00:00
|
|
|
string id = 1; // a globally unique ID string for this user. In the case of
|
2020-05-30 23:03:35 +00:00
|
|
|
// Signal that would mean +16504442323, for the default macaddr
|
|
|
|
// derived id it would be !<6 hexidecimal bytes>
|
2020-06-03 20:56:54 +00:00
|
|
|
string long_name = 2; // A full name for this user, i.e. "Kevin Hester"
|
2020-03-24 20:12:25 +00:00
|
|
|
string short_name = 3; // A VERY short name, ideally two characters. Suitable
|
2020-05-30 23:03:35 +00:00
|
|
|
// for a tiny OLED screen
|
|
|
|
bytes macaddr = 4; // This is the addr of the radio. Not populated by the
|
|
|
|
// phone, but added by the esp32 when broadcasting
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
2020-04-17 16:48:14 +00:00
|
|
|
/// A message used in our Dynamic Source Routing protocol (RFC 4728 based)
|
|
|
|
message RouteDiscovery {
|
|
|
|
|
|
|
|
/**
|
|
|
|
The list of nodes this packet has visited so far
|
|
|
|
*/
|
|
|
|
repeated int32 route = 2;
|
|
|
|
}
|
|
|
|
|
2020-05-23 22:39:38 +00:00
|
|
|
enum RouteError {
|
|
|
|
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;
|
2020-05-24 00:38:49 +00:00
|
|
|
|
|
|
|
TIMEOUT = 3;
|
2020-05-23 22:39:38 +00:00
|
|
|
}
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
// 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)
|
2020-03-02 17:47:10 +00:00
|
|
|
message SubPacket {
|
2020-03-24 20:12:25 +00:00
|
|
|
|
2020-05-12 20:34:44 +00:00
|
|
|
// Only one of the following fields can be populated at a time
|
|
|
|
oneof payload {
|
2020-04-17 16:48:14 +00:00
|
|
|
|
2020-05-12 20:34:44 +00:00
|
|
|
Position position = 1;
|
|
|
|
Data data = 3;
|
|
|
|
User user = 4;
|
2020-05-11 22:40:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
A route request going from the requester
|
|
|
|
*/
|
2020-05-23 22:39:38 +00:00
|
|
|
RouteDiscovery route_request = 6;
|
2020-05-11 22:40:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
A route reply
|
|
|
|
*/
|
2020-05-23 22:39:38 +00:00
|
|
|
RouteDiscovery route_reply = 7;
|
|
|
|
|
|
|
|
/**
|
|
|
|
A failure in a routed message
|
|
|
|
*/
|
|
|
|
RouteError route_error = 13;
|
2020-05-11 22:40:04 +00:00
|
|
|
}
|
2020-04-17 16:48:14 +00:00
|
|
|
|
2020-05-12 20:34:44 +00:00
|
|
|
/// 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
|
|
|
|
/// its position).
|
|
|
|
// Note: that if you set this on a broadcast you will receive many replies.
|
|
|
|
// FIXME - unify (i.e. remove) this with the new reliable messaging at the
|
|
|
|
// MeshPacket level
|
|
|
|
bool want_response = 5;
|
2020-04-17 16:48:14 +00:00
|
|
|
|
2020-05-12 20:34:44 +00:00
|
|
|
oneof 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.
|
|
|
|
*/
|
|
|
|
uint32 success_id = 10;
|
|
|
|
|
|
|
|
/** This is a nak, we failed to deliver this message.
|
|
|
|
*/
|
|
|
|
uint32 fail_id = 11;
|
|
|
|
}
|
2020-04-17 16:48:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
The address of the destination node.
|
2020-05-21 19:31:54 +00:00
|
|
|
|
2020-04-17 16:48:14 +00:00
|
|
|
This field is is filled in by the mesh radio device software, applicaiton
|
|
|
|
layer software should never need it.
|
2020-05-21 19:31:54 +00:00
|
|
|
|
|
|
|
RouteDiscovery messages _must_ populate this. Other message types might need
|
|
|
|
to if they are doing multihop routing.
|
2020-04-17 16:48:14 +00:00
|
|
|
*/
|
2020-05-11 22:40:04 +00:00
|
|
|
uint32 dest = 9;
|
2020-05-23 22:39:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
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;
|
2020-05-24 00:38:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
Only used in route_error messages. Indicates the original message ID that
|
|
|
|
this message is reporting failure on.
|
|
|
|
*/
|
|
|
|
uint32 original_id = 2;
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
2020-04-17 16:48:14 +00:00
|
|
|
// A full packet sent/received over the mesh
|
2020-03-24 20:12:25 +00:00
|
|
|
// Note: For simplicity reasons (and that we want to keep over the radio packets
|
|
|
|
// very small, we now assume that there is only _one_ SubPacket in each
|
2020-04-17 16:48:14 +00:00
|
|
|
// MeshPacket).
|
2020-03-02 17:47:10 +00:00
|
|
|
message MeshPacket {
|
2020-04-17 16:48:14 +00:00
|
|
|
|
2020-05-09 23:14:30 +00:00
|
|
|
/**
|
|
|
|
The sending node number.
|
|
|
|
|
|
|
|
Note: Our crypto implementation uses this field as well. See
|
|
|
|
docs/software/crypto.md for details.
|
|
|
|
*/
|
2020-06-06 20:15:15 +00:00
|
|
|
uint32 from = 1; // FIXME - really should be fixed32 instead, this encoding
|
|
|
|
// only hurts the ble link though.
|
2020-04-17 16:48:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
The (immediate) destination for this packet. If we are using routing, the
|
|
|
|
final destination will be in payload.dest
|
|
|
|
*/
|
2020-06-06 20:15:15 +00:00
|
|
|
uint32 to = 2; // FIXME - really should be fixed32 instead, this encoding only
|
|
|
|
// hurts the ble link though.
|
2020-03-24 20:12:25 +00:00
|
|
|
|
2020-05-10 00:07:47 +00:00
|
|
|
/**
|
2020-05-10 02:06:45 +00:00
|
|
|
Internally to the mesh radios we will route SubPackets encrypted per
|
2020-05-10 00:07:47 +00:00
|
|
|
docs/software/crypto.md. However, when a particular node has the correct
|
|
|
|
key to decode a particular packet, it will decode the payload into a SubPacket
|
2020-05-10 02:06:45 +00:00
|
|
|
protobuf structure.
|
2020-05-10 00:07:47 +00:00
|
|
|
|
2020-05-10 02:06:45 +00:00
|
|
|
Software outside of the device nodes will never encounter a packet where
|
|
|
|
"decoded" is not populated (i.e. any encryption/decryption happens before
|
|
|
|
reaching the applications)
|
2020-05-10 00:07:47 +00:00
|
|
|
|
2020-05-10 02:06:45 +00:00
|
|
|
The numeric IDs for these fields were selected to keep backwards compatibility
|
|
|
|
with old applications.
|
2020-05-10 00:07:47 +00:00
|
|
|
*/
|
2020-05-10 02:06:45 +00:00
|
|
|
oneof payload {
|
2020-05-10 00:07:47 +00:00
|
|
|
SubPacket decoded = 3;
|
|
|
|
bytes encrypted = 8;
|
2020-05-10 02:06:45 +00:00
|
|
|
}
|
2020-03-24 20:12:25 +00:00
|
|
|
|
2020-04-17 00:31:45 +00:00
|
|
|
/**
|
|
|
|
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).
|
2020-05-09 23:14:30 +00:00
|
|
|
|
|
|
|
Note: Our crypto implementation uses this id as well. See
|
|
|
|
docs/software/crypto.md for details.
|
2020-04-17 00:31:45 +00:00
|
|
|
*/
|
2020-06-06 20:15:15 +00:00
|
|
|
uint32 id = 6; // FIXME - really should be fixed32 instead, this encoding only
|
|
|
|
// hurts the ble link though.
|
2020-04-30 19:34:49 +00:00
|
|
|
|
2020-05-11 22:40:04 +00:00
|
|
|
/// 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)
|
|
|
|
fixed32 rx_time = 9;
|
|
|
|
|
2020-04-30 19:34:49 +00:00
|
|
|
/// *Never* sent over the radio links. Set during reception to indicate the
|
|
|
|
/// SNR
|
|
|
|
/// of this packet. Used to collect statistics on current link waulity.
|
|
|
|
float rx_snr = 7;
|
2020-05-12 20:34:44 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
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.
|
|
|
|
|
2020-05-19 17:27:02 +00:00
|
|
|
This field is normally placed into a few of bits in the header.
|
2020-05-12 20:34:44 +00:00
|
|
|
*/
|
|
|
|
uint32 hop_limit = 10;
|
2020-05-19 17:27:02 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
This packet is being sent as a reliable message, we would prefer it to arrive
|
|
|
|
at the destination. We would like to receive a ack packet in response.
|
|
|
|
|
2020-05-21 19:31:54 +00:00
|
|
|
Broadcasts messages treat this flag specially: Since acks for broadcasts would
|
|
|
|
rapidly flood the channel, the normal ack behavior is suppressed. Instead,
|
|
|
|
the original sender listens to see if at least one node is rebroadcasting this
|
|
|
|
packet (because naive flooding algoritm). If it hears that the odds (given
|
|
|
|
typical LoRa topologies) the odds are very high that every node should
|
|
|
|
eventually receive the message. So FloodingRouter.cpp generates an implicit
|
|
|
|
ack which is delivered to the original sender. If after some time we don't
|
|
|
|
hear anyone rebroadcast our packet, we will timeout and retransmit, using the
|
|
|
|
regular resend logic.
|
|
|
|
|
2020-05-19 17:27:02 +00:00
|
|
|
Note: This flag is normally sent in a flag bit in the header when sent over
|
|
|
|
the wire
|
|
|
|
*/
|
|
|
|
bool want_ack = 11;
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Shared constants between device and phone
|
|
|
|
enum Constants {
|
2020-03-24 20:12:25 +00:00
|
|
|
Unused = 0; // First enum must be zero, and we are just using this enum to
|
2020-05-30 23:03:35 +00:00
|
|
|
// pass int constants between two very different environments
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
// Full settings (center freq, spread factor, pre-shared secret key etc...)
|
|
|
|
// needed to configure a radio for speaking on a particlar channel This
|
|
|
|
// information can be encoded as a QRcode/url so that other users can configure
|
|
|
|
// their radio to join the same channel.
|
2020-03-02 17:47:10 +00:00
|
|
|
message ChannelSettings {
|
2020-03-24 20:12:25 +00:00
|
|
|
int32 tx_power = 1;
|
|
|
|
|
|
|
|
// We now select channel number by hashing the name of the channel. We do
|
|
|
|
// this on the device and it is opaque to the phone. Therefore no need to
|
|
|
|
// show this in channel settings uint32 channel_num = 2;
|
|
|
|
|
|
|
|
enum ModemConfig {
|
|
|
|
// Note: these mappings must match ModemConfigChoice in the device code.
|
2020-05-30 23:03:35 +00:00
|
|
|
Bw125Cr45Sf128 = 0; ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC
|
|
|
|
///< on. Default medium range
|
|
|
|
Bw500Cr45Sf128 = 1; ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC
|
|
|
|
///< on. Fast+short range
|
2020-03-24 20:12:25 +00:00
|
|
|
Bw31_25Cr48Sf512 = 2; ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol,
|
2020-05-30 23:03:35 +00:00
|
|
|
///< CRC on. Slow+long range
|
2020-03-24 20:12:25 +00:00
|
|
|
Bw125Cr48Sf4096 = 3; ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC
|
2020-05-30 23:03:35 +00:00
|
|
|
///< on. Slow+long range
|
2020-03-24 20:12:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// This value replaces bandwidth/spread_factor/coding_rate. If you'd like to
|
|
|
|
/// experiment with other options add them to MeshRadio.cpp in the device
|
|
|
|
/// code.
|
|
|
|
ModemConfig modem_config = 3;
|
|
|
|
// uint32 bandwidth = 5;
|
|
|
|
// int32 spread_factor = 6;
|
|
|
|
// int32 coding_rate = 7;
|
|
|
|
|
2020-05-10 02:06:45 +00:00
|
|
|
/// A simple preshared key for now for crypto. Must be either 0 bytes (no
|
|
|
|
/// crypto), 16 bytes (AES128), or 32 bytes (AES256)
|
2020-03-24 20:12:25 +00:00
|
|
|
bytes psk = 4;
|
|
|
|
|
|
|
|
/// A SHORT name that will be packed into the URL. Less than 12 bytes.
|
|
|
|
/// Something for end users to call the channel
|
|
|
|
string name = 5;
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
// The entire set of user settable/readable settings for our radio device.
|
|
|
|
// Includes both the current channel settings and any preferences the user has
|
|
|
|
// set for behavior of their node
|
2020-03-02 17:47:10 +00:00
|
|
|
message RadioConfig {
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
message UserPreferences {
|
|
|
|
// We should send our position this often (but only if it has changed
|
|
|
|
// significantly)
|
|
|
|
uint32 position_broadcast_secs = 1;
|
|
|
|
|
|
|
|
// Send our owner info at least this often (also we always send once at boot
|
|
|
|
// - to rejoin the mesh)
|
|
|
|
uint32 send_owner_interval = 2;
|
|
|
|
|
|
|
|
/// If we miss this many owner messages from a node, we declare the node
|
|
|
|
/// offline (defaults to 3 - to allow for some lost packets)
|
|
|
|
uint32 num_missed_to_fail = 3;
|
|
|
|
|
|
|
|
/// see sw-design.md
|
|
|
|
uint32 wait_bluetooth_secs = 4;
|
|
|
|
uint32 screen_on_secs = 5;
|
|
|
|
uint32 phone_timeout_secs = 6;
|
|
|
|
uint32 phone_sds_timeout_sec = 7;
|
|
|
|
uint32 mesh_sds_timeout_secs = 8;
|
|
|
|
uint32 sds_secs = 9;
|
|
|
|
uint32 ls_secs = 10;
|
|
|
|
uint32 min_wake_secs = 11;
|
|
|
|
|
|
|
|
// If true, radio should not try to be smart about what packets to queue to
|
|
|
|
// the phone
|
|
|
|
bool keep_all_packets = 100;
|
|
|
|
|
|
|
|
// If true, we will try to capture all the packets sent on the mesh, not
|
|
|
|
// just the ones destined to our node.
|
|
|
|
bool promiscuous_mode = 101;
|
2020-05-23 16:24:54 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
For testing it is useful sometimes to force a node to never listen to
|
|
|
|
particular other nodes (simulating radio out of range). All nodenums listed
|
|
|
|
in ignore_incoming will have packets they send droped on receive (by
|
|
|
|
router.cpp)
|
|
|
|
*/
|
|
|
|
repeated uint32 ignore_incoming = 102;
|
2020-03-24 20:12:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UserPreferences preferences = 1;
|
|
|
|
ChannelSettings channel_settings = 2;
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
The bluetooth to device link:
|
|
|
|
|
|
|
|
Old BTLE protocol docs from TODO, merge in above and make real docs...
|
|
|
|
|
|
|
|
use protocol buffers, and NanoPB
|
|
|
|
|
|
|
|
messages from device to phone:
|
|
|
|
POSITION_UPDATE (..., time)
|
|
|
|
TEXT_RECEIVED(from, text, time)
|
|
|
|
OPAQUE_RECEIVED(from, payload, time) (for signal messages or other applications)
|
|
|
|
|
|
|
|
messages from phone to device:
|
2020-03-24 20:12:25 +00:00
|
|
|
SET_MYID(id, human readable long, human readable short) (send down the unique ID
|
|
|
|
string used for this node, a human readable string shown for that id, and a very
|
|
|
|
short human readable string suitable for oled screen) SEND_OPAQUE(dest, payload)
|
|
|
|
(for signal messages or other applications) SEND_TEXT(dest, text) Get all
|
|
|
|
nodes() (returns list of nodes, with full info, last time seen, loc, battery
|
|
|
|
level etc) SET_CONFIG (switches device to a new set of radio params and
|
|
|
|
preshared key, drops all existing nodes, force our node to rejoin this new
|
|
|
|
group)
|
2020-03-02 17:47:10 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Full information about a node on the mesh
|
|
|
|
message NodeInfo {
|
2020-05-11 22:40:04 +00:00
|
|
|
uint32 num = 1; // the node number
|
2020-03-24 20:12:25 +00:00
|
|
|
User user = 2;
|
|
|
|
|
|
|
|
/// This position data will also contain a time last seen
|
|
|
|
Position position = 3;
|
|
|
|
|
|
|
|
/// Returns the Signal-to-noise ratio (SNR) of the last received message, as
|
|
|
|
/// measured by the receiver. return SNR of the last received message in dB
|
2020-04-30 19:34:49 +00:00
|
|
|
float snr = 7;
|
2020-03-24 20:12:25 +00:00
|
|
|
|
|
|
|
/// Returns the last measured frequency error.
|
|
|
|
/// The LoRa receiver estimates the frequency offset between the receiver
|
|
|
|
/// centre frequency and that of the received LoRa signal. This function
|
|
|
|
/// returns the estimates offset (in Hz) of the last received message.
|
|
|
|
/// Caution: this measurement is not absolute, but is measured relative to the
|
|
|
|
/// local receiver's oscillator. Apparent errors may be due to the
|
|
|
|
/// transmitter, the receiver or both. \return The estimated centre frequency
|
|
|
|
/// offset in Hz of the last received message.
|
2020-04-30 19:34:49 +00:00
|
|
|
// int32 frequency_error = 6;
|
2020-05-11 22:40:04 +00:00
|
|
|
|
|
|
|
/* enum RouteState {
|
|
|
|
Invalid = 0;
|
|
|
|
Discovering = 1;
|
|
|
|
Valid = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
Not needed?
|
|
|
|
RouteState route = 4; */
|
|
|
|
|
|
|
|
/// Our current preferred node node for routing - might be the same as num if
|
|
|
|
/// we are adjacent Or zero if we don't yet know a route to this node.
|
|
|
|
uint32 next_hop = 5;
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Unique local debugging info for this node
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
Note: we don't include position or the user info, because that will come in the
|
2020-03-02 17:47:10 +00:00
|
|
|
|
|
|
|
Sent to the phone in response to WantNodes.
|
|
|
|
*/
|
|
|
|
message MyNodeInfo {
|
2020-03-24 20:12:25 +00:00
|
|
|
/// Tells the phone what our node number is, default starting value is lowbyte
|
|
|
|
/// of macaddr, but it will be fixed if that is already in use
|
2020-05-22 03:30:56 +00:00
|
|
|
uint32 my_node_num = 1;
|
2020-03-24 20:12:25 +00:00
|
|
|
|
|
|
|
/// if false it would be great if the phone can help provide gps coordinates
|
|
|
|
bool has_gps = 2;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// # of legal channels (set at build time in the device flash image)
|
|
|
|
int32 num_channels = 3;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// The region code for my radio (US, CN, etc...)
|
|
|
|
string region = 4;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// TBEAM, HELTEC, etc...
|
|
|
|
string hw_model = 5;
|
2020-03-03 14:54:14 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// 0.0.5 etc...
|
|
|
|
string firmware_version = 6;
|
2020-03-03 14:54:14 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// An error message we'd like to report back to the mothership through
|
|
|
|
/// analytics. It indicates a serious bug occurred on the device, the device
|
|
|
|
/// coped with it, but we still want to tell the devs about the bug. This
|
|
|
|
/// field will be cleared after the phone reads MyNodeInfo (i.e. it will only
|
|
|
|
/// be reported once) a numeric error code to go with error message, zero
|
|
|
|
/// means no error
|
|
|
|
uint32 error_code = 7;
|
2020-03-03 14:54:14 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// A numeric error address (nonzero if available)
|
|
|
|
uint32 error_address = 8;
|
|
|
|
|
2020-03-24 20:22:16 +00:00
|
|
|
/// The total number of errors this node has ever encountered (well - since
|
|
|
|
/// the last time we discarded preferences)
|
|
|
|
uint32 error_count = 9;
|
|
|
|
|
2020-06-03 20:56:54 +00:00
|
|
|
/** How many bits are used for the packetid. If zero it is assumed we use
|
|
|
|
eight bit packetids Old device loads (older that 0.6.5 do not populate this
|
|
|
|
field, but all newer loads do). */
|
2020-05-30 23:15:27 +00:00
|
|
|
uint32 packet_id_bits = 10;
|
|
|
|
|
2020-06-03 20:56:54 +00:00
|
|
|
/** The current ID this node is using for sending new packets (exposed so that
|
|
|
|
the phone can self assign packet IDs if it wishes by picking packet IDs from
|
|
|
|
the opposite side of the pacekt ID space).
|
2020-05-30 23:15:27 +00:00
|
|
|
|
2020-06-03 20:56:54 +00:00
|
|
|
Old device loads (older that 0.6.5 do not populate this field, but all newer
|
|
|
|
loads do).
|
2020-05-30 23:15:27 +00:00
|
|
|
|
2020-06-03 20:56:54 +00:00
|
|
|
FIXME: that we need to expose this is a bit of a mistake. Really the phones
|
|
|
|
should be modeled/treated as 1st class nodes like any other, and the radio
|
|
|
|
connected to the phone just routes like any other. This would allow all sorts
|
|
|
|
of clean/clever routing topologies in the future.
|
2020-05-30 23:15:27 +00:00
|
|
|
**/
|
|
|
|
uint32 current_packet_id = 11;
|
|
|
|
|
2020-06-03 20:56:54 +00:00
|
|
|
/** How many bits are used for the nodenum. If zero it is assumed we use
|
|
|
|
eight bit nodenums New device loads will user 32 bit nodenum.
|
|
|
|
Old device loads (older that 0.6.5 do not populate this field, but all newer
|
|
|
|
loads do). */
|
2020-05-30 23:15:27 +00:00
|
|
|
uint32 node_num_bits = 12;
|
2020-05-30 23:03:35 +00:00
|
|
|
|
2020-06-03 20:56:54 +00:00
|
|
|
/** How long before we consider a message abandoned and we can clear our
|
|
|
|
caches of any messages in flight Normally quite large to handle the worst case
|
|
|
|
message delivery time, 5 minutes. Formerly called FLOOD_EXPIRE_TIME in the
|
|
|
|
device code
|
2020-05-31 02:04:33 +00:00
|
|
|
*/
|
|
|
|
uint32 message_timeout_msec = 13;
|
|
|
|
|
2020-06-03 20:56:54 +00:00
|
|
|
/** The minimum app version that can talk to this device. Android apps should
|
|
|
|
compare this to their build number and if too low tell the user they must
|
|
|
|
update their app
|
|
|
|
*/
|
|
|
|
uint32 min_app_version = 14;
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// FIXME - add more useful debugging state (queue depths etc)
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
// This message is never sent over the wire, but it is used for serializing DB
|
|
|
|
// state to flash in the device code
|
|
|
|
// FIXME, since we write this each time we enter deep sleep (and have infinite
|
|
|
|
// flash) it would be better to use some sort of append only data structure for
|
|
|
|
// the receive queue and use the preferences store for the other stuff
|
2020-03-02 17:47:10 +00:00
|
|
|
message DeviceState {
|
2020-03-24 20:12:25 +00:00
|
|
|
RadioConfig radio = 1;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// Read only settings/info about this node
|
|
|
|
MyNodeInfo my_node = 2;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// My owner info
|
|
|
|
User owner = 3;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
repeated NodeInfo node_db = 4;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// Received packets saved for delivery to the phone
|
|
|
|
repeated MeshPacket receive_queue = 5;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// A version integer used to invalidate old save files when we make
|
|
|
|
/// incompatible changes This integer is set at build time and is private to
|
|
|
|
/// NodeDB.cpp in the device code.
|
|
|
|
uint32 version = 8;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
/// We keep the last received text message (only) stored in the device flash,
|
|
|
|
/// so we can show it on the screen. Might be null
|
|
|
|
MeshPacket rx_text_message = 7;
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
2020-04-20 23:15:52 +00:00
|
|
|
/// Debug output from the device
|
|
|
|
message DebugString {
|
|
|
|
string message = 1;
|
|
|
|
|
|
|
|
// eventually we might add source and level
|
|
|
|
}
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
// packets from the radio to the phone will appear on the fromRadio
|
|
|
|
// characteristic. It will support READ and NOTIFY. When a new packet arrives
|
|
|
|
// the device will notify? possibly identify instead? it will sit in that
|
|
|
|
// descriptor until consumed by the phone, at which point the next item in the
|
|
|
|
// FIFO will be populated. FIXME
|
2020-03-02 17:47:10 +00:00
|
|
|
message FromRadio {
|
2020-03-24 20:12:25 +00:00
|
|
|
// The packet num, used to allow the phone to request missing read packets
|
|
|
|
// from the FIFO, see our bluetooth docs
|
|
|
|
uint32 num = 1;
|
|
|
|
|
|
|
|
oneof variant {
|
|
|
|
MeshPacket packet = 2;
|
|
|
|
|
|
|
|
/// Tells the phone what our node number is, can be -1 if we've not yet
|
|
|
|
/// joined a mesh.
|
2020-04-20 23:15:52 +00:00
|
|
|
// REV2: In the rev 1 API this is in the BLE mynodeinfo characteristic
|
|
|
|
MyNodeInfo my_info = 3;
|
2020-03-24 20:12:25 +00:00
|
|
|
|
|
|
|
/// One packet is sent for each node in the on radio DB
|
2020-04-20 23:15:52 +00:00
|
|
|
// REV2: In the rev1 API this is available in the nodeinfo characteristic
|
|
|
|
// starts over with the first node in our DB
|
|
|
|
NodeInfo node_info = 4;
|
|
|
|
|
|
|
|
/// REV2: In rev1 this was the Owner BLE characteristic
|
2020-04-23 00:56:10 +00:00
|
|
|
// Note: there is no separate payload for reading the owner, it comes
|
|
|
|
// implicitly as part of the NodeInfo for whichever node corresponds to our
|
|
|
|
// device. User owner = 5;
|
2020-04-20 23:15:52 +00:00
|
|
|
|
|
|
|
/// REV2: In rev1 this was the radio BLE characteristic
|
|
|
|
RadioConfig radio = 6;
|
|
|
|
|
2020-04-21 02:31:09 +00:00
|
|
|
/// REV2: set to send debug console output over our protobuf stream
|
2020-04-20 23:15:52 +00:00
|
|
|
DebugString debug_string = 7;
|
|
|
|
|
|
|
|
/// REV2: sent as true once the device has finished sending all of the
|
|
|
|
/// responses to want_config
|
2020-04-21 02:31:09 +00:00
|
|
|
/// recipient should check if this ID matches our original request nonce, if
|
|
|
|
/// not, it means your config responses haven't started yet
|
|
|
|
uint32 config_complete_id = 8;
|
2020-04-29 00:34:06 +00:00
|
|
|
|
|
|
|
/// Sent to tell clients the radio has just rebooted. Set to true if
|
|
|
|
/// present. Not used on all transports, currently just used for the serial
|
|
|
|
/// console.
|
|
|
|
bool rebooted = 9;
|
2020-03-24 20:12:25 +00:00
|
|
|
}
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
// packets/commands to the radio will be written (reliably) to the toRadio
|
|
|
|
// characteristic. Once the write completes the phone can assume it is handled.
|
2020-03-02 17:47:10 +00:00
|
|
|
message ToRadio {
|
|
|
|
|
2020-03-24 20:12:25 +00:00
|
|
|
oneof variant {
|
|
|
|
MeshPacket packet = 1; // send this packet on the mesh
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-04-20 23:15:52 +00:00
|
|
|
/// REV2: 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
|
2020-04-21 02:31:09 +00:00
|
|
|
/// 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.
|
|
|
|
uint32 want_config_id = 100;
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-04-20 23:15:52 +00:00
|
|
|
/// REV2: In rev1 this was the radio config characteristic
|
|
|
|
RadioConfig set_radio = 101; // set the radio provisioning for this node
|
2020-03-02 17:47:10 +00:00
|
|
|
|
2020-04-20 23:15:52 +00:00
|
|
|
/// REV2: In rev1 this was the owner characteristic
|
|
|
|
User set_owner = 102; // Set the owner for this node
|
2020-03-24 20:12:25 +00:00
|
|
|
}
|
2020-03-02 17:47:10 +00:00
|
|
|
}
|
2020-05-19 00:03:16 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
Placeholder for data we will eventually set during initial programming. This
|
|
|
|
will allow us to stop having a load for each region.
|
|
|
|
*/
|
|
|
|
message ManufacturingData {
|
2020-05-19 17:27:02 +00:00
|
|
|
/// center frequency for the radio hardware that was stuffed
|
|
|
|
uint32 fradioFreq = 1;
|
2020-05-19 00:03:16 +00:00
|
|
|
|
|
|
|
/// TBEAM, HELTEC, etc...
|
|
|
|
string hw_model = 2;
|
|
|
|
|
|
|
|
// Hardware version number
|
|
|
|
string hw_version = 3;
|
|
|
|
|
|
|
|
/**
|
|
|
|
This code is written during manfacturing time and allows users to confirm that
|
|
|
|
the initial manufacturing tests succeeded.
|
|
|
|
|
|
|
|
0 means no test performed.
|
|
|
|
1 means all tests passed
|
|
|
|
negative numbers indicate particular error codes
|
|
|
|
*/
|
|
|
|
sint32 selftest_result = 4;
|
|
|
|
}
|