diff --git a/TODO.md b/TODO.md index c6d773a1..1ce91771 100644 --- a/TODO.md +++ b/TODO.md @@ -59,6 +59,7 @@ until the phone pulls those packets. Ever so often power on bluetooth just so w # Low priority +* add a watchdog timer * fix GPS.zeroOffset calculation it is wrong * handle millis() rollover in GPS.getTime - otherwise we will break after 50 days * reneable the bluetooth battely level service on the T-BEAM, because we can read battery level there diff --git a/src/GPS.cpp b/src/GPS.cpp index 79b6eca5..2e610747 100644 --- a/src/GPS.cpp +++ b/src/GPS.cpp @@ -39,7 +39,7 @@ void GPS::loop() 24 * 60 * 60 * (date.month() * 31 + date.day() + 365 * (date.year() - 1970))) + time.centisecond() * 10; - DEBUG_MSG("Setting time zero %lld", zeroOffset); + DEBUG_MSG("Setting time zero %lld\n", zeroOffset); } #endif } diff --git a/src/MemoryPool.h b/src/MemoryPool.h index d75581c1..60b8a801 100644 --- a/src/MemoryPool.h +++ b/src/MemoryPool.h @@ -29,8 +29,17 @@ public: delete[] buf; } - /// Return a queable object which has been prefilled with zeros - T *allocZeroed(TickType_t maxWait = portMAX_DELAY) { + /// Return a queable object which has been prefilled with zeros. Panic if no buffer is available + T *allocZeroed() { + T *p = allocZeroed(0); + + assert(p); // FIXME panic instead + return p; + } + + + /// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you probably don't want this version) + T *allocZeroed(TickType_t maxWait) { T *p = dead.dequeuePtr(maxWait); if(p) diff --git a/src/MeshService.cpp b/src/MeshService.cpp index 79f1dc7d..5a511b4f 100644 --- a/src/MeshService.cpp +++ b/src/MeshService.cpp @@ -6,6 +6,7 @@ #include "MeshService.h" #include "MeshBluetoothService.h" #include "NodeDB.h" +#include "GPS.h" /* receivedPacketQueue - this is a queue of messages we've received from the mesh, which we are keeping to deliver to the phone. @@ -18,19 +19,18 @@ a node number and keeping the current nodedb. */ - 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_PACKETS 32 // max number of packets which can be in flight (either queued from reception or queued for sending) #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() - : packetPool(MAX_PACKETS), - toPhoneQueue(MAX_RX_TOPHONE), - fromRadioQueue(MAX_RX_FROMRADIO), - fromNum(0), - radio(packetPool, fromRadioQueue) + : packetPool(MAX_PACKETS), + toPhoneQueue(MAX_RX_TOPHONE), + fromRadioQueue(MAX_RX_FROMRADIO), + fromNum(0), + radio(packetPool, fromRadioQueue) { // assert(MAX_RX_TOPHONE == 32); // FIXME, delete this, just checking my clever macro } @@ -38,9 +38,11 @@ MeshService::MeshService() void MeshService::init() { nodeDB.init(); - + if (!radio.init()) DEBUG_MSG("radio init failed\n"); + + gps.addObserver(this); } /// Do idle processing (mostly processing messages which have been queued from the radio) @@ -50,14 +52,14 @@ void MeshService::loop() MeshPacket *mp; uint32_t oldFromNum = fromNum; - while((mp = fromRadioQueue.dequeuePtr(0)) != NULL) { - nodeDB.updateFrom(*mp); + while ((mp = fromRadioQueue.dequeuePtr(0)) != NULL) + { + nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio fromNum++; - assert(toPhoneQueue.enqueue(mp , 0) == pdTRUE); // FIXME, instead of failing for full queue, delete the oldest mssages - + assert(toPhoneQueue.enqueue(mp, 0) == pdTRUE); // FIXME, instead of failing for full queue, delete the oldest mssages } - if(oldFromNum != fromNum) // We don't want to generate extra notifies for multiple new packets + if (oldFromNum != fromNum) // We don't want to generate extra notifies for multiple new packets bluetoothNotifyFromNum(fromNum); } @@ -71,7 +73,7 @@ void MeshService::handleToRadio(std::string s) switch (r.which_variant) { case ToRadio_packet_tag: - sendToMesh(r.variant.packet); + sendToMesh(packetPool.allocCopy(r.variant.packet)); break; default: @@ -81,12 +83,31 @@ void MeshService::handleToRadio(std::string s) } } -/// Send a packet into the mesh - note p is read only and should be copied into a pool based MeshPacket before -/// sending. -void MeshService::sendToMesh(const MeshPacket &pIn) +void MeshService::sendToMesh(MeshPacket *p) { - MeshPacket *pOut = packetPool.allocCopy(pIn); - assert(pOut); // FIXME - - assert(radio.send(pOut) == pdTRUE); + nodeDB.updateFrom(*p); + assert(radio.send(p) == pdTRUE); } + +void MeshService::onGPSChanged() +{ + MeshPacket *p = packetPool.allocZeroed(); + + p->has_payload = true; + p->from = nodeDB.getNodeNum(); + p->to = NODENUM_BROADCAST; + p->payload.which_variant = SubPacket_position_tag; + Position &pos = p->payload.variant.position; + if (gps.altitude.isValid()) + pos.altitude = gps.altitude.value(); + pos.latitude = gps.location.lat(); + pos.longitude = gps.location.lng(); + + sendToMesh(p); +} + +void MeshService::onNotify(Observable *o) +{ + DEBUG_MSG("got gps notify\n"); + onGPSChanged(); +} \ No newline at end of file diff --git a/src/MeshService.h b/src/MeshService.h index 76212f0c..0e58e2e3 100644 --- a/src/MeshService.h +++ b/src/MeshService.h @@ -7,12 +7,13 @@ #include "MeshRadio.h" #include "PointerQueue.h" #include "MemoryPool.h" +#include "Observer.h" /** * Top level app for this service. keeps the mesh, the radio config and the queue of received packets. * */ -class MeshService +class MeshService: private Observer { MemoryPool packetPool; @@ -58,10 +59,14 @@ public: private: - /// Send a packet into the mesh - note p is read only and should be copied into a pool based MeshPacket before - /// sending. - void sendToMesh(const MeshPacket &p); + /// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after sending. + /// This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb cache + void sendToMesh(MeshPacket *p); + /// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh + void onGPSChanged(); + + virtual void onNotify(Observable *o); }; extern MeshService service; diff --git a/src/Observer.h b/src/Observer.h index 5490be5a..74163973 100644 --- a/src/Observer.h +++ b/src/Observer.h @@ -17,6 +17,9 @@ public: void observe(Observable *o); +private: + friend class Observable; + virtual void onNotify(Observable *o) = 0; };