add beginnings of nodedb

This commit is contained in:
geeksville
2020-02-03 09:13:19 -08:00
parent e6535f5504
commit d11b023c85
8 changed files with 194 additions and 51 deletions

View File

@@ -7,27 +7,15 @@
#include <pb_decode.h>
#include "MeshRadio.h"
#include "configuration.h"
#include "NodeDB.h"
// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0
/**
* 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)
*/
NodeNum getDesiredNodeNum()
{
uint8_t dmac[6];
esp_efuse_mac_get_default(dmac);
// FIXME not the right way to guess node numes
uint8_t r = dmac[5];
assert(r != 0xff); // It better not be the broadcast address
return r;
}
MeshRadio::MeshRadio(MemoryPool<MeshPacket> &_pool, PointerQueue<MeshPacket> &_rxDest)
: rf95(NSS_GPIO, DIO0_GPIO),
manager(rf95, getDesiredNodeNum()),
manager(rf95, nodeDB.getNodeNum()),
pool(_pool),
rxDest(_rxDest),
txQueue(MAX_TX_QUEUE)

View File

@@ -5,13 +5,9 @@
#include "MemoryPool.h"
#include "mesh.pb.h"
#include "PointerQueue.h"
#include "MeshTypes.h"
#define NODENUM_BROADCAST 255
#define ERRNO_OK 0
#define ERRNO_UNKNOWN 32 // pick something that doesn't conflict with RH_ROUTER_ERROR_UNABLE_TO_DELIVER
typedef int ErrorCode;
typedef uint8_t NodeNum;
#define MAX_TX_QUEUE 8 // max number of packets which can be waiting for transmission

View File

@@ -4,9 +4,10 @@
#include <pb_encode.h>
#include <pb_decode.h>
#include "mesh.pb.h"
#include "mesh-pb-constants.h"
#include "MeshService.h"
#include "MeshBluetoothService.h"
#include "NodeDB.h"
/*
receivedPacketQueue - this is a queue of messages we've received from the mesh, which we are keeping to deliver to the phone.
@@ -17,40 +18,13 @@ of packets we can delete just as soon as we are sure the phone has acked those p
mesh - an instance of Mesh class. Which manages the interface to the mesh radio library, reception of packets from other nodes, arbitrating to select
a node number and keeping the current nodedb.
typedef in32_t NodeNum;
class NodeInfo {
position;
last_seen
user
};
class NodeDB {
NodeNum provisionalNodeNum; // if we are trying to find a node num this is our current attempt
NodeNum ourNodeNum; // -1 if not yet found
HashMap<NodeNum, NodeInfo> nodes;
public:
/// don't do mesh based algoritm for node id assignment (initially) - instead just store in flash - possibly even in the initial alpha release do this hack
/// if returns false, that means our node should send a DenyNodeNum response. If true, we think the number is okay for use
// bool handleWantNodeNum(NodeNum n);
void handleDenyNodeNum(NodeNum FIXME read mesh proto docs, perhaps picking a random node num is not a great idea
and instead we should use a special 'im unconfigured node number' and include our desired node number in the wantnum message. the
unconfigured node num would only be used while initially joining the mesh so low odds of conflicting (especially if we randomly select
from a small number of nodenums which can be used temporarily for this operation). figure out what the lower level
mesh sw does if it does conflict? would it be better for people who are replying with denynode num to just broadcast their denial?)
};
*/
MeshService service;
#define MAX_PACKETS 32 // max number of packets which can be in flight (either queued from reception or queued for sending)
#define MAX_RX_TOPHONE 16 // max number of packets which can be waiting for delivery to android
#define MAX_RX_FROMRADIO 4 // max number of packets destined to our queue, we dispatch packets quickly so it doesn't need to be big
MeshService::MeshService()
@@ -60,6 +34,7 @@ MeshService::MeshService()
fromNum(0),
radio(packetPool, fromRadioQueue)
{
// assert(MAX_RX_TOPHONE == 32); // FIXME, delete this, just checking my clever macro
}
void MeshService::init()

