2020-02-03 17:13:19 +00:00
|
|
|
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include <pb_encode.h>
|
|
|
|
#include <pb_decode.h>
|
2020-02-04 16:17:44 +00:00
|
|
|
#include "configuration.h"
|
2020-02-03 17:13:19 +00:00
|
|
|
#include "mesh-pb-constants.h"
|
|
|
|
#include "NodeDB.h"
|
2020-02-06 16:18:20 +00:00
|
|
|
#include "GPS.h"
|
2020-02-03 17:13:19 +00:00
|
|
|
|
2020-02-03 19:53:38 +00:00
|
|
|
MyNodeInfo myNodeInfo = MyNodeInfo_init_zero;
|
2020-02-03 17:13:19 +00:00
|
|
|
NodeDB nodeDB;
|
2020-02-04 17:00:17 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Normally userids are unique and start with +country code to look like Signal phone numbers.
|
|
|
|
* But there are some special ids used when we haven't yet been configured by a user. In that case
|
|
|
|
* we use !macaddr (no colons).
|
|
|
|
*/
|
|
|
|
User owner = {"+1650xxxyyyy", "unset name", "????", {0}};
|
|
|
|
|
|
|
|
static uint8_t ourMacAddr[6];
|
2020-02-03 17:13:19 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* get our starting (provisional) nodenum from flash. But check first if anyone else is using it, by trying to send a message to it (arping)
|
|
|
|
*/
|
|
|
|
static NodeNum getDesiredNodeNum()
|
|
|
|
{
|
2020-02-04 17:00:17 +00:00
|
|
|
esp_efuse_mac_get_default(ourMacAddr);
|
2020-02-03 17:13:19 +00:00
|
|
|
|
|
|
|
// FIXME not the right way to guess node numes
|
2020-02-04 17:00:17 +00:00
|
|
|
uint8_t r = ourMacAddr[5];
|
2020-02-06 18:58:19 +00:00
|
|
|
assert(r != 0xff && r != 0); // It better not be the broadcast address or zero
|
2020-02-03 17:13:19 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-02-04 17:00:17 +00:00
|
|
|
|
|
|
|
NodeDB::NodeDB()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void NodeDB::init() {
|
2020-02-04 21:47:42 +00:00
|
|
|
myNodeInfo.my_node_num = getDesiredNodeNum();
|
2020-02-04 17:00:17 +00:00
|
|
|
|
|
|
|
// Init our blank owner info to reasonable defaults
|
|
|
|
sprintf(owner.id, "!%02x%02x%02x%02x%02x%02x", ourMacAddr[0],
|
|
|
|
ourMacAddr[1], ourMacAddr[2], ourMacAddr[3], ourMacAddr[4], ourMacAddr[5]);
|
|
|
|
memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));
|
|
|
|
|
2020-02-06 18:58:19 +00:00
|
|
|
sprintf(owner.long_name, "Unknown %02x%02x", ourMacAddr[4], ourMacAddr[5]);
|
|
|
|
sprintf(owner.short_name, "?%02X", ourMacAddr[5]);
|
2020-02-04 17:00:17 +00:00
|
|
|
// FIXME, read owner info from flash
|
|
|
|
|
|
|
|
// Include our owner in the node db under our nodenum
|
2020-02-04 21:47:42 +00:00
|
|
|
NodeInfo *info = getOrCreateNode(getNodeNum());
|
2020-02-04 17:00:17 +00:00
|
|
|
info->user = owner;
|
|
|
|
info->has_user = true;
|
2020-02-06 16:18:20 +00:00
|
|
|
info->last_seen = 0; // haven't heard a real message yet
|
2020-02-04 17:00:17 +00:00
|
|
|
}
|
|
|
|
|
2020-02-04 05:03:20 +00:00
|
|
|
const NodeInfo *NodeDB::readNextInfo()
|
|
|
|
{
|
|
|
|
if (readPointer < numNodes)
|
|
|
|
return &nodes[readPointer++];
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-02-03 17:13:19 +00:00
|
|
|
/// given a subpacket sniffed from the network, update our DB state
|
|
|
|
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
|
|
|
|
void NodeDB::updateFrom(const MeshPacket &mp)
|
|
|
|
{
|
|
|
|
if (mp.has_payload)
|
|
|
|
{
|
|
|
|
const SubPacket &p = mp.payload;
|
2020-02-06 18:58:19 +00:00
|
|
|
DEBUG_MSG("Update DB node %x for variant %d\n", mp.from, p.which_variant);
|
2020-02-03 17:13:19 +00:00
|
|
|
if (p.which_variant != SubPacket_want_node_tag) // we don't create nodeinfo records for someone that is just trying to claim a nodenum
|
|
|
|
{
|
|
|
|
int oldNumNodes = numNodes;
|
|
|
|
NodeInfo *info = getOrCreateNode(mp.from);
|
|
|
|
|
|
|
|
if (oldNumNodes != numNodes)
|
|
|
|
updateGUI = true; // we just created a nodeinfo
|
|
|
|
|
2020-02-06 16:18:20 +00:00
|
|
|
info->last_seen = gps.getTime();
|
2020-02-04 05:03:20 +00:00
|
|
|
|
2020-02-03 17:13:19 +00:00
|
|
|
switch (p.which_variant)
|
|
|
|
{
|
|
|
|
case SubPacket_position_tag:
|
|
|
|
info->position = p.variant.position;
|
|
|
|
info->has_position = true;
|
|
|
|
updateGUIforNode = info;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SubPacket_user_tag:
|
|
|
|
info->user = p.variant.user;
|
|
|
|
info->has_user = true;
|
|
|
|
updateGUIforNode = info;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break; // Ignore other packet types
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Find a node in our DB, return null for missing
|
|
|
|
NodeInfo *NodeDB::getNode(NodeNum n)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < numNodes; i++)
|
|
|
|
if (nodes[i].num == n)
|
|
|
|
return &nodes[i];
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Find a node in our DB, create an empty NodeInfo if missing
|
|
|
|
NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
|
|
|
|
{
|
|
|
|
NodeInfo *info = getNode(n);
|
|
|
|
|
2020-02-04 17:00:17 +00:00
|
|
|
if (!info)
|
2020-02-03 17:13:19 +00:00
|
|
|
{
|
|
|
|
// add the node
|
|
|
|
assert(numNodes < MAX_NUM_NODES);
|
|
|
|
info = &nodes[numNodes++];
|
|
|
|
|
|
|
|
// everything is missing except the nodenum
|
|
|
|
memset(info, 0, sizeof(*info));
|
|
|
|
info->num = n;
|
|
|
|
}
|
|
|
|
|
|
|
|
return info;
|
|
|
|
}
|