From 634a547030881aec61e0cf5884aab06f5c63cb48 Mon Sep 17 00:00:00 2001 From: geeksville Date: Mon, 3 Feb 2020 21:03:20 -0800 Subject: [PATCH] implement nodeinfo ble charstic --- TODO.md | 1 + src/MeshBluetoothService.cpp | 44 ++++++++++++++++++++++++++++++++---- src/NodeDB.cpp | 15 +++++++++--- src/NodeDB.h | 23 +++++++++++++------ src/configuration.h | 17 -------------- 5 files changed, 69 insertions(+), 31 deletions(-) diff --git a/TODO.md b/TODO.md index c10dadee9..4272fcbfb 100644 --- a/TODO.md +++ b/TODO.md @@ -7,6 +7,7 @@ * implement getCurrentTime() - set based off gps but then updated locally * confirm second device receives that gps message and updates device db * pretty often send our position packet (but only if we've moved) +* port my graphics library over from the sw102, same screen controller and resolution * very occasionally send our position and user packet (if for nothing else so that other nodes update last_seen) * switch to my gui layout manager * have a state machine return the correct FromRadio packet to the phone, it isn't always going to be a MeshPacket. Do a notify on fromnum to force the radio to read our state machine generated packets diff --git a/src/MeshBluetoothService.cpp b/src/MeshBluetoothService.cpp index f71d2543f..ced1a7878 100644 --- a/src/MeshBluetoothService.cpp +++ b/src/MeshBluetoothService.cpp @@ -39,17 +39,52 @@ public: // dumpCharacteristic(pCharacteristic); Serial.println("Got on proto write"); std::string src = c->getValue(); - if (pb_decode_from_bytes((const uint8_t *)src.c_str(), src.length(), fields, my_struct)) { + if (pb_decode_from_bytes((const uint8_t *)src.c_str(), src.length(), fields, my_struct)) + { // Success, the bytes are now in our struct - do nothing else } } }; +class NodeInfoCharacteristic : public BLECharacteristic, public BLECharacteristicCallbacks +{ +public: + NodeInfoCharacteristic() + : BLECharacteristic("d31e02e0-c8ab-4d3f-9cc9-0b8466bdabe8", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ) + { + setCallbacks(this); + } + + void onRead(BLECharacteristic *c) + { + Serial.println("Got nodeinfo read"); + const NodeInfo *info = nodeDB.readNextInfo(); + + if (info) + { + size_t numbytes = pb_encode_to_bytes(trBytes, sizeof(trBytes), NodeInfo_fields, info); + c->setValue(trBytes, numbytes); + } + else + { + c->setValue(trBytes, 0); // Send an empty response + } + } + + void onWrite(BLECharacteristic *c) + { + // dumpCharacteristic(pCharacteristic); + Serial.println("Got on nodeinfo write"); + nodeDB.resetReadPointer(); + } +}; + static BLECharacteristic meshFromRadioCharacteristic("8ba2bcc2-ee02-4a55-a531-c525c5e454d5", BLECharacteristic::PROPERTY_READ), meshToRadioCharacteristic("f75c76d2-129e-4dad-a1dd-7866124401e7", BLECharacteristic::PROPERTY_WRITE), - meshFromNumCharacteristic("ed9da18c-a800-4f66-a670-aa7547e34453", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY), - meshNodeInfoCharacteristic("d31e02e0-c8ab-4d3f-9cc9-0b8466bdabe8", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ); + meshFromNumCharacteristic("ed9da18c-a800-4f66-a670-aa7547e34453", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); + +static NodeInfoCharacteristic meshNodeInfoCharacteristic; static ProtobufCharacteristic meshMyNodeCharacteristic("ea9f3f82-8dc4-4733-9452-1f6da28892a2", BLECharacteristic::PROPERTY_READ, MyNodeInfo_fields, &myNodeInfo), @@ -163,7 +198,7 @@ meshMyNodeCharacteristic("ea9f3f82-8dc4-4733-9452-1f6da28892a2", BLECharacterist mynode - read/write this to access a MyNodeInfo protobuf meshNodeInfoCharacteristic("d31e02e0-c8ab-4d3f-9cc9-0b8466bdabe8", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ), -mynodeinfo - read this to get a series of node infos (ending with a null empty record), write to this to restart the read statemachine that returns all the node infos +nodeinfo - read this to get a series of node infos (ending with a null empty record), write to this to restart the read statemachine that returns all the node infos meshRadioCharacteristic("b56786c8-839a-44a1-b98e-a1724c4a0262", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ), radio - read/write this to access a RadioConfig protobuf @@ -195,6 +230,7 @@ BLEService *createMeshBluetoothService(BLEServer *server) addWithDesc(service, &meshMyNodeCharacteristic, "myNode"); addWithDesc(service, &meshRadioCharacteristic, "radio"); addWithDesc(service, &meshOwnerCharacteristic, "owner"); + addWithDesc(service, &meshNodeInfoCharacteristic, "nodeinfo"); meshFromNumCharacteristic.addDescriptor(new BLE2902()); // Needed so clients can request notification diff --git a/src/NodeDB.cpp b/src/NodeDB.cpp index 5f5852a41..1e99a3905 100644 --- a/src/NodeDB.cpp +++ b/src/NodeDB.cpp @@ -25,15 +25,24 @@ static NodeNum getDesiredNodeNum() return r; } -NodeDB::NodeDB() : ourNodeNum(getDesiredNodeNum()), numNodes(0) +NodeDB::NodeDB() : ourNodeNum(getDesiredNodeNum()) { } /// return number msecs since 1970 -uint64_t getCurrentTime() { +uint64_t getCurrentTime() +{ return 4403; // FIXME } +const NodeInfo *NodeDB::readNextInfo() +{ + if (readPointer < numNodes) + return &nodes[readPointer++]; + else + return NULL; +} + /// 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) @@ -52,7 +61,7 @@ void NodeDB::updateFrom(const MeshPacket &mp) info->last_seen.msecs = getCurrentTime(); info->has_last_seen = true; - + switch (p.which_variant) { case SubPacket_position_tag: diff --git a/src/NodeDB.h b/src/NodeDB.h index ea0902ffa..781389ee5 100644 --- a/src/NodeDB.h +++ b/src/NodeDB.h @@ -6,20 +6,23 @@ #include "mesh-pb-constants.h" #include "MeshTypes.h" -class NodeDB { +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 + NodeNum ourNodeNum; // A NodeInfo for every node we've seen // Eventually use a smarter datastructure // HashMap nodes; NodeInfo nodes[MAX_NUM_NODES]; - int numNodes; + int numNodes = 0; + + bool updateGUI = false; // we think the gui should definitely be redrawn + NodeInfo *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI + + int readPointer = 0; - 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 @@ -41,11 +44,17 @@ public: mesh sw does if it does conflict? would it be better for people who are replying with denynode num to just broadcast their denial?) */ + /// Called from bluetooth when the user wants to start reading the node DB from scratch. + void resetReadPointer() { readPointer = 0; } + + /// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading + const NodeInfo *readNextInfo(); + 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 + /// Find a node in our DB, create an empty NodeInfo if missing NodeInfo *getOrCreateNode(NodeNum n); }; diff --git a/src/configuration.h b/src/configuration.h index f96e8fc59..59710ec82 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -67,23 +67,6 @@ along with this program. If not, see . #define DEBUG_MSG(...) #endif -// ----------------------------------------------------------------------------- -// Custom messages -// ----------------------------------------------------------------------------- - -#define EV_QUEUED 100 -#define EV_PENDING 101 -#define EV_ACK 102 -#define EV_RESPONSE 103 - -// ----------------------------------------------------------------------------- -// General -// ----------------------------------------------------------------------------- - - - - - // ----------------------------------------------------------------------------- // OLED // -----------------------------------------------------------------------------