mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
208 lines
8.4 KiB
Protocol Buffer
208 lines
8.4 KiB
Protocol Buffer
syntax = "proto3";
|
|
// per https://developers.google.com/protocol-buffers/docs/proto3
|
|
|
|
package mesh;
|
|
|
|
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...
|
|
|
|
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.
|
|
|
|
once in that group, we can talk between 254 node numbers.
|
|
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
|
|
rejoined the network) can build a map of all participants.
|
|
|
|
We will periodically broadcast POSITION-UPDATE as needed based on distance moved or a periodic minimum heartbeat.
|
|
|
|
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.
|
|
*/
|
|
|
|
// a gps position
|
|
message Position {
|
|
double latitude = 1;
|
|
double longitude = 2;
|
|
int32 altitude = 3;
|
|
int32 battery_level = 4; // 0-100
|
|
}
|
|
|
|
// 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)
|
|
message Time {
|
|
uint64 msecs = 1; // msecs since 1970
|
|
}
|
|
|
|
// 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 {
|
|
enum Type {
|
|
/// A message sent from a device outside of the mesh, in a form the mesh does not understand
|
|
SIGNAL_OPAQUE = 0; // NOTE: This must be 0, because it is documented in IMeshService.aidl to be so
|
|
|
|
/// 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;
|
|
|
|
/// Not yet used but eventually:
|
|
/// SIGNAL_CLEAR_DATA = 3; // Unencrypted at the signal level, relying on the radio crypt only (to keep size small), but contains Signal control data radios don't care about (ie non text)
|
|
}
|
|
|
|
Type typ = 1; // required
|
|
bytes payload = 2; // required
|
|
}
|
|
|
|
// 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)
|
|
message User {
|
|
string id = 1; // a globally unique ID string for this user. In the case of Signal that would mean +16504442323
|
|
string long_name = 2; // A full name for this user, i.e. "Kevin Hester"
|
|
string short_name = 3; // A VERY short name, ideally two characters. Suitable for a tiny OLED screen
|
|
}
|
|
|
|
// Broadcast when a newly powered mesh node wants to find a node num it can use (see document for more
|
|
// details)
|
|
message WantNodeNum {
|
|
// No payload, just its existence is sufficient (desired node num will be in the from field)
|
|
}
|
|
|
|
// Sent to a node which has requested a nodenum when it is told it can't have it
|
|
message DenyNodeNum {
|
|
}
|
|
|
|
// A single packet might have a series of SubPacket included
|
|
message SubPacket {
|
|
oneof variant {
|
|
Position position = 1;
|
|
Time time = 2;
|
|
Data data = 3;
|
|
User user = 4;
|
|
WantNodeNum want_node = 5;
|
|
DenyNodeNum deny_node = 6;
|
|
}
|
|
}
|
|
|
|
// A packet sent over our mesh.
|
|
// NOTE: this raw payload does not include the from and to addresses, which are stripped off
|
|
// and passed into the mesh library code separately.
|
|
message MeshPayload {
|
|
repeated SubPacket subPackets = 3;
|
|
}
|
|
|
|
// A full packet sent/received over the mesh
|
|
message MeshPacket {
|
|
int32 from = 1;
|
|
int32 to = 2;
|
|
MeshPayload payload = 3;
|
|
}
|
|
|
|
// Full settings (center freq, spread factor, pre-shared secret key etc...) needed to configure a radio
|
|
message RadioConfig {
|
|
// FIXME
|
|
|
|
// 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;
|
|
}
|
|
|
|
/**
|
|
|
|
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:
|
|
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)
|
|
|
|
*/
|
|
|
|
// Full information about a node on the mesh
|
|
message NodeInfo {
|
|
int32 num = 1; // the node number
|
|
User user = 2;
|
|
Position position = 4;
|
|
Time last_seen = 5;
|
|
}
|
|
|
|
// 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
|
|
message FromRadio {
|
|
// 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.
|
|
sint32 my_node_num = 3;
|
|
|
|
/// One packet is sent for each node in the on radio DB
|
|
NodeInfo node_info = 4;
|
|
}
|
|
}
|
|
|
|
// packets/commands to the radio will be written (reliably) to the toRadio characteristic. Once the
|
|
// write completes the phone can assume it is handled.
|
|
message ToRadio {
|
|
|
|
// If sent to the radio, the radio will send the phone its full node DB (NodeInfo records)
|
|
// Used to populate network info the first time the phone connects to the radio
|
|
message WantNodes {
|
|
// Empty
|
|
}
|
|
|
|
oneof variant {
|
|
MeshPacket packet = 1; // send this packet on the mesh
|
|
|
|
//
|
|
// Rare operations
|
|
//
|
|
|
|
/// 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 FromRadio.my_node_num and a series of FromRadio.node_info
|
|
WantNodes want_nodes = 100;
|
|
|
|
RadioConfig set_radio = 101; // set the radio provisioning for this node
|
|
User set_owner = 102; // Set the owner for this node
|
|
}
|
|
}
|
|
|