13
src/MeshTypes.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
// low level types
#include <Arduino.h>
typedef uint8_t NodeNum;
#define NODENUM_BROADCAST 255
#define ERRNO_OK 0
#define ERRNO_UNKNOWN 32 // pick something that doesn't conflict with RH_ROUTER_ERROR_UNABLE_TO_DELIVER
typedef int ErrorCode;

102
src/NodeDB.cpp Normal file
View File

@@ -0,0 +1,102 @@
#include <Arduino.h>
#include <assert.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include "mesh-pb-constants.h"
#include "NodeDB.h"
NodeDB nodeDB;
/**
* 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()
{
uint8_t dmac[6];
esp_efuse_mac_get_default(dmac);
// FIXME not the right way to guess node numes
uint8_t r = dmac[5];
assert(r != 0xff); // It better not be the broadcast address
return r;
}
NodeDB::NodeDB() : ourNodeNum(getDesiredNodeNum()), numNodes(0)
{
}
/// return number msecs since 1970
uint64_t getCurrentTime() {
return 4403; // FIXME
}
/// 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;
Serial.printf("Update DB node %x for %d\n", mp.from, p.which_variant);
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
info->last_seen.msecs = getCurrentTime();
info->has_last_seen = true;
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);
if (!n)
{
// 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;
}

52
src/NodeDB.h Normal file
View File

@@ -0,0 +1,52 @@
#pragma once
#include <Arduino.h>
#include <assert.h>
#include "mesh-pb-constants.h"
#include "MeshTypes.h"
class NodeDB {
// NodeNum provisionalNodeNum; // if we are trying to find a node num this is our current attempt
NodeNum ourNodeNum; // -1 if not yet found
// A NodeInfo for every node we've seen
// Eventually use a smarter datastructure
// HashMap<NodeNum, NodeInfo> nodes;
NodeInfo nodes[MAX_NUM_NODES];
int numNodes;
bool updateGUI; // we think the gui should definitely be redrawn
NodeInfo *updateGUIforNode; // if currently showing this node, we think you should update the GUI
public:
/// don't do mesh based algoritm for node id assignment (initially)
/// instead just store in flash - possibly even in the initial alpha release do this hack
NodeDB();
/// 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 updateFrom(const MeshPacket &p);
NodeNum getNodeNum() { return ourNodeNum; }
/// if returns false, that means our node should send a DenyNodeNum response. If true, we think the number is okay for use
// bool handleWantNodeNum(NodeNum n);
/* void handleDenyNodeNum(NodeNum FIXME read mesh proto docs, perhaps picking a random node num is not a great idea
and instead we should use a special 'im unconfigured node number' and include our desired node number in the wantnum message. the
unconfigured node num would only be used while initially joining the mesh so low odds of conflicting (especially if we randomly select
from a small number of nodenums which can be used temporarily for this operation). figure out what the lower level
mesh sw does if it does conflict? would it be better for people who are replying with denynode num to just broadcast their denial?)
*/
private:
/// Find a node in our DB, return null for missing
NodeInfo *getNode(NodeNum n);
/// Find a node in our DB, create an empty NodeInfo if missing
NodeInfo *getOrCreateNode(NodeNum n);
};
extern NodeDB nodeDB;

14
src/mesh-pb-constants.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#include "mesh.pb.h"
// this file defines constants which come from mesh.options
// Tricky macro to let you find the sizeof a type member
#define member_size(type, member) sizeof(((type *)0)->member)
/// max number of packets which can be waiting for delivery to android - note, this value comes from mesh.options protobuf
#define MAX_RX_TOPHONE (member_size(DeviceState, receive_queue) / member_size(DeviceState, receive_queue[0]))
/// max number of nodes allowed in the mesh
#define MAX_NUM_NODES (member_size(DeviceState, node_db) / member_size(DeviceState, node_db[0]))