From 88b91de197e50e09e27e56aa8f9c4493927dc39e Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 12 Jun 2020 11:53:59 -0700 Subject: [PATCH 01/15] Prepare to make MemoryDynamic --- src/mesh/MemoryPool.h | 88 ++++++++++++++++++++++++++----------------- src/mesh/MeshTypes.h | 2 +- src/mesh/Router.cpp | 4 +- 3 files changed, 58 insertions(+), 36 deletions(-) diff --git a/src/mesh/MemoryPool.h b/src/mesh/MemoryPool.h index 89c514c90..7f051af13 100644 --- a/src/mesh/MemoryPool.h +++ b/src/mesh/MemoryPool.h @@ -5,12 +5,58 @@ #include "PointerQueue.h" +template class Allocator +{ + + public: + virtual ~Allocator() {} + + /// Return a queable object which has been prefilled with zeros. Panic if no buffer is available + /// Note: this method is safe to call from regular OR ISR code + 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 = alloc(maxWait); + assert(p); + + if (p) + memset(p, 0, sizeof(T)); + return p; + } + + /// Return a queable object which is a copy of some other object + T *allocCopy(const T &src, TickType_t maxWait = portMAX_DELAY) + { + T *p = alloc(maxWait); + assert(p); + + if (p) + *p = src; + return p; + } + + /// Return a buffer for use by others + virtual void release(T *p) = 0; + + protected: + // Alloc some storage + virtual T *alloc(TickType_t maxWait) = 0; +}; + /** * A pool based allocator * - * Eventually this routine will even be safe for ISR use... */ -template class MemoryPool +template class MemoryPool : public Allocator { PointerQueue dead; @@ -30,39 +76,8 @@ template class MemoryPool ~MemoryPool() { delete[] buf; } - /// Return a queable object which has been prefilled with zeros. Panic if no buffer is available - /// Note: this method is safe to call from regular OR ISR code - 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) - memset(p, 0, sizeof(T)); - return p; - } - - /// Return a queable object which is a copy of some other object - T *allocCopy(const T &src, TickType_t maxWait = portMAX_DELAY) - { - T *p = dead.dequeuePtr(maxWait); - - if (p) - *p = src; - return p; - } - /// Return a buffer for use by others - void release(T *p) + virtual void release(T *p) { assert(dead.enqueue(p, 0)); assert(p >= buf && @@ -78,4 +93,9 @@ template class MemoryPool (size_t)(p - buf) < maxElements); // sanity check to make sure a programmer didn't free something that didn't come from this pool } + + protected: + /// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you + /// probably don't want this version). + virtual T *alloc(TickType_t maxWait) { return dead.dequeuePtr(maxWait); } }; diff --git a/src/mesh/MeshTypes.h b/src/mesh/MeshTypes.h index 32ec2b08d..7c58b2e3e 100644 --- a/src/mesh/MeshTypes.h +++ b/src/mesh/MeshTypes.h @@ -29,4 +29,4 @@ typedef uint32_t PacketId; // A packet sequence number typedef int ErrorCode; /// Alloc and free packets to our global, ISR safe pool -extern MemoryPool packetPool; \ No newline at end of file +extern Allocator &packetPool; \ No newline at end of file diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 2f8dd5e28..f9b196d60 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -23,7 +23,9 @@ (MAX_RX_TOPHONE + MAX_RX_FROMRADIO + MAX_TX_QUEUE + \ 2) // max number of packets which can be in flight (either queued from reception or queued for sending) -MemoryPool packetPool(MAX_PACKETS); + +static MemoryPool staticPool(MAX_PACKETS); +Allocator &packetPool = staticPool; /** * Constructor From f0b8f10665498566df231a5fa06c729786e66535 Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 12 Jun 2020 12:11:18 -0700 Subject: [PATCH 02/15] Fix #149: Use a simple heap allocator for now, after 1.0 we can go to fixed sized pools to protect against fragmentation. --- docs/software/TODO.md | 1 + src/mesh/MemoryPool.h | 20 +++++++++++++++++++- src/mesh/Router.cpp | 3 ++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index a2ad8e82f..bbec4546c 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -24,6 +24,7 @@ During the beta timeframe the following improvements 'would be nice' Items after the first final candidate release. +- Change back to using a fixed sized MemoryPool rather than MemoryDynamic (see bug #149) - scan to find channels with low background noise? (Use CAD mode of the RF95 to automatically find low noise channels) - If the phone doesn't read fromradio mailbox within X seconds, assume the phone is gone and we can stop queing location msgs for it (because it will redownload the nodedb when it comes back) diff --git a/src/mesh/MemoryPool.h b/src/mesh/MemoryPool.h index 7f051af13..8c6986e16 100644 --- a/src/mesh/MemoryPool.h +++ b/src/mesh/MemoryPool.h @@ -26,7 +26,6 @@ template class Allocator T *allocZeroed(TickType_t maxWait) { T *p = alloc(maxWait); - assert(p); if (p) memset(p, 0, sizeof(T)); @@ -52,6 +51,25 @@ template class Allocator virtual T *alloc(TickType_t maxWait) = 0; }; +/** + * An allocator that just uses regular free/malloc + */ +template class MemoryDynamic : public Allocator +{ + public: + /// Return a buffer for use by others + virtual void release(T *p) + { + assert(p); + free(p); + } + + protected: + /// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you + /// probably don't want this version). + virtual T *alloc(TickType_t maxWait) { return (T *)malloc(sizeof(T)); } +}; + /** * A pool based allocator * diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index f9b196d60..914e50d09 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -23,8 +23,9 @@ (MAX_RX_TOPHONE + MAX_RX_FROMRADIO + MAX_TX_QUEUE + \ 2) // max number of packets which can be in flight (either queued from reception or queued for sending) +// static MemoryPool staticPool(MAX_PACKETS); +static MemoryDynamic staticPool; -static MemoryPool staticPool(MAX_PACKETS); Allocator &packetPool = staticPool; /** From de37e1bbabba430fd7a3636d2ee8a11f1deddb0e Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 12 Jun 2020 15:40:36 -0700 Subject: [PATCH 03/15] todo notes --- docs/software/TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index bbec4546c..9043a1616 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -35,7 +35,7 @@ Items after the first final candidate release. - Don't store position packets in the to phone fifo if we are disconnected. The phone will get that info for 'free' when it fetches the fresh nodedb. - Use the RFM95 sequencer to stay in idle mode most of the time, then automatically go to receive mode and automatically go from transmit to receive mode. See 4.2.8.2 of manual. -- Use fixed32 for node IDs, packetIDs and lat/lon - will require all nodes to be updated, but make messages slightly smaller. +- Use fixed32 for node IDs, packetIDs, successid, failid, and lat/lon - will require all nodes to be updated, but make messages slightly smaller. - add "store and forward" support for messages, or move to the DB sync model. This would allow messages to be eventually delivered even if nodes are out of contact at the moment. - use variable length Strings in protobufs (instead of current fixed buffers). This would save lots of RAM - use BLEDevice::setPower to lower our BLE transmit power - extra range doesn't help us, it costs amps and it increases snoopability From a8d4b5479d0889365164df6a36b2915e8a453183 Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 12 Jun 2020 15:40:56 -0700 Subject: [PATCH 04/15] don't start the BLE update service for now - the android side isn't ready --- src/esp32/BluetoothUtil.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/esp32/BluetoothUtil.cpp b/src/esp32/BluetoothUtil.cpp index ccaf41639..067dcee1a 100644 --- a/src/esp32/BluetoothUtil.cpp +++ b/src/esp32/BluetoothUtil.cpp @@ -223,11 +223,14 @@ void deinitBLE() pServer->getAdvertising()->stop(); - destroyUpdateService(); + if (pUpdate != NULL) { + destroyUpdateService(); + + pUpdate->stop(); + pUpdate->stop(); // we delete them below + } - pUpdate->stop(); pDevInfo->stop(); - pUpdate->stop(); // we delete them below // First shutdown bluetooth BLEDevice::deinit(false); @@ -235,7 +238,8 @@ void deinitBLE() // do not delete this - it is dynamically allocated, but only once - statically in BLEDevice // delete pServer->getAdvertising(); - delete pUpdate; + if (pUpdate != NULL) + delete pUpdate; delete pDevInfo; delete pServer; @@ -276,15 +280,18 @@ BLEServer *initBLE(StartBluetoothPinScreenCallback startBtPinScreen, StopBluetoo // We now let users create the battery service only if they really want (not all devices have a battery) // BLEService *pBattery = createBatteryService(pServer); +#ifdef BLE_SOFTWARE_UPDATE // Disable for now pUpdate = createUpdateService(pServer, hwVendor, swVersion, hwVersion); // We need to advertise this so our android ble scan operation can see it + pUpdate->start(); +#endif + // It seems only one service can be advertised - so for now don't advertise our updater // pServer->getAdvertising()->addServiceUUID(pUpdate->getUUID()); // start all our services (do this after creating all of them) pDevInfo->start(); - pUpdate->start(); // FIXME turn on this restriction only after the device is paired with a phone // advert->setScanFilter(false, true); // We let anyone scan for us (FIXME, perhaps only allow that until we are paired with a From 03cb3c2145603c3c4795014739bf5f2974bae7c3 Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 12 Jun 2020 16:37:03 -0700 Subject: [PATCH 05/15] basic stack debugging - we are okay for now --- src/WorkerThread.cpp | 12 ++++++++++-- src/WorkerThread.h | 2 ++ src/main.cpp | 9 +++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/WorkerThread.cpp b/src/WorkerThread.cpp index f84d83be2..bf38a9266 100644 --- a/src/WorkerThread.cpp +++ b/src/WorkerThread.cpp @@ -1,4 +1,5 @@ #include "WorkerThread.h" +#include "debug.h" #include void Thread::start(const char *name, size_t stackSize, uint32_t priority) @@ -16,6 +17,15 @@ void WorkerThread::doRun() { while (!wantExit) { block(); + +#ifdef DEBUG_STACK + static uint32_t lastPrint = 0; + if (millis() - lastPrint > 10 * 1000L) { + lastPrint = millis(); + meshtastic::printThreadInfo("net"); + } +#endif + loop(); } } @@ -28,8 +38,6 @@ void NotifiedWorkerThread::notify(uint32_t v, eNotifyAction action) xTaskNotify(taskHandle, v, action); } - - void NotifiedWorkerThread::block() { xTaskNotifyWait(0, // don't clear notification on entry diff --git a/src/WorkerThread.h b/src/WorkerThread.h index 86ec08e13..655e316f8 100644 --- a/src/WorkerThread.h +++ b/src/WorkerThread.h @@ -15,6 +15,8 @@ class Thread virtual ~Thread() { vTaskDelete(taskHandle); } + uint32_t getStackHighwaterMark() { return uxTaskGetStackHighWaterMark(taskHandle); } + protected: /** * The method that will be called when start is called. diff --git a/src/main.cpp b/src/main.cpp index d7fb21bd1..0c9fe5ca3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,6 +33,7 @@ #include "power.h" // #include "rom/rtc.h" #include "DSRRouter.h" +#include "debug.h" #include "main.h" #include "screen.h" #include "sleep.h" @@ -314,6 +315,14 @@ void loop() showingBootScreen = false; } +#ifdef DEBUG_STACK + static uint32_t lastPrint = 0; + if (millis() - lastPrint > 10 * 1000L) { + lastPrint = millis(); + meshtastic::printThreadInfo("main"); + } +#endif + // Update the screen last, after we've figured out what to show. screen.debug()->setNodeNumbersStatus(nodeDB.getNumOnlineNodes(), nodeDB.getNumNodes()); screen.debug()->setChannelNameStatus(channelSettings.name); From 47e614c7d63fca402f14f6d43c48a3bd6040d39c Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 08:26:48 -0700 Subject: [PATCH 06/15] fix #172 We need our own branch because we need this fix and associated pullrequest https://github.com/espressif/arduino-esp32/pull/4085 --- docs/software/TODO.md | 6 ++++++ platformio.ini | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index 9043a1616..840156e5c 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -1,9 +1,15 @@ # High priority +- why is the net so chatty now? +- E22 bringup +- encryption review findings writeup +- turn on modem-sleep mode + # Medium priority Items to complete before the first beta release. +- turn on watchdog timer (because lib code seems buggy) - show battery level as % full - rx signal measurements -3 marginal, -9 bad, 10 great, -10 means almost unusable. So scale this into % signal strength. preferably as a graph, with an X indicating loss of comms. diff --git a/platformio.ini b/platformio.ini index c51e0954e..791bfed20 100644 --- a/platformio.ini +++ b/platformio.ini @@ -22,8 +22,6 @@ default_envs = tbeam ; Note: the github actions CI test build can't yet build NR ; HW_VERSION (default emptystring) [env] -platform = espressif32 -framework = arduino ; customize the partition table ; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables @@ -79,6 +77,8 @@ lib_deps = ; Common settings for ESP targes, mixin with extends = esp32_base [esp32_base] +platform = espressif32 +framework = arduino src_filter = ${env.src_filter} - upload_speed = 921600 @@ -86,6 +86,8 @@ debug_init_break = tbreak setup build_flags = ${env.build_flags} -Wall -Wextra -Isrc/esp32 lib_ignore = segger_rtt +platform_packages = + framework-arduinoespressif32 @ https://github.com/meshtastic/arduino-esp32.git ; The 1.0 release of the TBEAM board [env:tbeam] From db66e4dc008c573957fd0bdee76c3f25eda4e17f Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 08:27:25 -0700 Subject: [PATCH 07/15] ensure we never get null from malloc --- src/mesh/MemoryPool.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mesh/MemoryPool.h b/src/mesh/MemoryPool.h index 8c6986e16..4fefb4c4d 100644 --- a/src/mesh/MemoryPool.h +++ b/src/mesh/MemoryPool.h @@ -65,9 +65,13 @@ template class MemoryDynamic : public Allocator } protected: - /// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you - /// probably don't want this version). - virtual T *alloc(TickType_t maxWait) { return (T *)malloc(sizeof(T)); } + // Alloc some storage + virtual T *alloc(TickType_t maxWait) + { + T *p = (T *)malloc(sizeof(T)); + assert(p); + return p; + } }; /** From f54b18f7337745dacf8278e347e855e060e4467b Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 08:27:44 -0700 Subject: [PATCH 08/15] each tx packet might have a retransmission/ack copy, make pool bigger --- src/mesh/Router.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 914e50d09..7ecb6e72f 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -19,8 +19,9 @@ 4 // max number of packets destined to our queue, we dispatch packets quickly so it doesn't need to be big // I think this is right, one packet for each of the three fifos + one packet being currently assembled for TX or RX +// And every TX packet might have a retransmission packet or an ack alive at any moment #define MAX_PACKETS \ - (MAX_RX_TOPHONE + MAX_RX_FROMRADIO + MAX_TX_QUEUE + \ + (MAX_RX_TOPHONE + MAX_RX_FROMRADIO + 2 * MAX_TX_QUEUE + \ 2) // max number of packets which can be in flight (either queued from reception or queued for sending) // static MemoryPool staticPool(MAX_PACKETS); From dc7469c64ba81486540a6f8b5e2458d4df6e4a4f Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 08:28:01 -0700 Subject: [PATCH 09/15] useful bluetooth debugging output --- src/esp32/main-esp32.cpp | 5 +++++ src/main.cpp | 2 ++ src/mesh/PhoneAPI.cpp | 6 +++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/esp32/main-esp32.cpp b/src/esp32/main-esp32.cpp index 67256bc7f..2b4711d5e 100644 --- a/src/esp32/main-esp32.cpp +++ b/src/esp32/main-esp32.cpp @@ -160,6 +160,11 @@ void esp32Setup() DEBUG_MSG("Setting random seed %u\n", seed); randomSeed(seed); // ESP docs say this is fairly random + DEBUG_MSG("Total heap: %d\n", ESP.getHeapSize()); + DEBUG_MSG("Free heap: %d\n", ESP.getFreeHeap()); + DEBUG_MSG("Total PSRAM: %d\n", ESP.getPsramSize()); + DEBUG_MSG("Free PSRAM: %d\n", ESP.getFreePsram()); + #ifdef AXP192_SLAVE_ADDRESS axp192Init(); #endif diff --git a/src/main.cpp b/src/main.cpp index 0c9fe5ca3..ded027f51 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -283,6 +283,8 @@ void loop() DEBUG_PORT.loop(); // Send/receive protobufs over the serial port #endif + // heap_caps_check_integrity_all(true); // FIXME - disable this expensive check + #ifndef NO_ESP32 esp32Loop(); #endif diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index b4c5538ca..ce8b13d22 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -91,8 +91,12 @@ void PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) */ size_t PhoneAPI::getFromRadio(uint8_t *buf) { - if (!available()) + if (!available()) { + DEBUG_MSG("getFromRadio, !available\n"); return false; + } else { + DEBUG_MSG("getFromRadio, state=%d\n", state); + } // In case we send a FromRadio packet memset(&fromRadioScratch, 0, sizeof(fromRadioScratch)); From 575a15e1359a4df75c26b8cbda6731bf16af86fd Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 08:29:41 -0700 Subject: [PATCH 10/15] remove more dead rev1 protocol code --- src/esp32/MeshBluetoothService.cpp | 33 ------------------------------ 1 file changed, 33 deletions(-) diff --git a/src/esp32/MeshBluetoothService.cpp b/src/esp32/MeshBluetoothService.cpp index 3e803ad66..2c05b7faa 100644 --- a/src/esp32/MeshBluetoothService.cpp +++ b/src/esp32/MeshBluetoothService.cpp @@ -41,39 +41,6 @@ class BluetoothPhoneAPI : public PhoneAPI BluetoothPhoneAPI *bluetoothPhoneAPI; -class ProtobufCharacteristic : public CallbackCharacteristic -{ - const pb_msgdesc_t *fields; - void *my_struct; - - public: - ProtobufCharacteristic(const char *uuid, uint32_t btprops, const pb_msgdesc_t *_fields, void *_my_struct) - : CallbackCharacteristic(uuid, btprops), fields(_fields), my_struct(_my_struct) - { - setCallbacks(this); - } - - void onRead(BLECharacteristic *c) - { - size_t numbytes = pb_encode_to_bytes(trBytes, sizeof(trBytes), fields, my_struct); - DEBUG_MSG("pbread from %s returns %d bytes\n", c->getUUID().toString().c_str(), numbytes); - c->setValue(trBytes, numbytes); - } - - void onWrite(BLECharacteristic *c) { writeToDest(c, my_struct); } - - protected: - /// like onWrite, but we provide an different destination to write to, for use by subclasses that - /// want to optionally ignore parts of writes. - /// returns true for success - bool writeToDest(BLECharacteristic *c, void *dest) - { - // dumpCharacteristic(pCharacteristic); - std::string src = c->getValue(); - DEBUG_MSG("pbwrite to %s of %d bytes\n", c->getUUID().toString().c_str(), src.length()); - return pb_decode_from_bytes((const uint8_t *)src.c_str(), src.length(), fields, dest); - } -}; class ToRadioCharacteristic : public CallbackCharacteristic { From d5deb49d20e2d9d0fef9f5f0becdd7b7e5b0f5ac Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 11:05:13 -0700 Subject: [PATCH 11/15] use executeDelete to prevent leaking BLE handles --- src/esp32/BluetoothUtil.cpp | 104 +++++++++++++++-------------- src/esp32/MeshBluetoothService.cpp | 1 + 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/src/esp32/BluetoothUtil.cpp b/src/esp32/BluetoothUtil.cpp index 067dcee1a..61f6e1592 100644 --- a/src/esp32/BluetoothUtil.cpp +++ b/src/esp32/BluetoothUtil.cpp @@ -8,53 +8,6 @@ SimpleAllocator btPool; -/** - * Create standard device info service - **/ -BLEService *createDeviceInfomationService(BLEServer *server, std::string hwVendor, std::string swVersion, - std::string hwVersion = "") -{ - BLEService *deviceInfoService = server->createService(BLEUUID((uint16_t)ESP_GATT_UUID_DEVICE_INFO_SVC)); - - BLECharacteristic *swC = - new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_SW_VERSION_STR), BLECharacteristic::PROPERTY_READ); - BLECharacteristic *mfC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_MANU_NAME), BLECharacteristic::PROPERTY_READ); - // BLECharacteristic SerialNumberCharacteristic(BLEUUID((uint16_t) ESP_GATT_UUID_SERIAL_NUMBER_STR), - // BLECharacteristic::PROPERTY_READ); - - /* - * Mandatory characteristic for device info service? - - BLECharacteristic *m_pnpCharacteristic = m_deviceInfoService->createCharacteristic(ESP_GATT_UUID_PNP_ID, - BLECharacteristic::PROPERTY_READ); - - uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version; - uint8_t pnp[] = { sig, (uint8_t) (vid >> 8), (uint8_t) vid, (uint8_t) (pid >> 8), (uint8_t) pid, (uint8_t) (version >> - 8), (uint8_t) version }; m_pnpCharacteristic->setValue(pnp, sizeof(pnp)); - */ - swC->setValue(swVersion); - deviceInfoService->addCharacteristic(addBLECharacteristic(swC)); - mfC->setValue(hwVendor); - deviceInfoService->addCharacteristic(addBLECharacteristic(mfC)); - if (!hwVersion.empty()) { - BLECharacteristic *hwvC = - new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_HW_VERSION_STR), BLECharacteristic::PROPERTY_READ); - hwvC->setValue(hwVersion); - deviceInfoService->addCharacteristic(addBLECharacteristic(hwvC)); - } - // SerialNumberCharacteristic.setValue("FIXME"); - // deviceInfoService->addCharacteristic(&SerialNumberCharacteristic); - - // m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t) 0x2a29, - // BLECharacteristic::PROPERTY_READ); m_manufacturerCharacteristic->setValue(name); - - /* add these later? - ESP_GATT_UUID_SYSTEM_ID - */ - - // caller must call service->start(); - return deviceInfoService; -} bool _BLEClientConnected = false; @@ -106,6 +59,54 @@ void addWithDesc(BLEService *service, BLECharacteristic *c, const char *descript addBLEDescriptor(desc); } +/** + * Create standard device info service + **/ +BLEService *createDeviceInfomationService(BLEServer *server, std::string hwVendor, std::string swVersion, + std::string hwVersion = "") +{ + BLEService *deviceInfoService = server->createService(BLEUUID((uint16_t)ESP_GATT_UUID_DEVICE_INFO_SVC)); + + BLECharacteristic *swC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_SW_VERSION_STR), BLECharacteristic::PROPERTY_READ); + BLECharacteristic *mfC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_MANU_NAME), BLECharacteristic::PROPERTY_READ); + // BLECharacteristic SerialNumberCharacteristic(BLEUUID((uint16_t) ESP_GATT_UUID_SERIAL_NUMBER_STR), + // BLECharacteristic::PROPERTY_READ); + + /* + * Mandatory characteristic for device info service? + + BLECharacteristic *m_pnpCharacteristic = m_deviceInfoService->createCharacteristic(ESP_GATT_UUID_PNP_ID, + BLECharacteristic::PROPERTY_READ); + + uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version; + uint8_t pnp[] = { sig, (uint8_t) (vid >> 8), (uint8_t) vid, (uint8_t) (pid >> 8), (uint8_t) pid, (uint8_t) (version >> + 8), (uint8_t) version }; m_pnpCharacteristic->setValue(pnp, sizeof(pnp)); + */ + swC->setValue(swVersion); + deviceInfoService->addCharacteristic(addBLECharacteristic(swC)); + mfC->setValue(hwVendor); + deviceInfoService->addCharacteristic(addBLECharacteristic(mfC)); + if (!hwVersion.empty()) { + BLECharacteristic *hwvC = + new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_HW_VERSION_STR), BLECharacteristic::PROPERTY_READ); + hwvC->setValue(hwVersion); + deviceInfoService->addCharacteristic(addBLECharacteristic(hwvC)); + } + // SerialNumberCharacteristic.setValue("FIXME"); + // deviceInfoService->addCharacteristic(&SerialNumberCharacteristic); + + // m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t) 0x2a29, + // BLECharacteristic::PROPERTY_READ); m_manufacturerCharacteristic->setValue(name); + + /* add these later? + ESP_GATT_UUID_SYSTEM_ID + */ + + // caller must call service->start(); + return deviceInfoService; +} + + static BLECharacteristic *batteryLevelC; /** @@ -226,11 +227,12 @@ void deinitBLE() if (pUpdate != NULL) { destroyUpdateService(); - pUpdate->stop(); pUpdate->stop(); // we delete them below + pUpdate->executeDelete(); } pDevInfo->stop(); + pDevInfo->executeDelete(); // First shutdown bluetooth BLEDevice::deinit(false); @@ -245,8 +247,9 @@ void deinitBLE() batteryLevelC = NULL; // Don't let anyone generate bogus notifies - for (int i = 0; i < numChars; i++) + for (int i = 0; i < numChars; i++) { delete chars[i]; + } numChars = 0; for (int i = 0; i < numDescs; i++) @@ -280,7 +283,8 @@ BLEServer *initBLE(StartBluetoothPinScreenCallback startBtPinScreen, StopBluetoo // We now let users create the battery service only if they really want (not all devices have a battery) // BLEService *pBattery = createBatteryService(pServer); -#ifdef BLE_SOFTWARE_UPDATE // Disable for now +#define BLE_SOFTWARE_UPDATE +#ifdef BLE_SOFTWARE_UPDATE pUpdate = createUpdateService(pServer, hwVendor, swVersion, hwVersion); // We need to advertise this so our android ble scan operation can see it diff --git a/src/esp32/MeshBluetoothService.cpp b/src/esp32/MeshBluetoothService.cpp index 2c05b7faa..0f3b512e2 100644 --- a/src/esp32/MeshBluetoothService.cpp +++ b/src/esp32/MeshBluetoothService.cpp @@ -133,6 +133,7 @@ void stopMeshBluetoothService() { assert(meshService); meshService->stop(); + meshService->executeDelete(); } void destroyMeshBluetoothService() From 8caa075bc60fda49e149c936457a797ea848de9d Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 11:05:36 -0700 Subject: [PATCH 12/15] used fixed pool allocator for now - since that's how we've been testing --- src/mesh/Router.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 7ecb6e72f..bbf03944f 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -24,8 +24,8 @@ (MAX_RX_TOPHONE + MAX_RX_FROMRADIO + 2 * MAX_TX_QUEUE + \ 2) // max number of packets which can be in flight (either queued from reception or queued for sending) -// static MemoryPool staticPool(MAX_PACKETS); -static MemoryDynamic staticPool; +static MemoryPool staticPool(MAX_PACKETS); +// static MemoryDynamic staticPool; Allocator &packetPool = staticPool; From 8a1754efe8366e102075c2888248c4bd760b9651 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 11:36:45 -0700 Subject: [PATCH 13/15] leave the software update service off for now - no one is using ityet --- docs/software/TODO.md | 3 ++- src/esp32/BluetoothUtil.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index 840156e5c..e0dcb2459 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -1,9 +1,10 @@ # High priority - why is the net so chatty now? +- do a release - E22 bringup - encryption review findings writeup -- turn on modem-sleep mode +- turn on modem-sleep mode - https://github.com/espressif/arduino-esp32/issues/1142#issuecomment-512428852 # Medium priority diff --git a/src/esp32/BluetoothUtil.cpp b/src/esp32/BluetoothUtil.cpp index 61f6e1592..2833a7ede 100644 --- a/src/esp32/BluetoothUtil.cpp +++ b/src/esp32/BluetoothUtil.cpp @@ -283,7 +283,7 @@ BLEServer *initBLE(StartBluetoothPinScreenCallback startBtPinScreen, StopBluetoo // We now let users create the battery service only if they really want (not all devices have a battery) // BLEService *pBattery = createBatteryService(pServer); -#define BLE_SOFTWARE_UPDATE +// #define BLE_SOFTWARE_UPDATE #ifdef BLE_SOFTWARE_UPDATE pUpdate = createUpdateService(pServer, hwVendor, swVersion, hwVersion); // We need to advertise this so our android ble scan operation can see it From 13307c502f6e1d0bcb78fdac09d286717d4062b8 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 16:29:53 -0700 Subject: [PATCH 14/15] misc debug output --- docs/software/TODO.md | 2 ++ src/esp32/MeshBluetoothService.cpp | 2 -- src/mesh/NodeDB.cpp | 4 +++- src/mesh/PhoneAPI.cpp | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index e0dcb2459..d646b589f 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -1,7 +1,9 @@ # High priority - why is the net so chatty now? +- three bakc to back sends are getting overritten - shows up as three separate writes with the same payload - might be a bug on the android side or the device side - probably android - do a release +- device wakes, turns BLE on and phone doesn't notice (while phone was sitting in auto-connect) - E22 bringup - encryption review findings writeup - turn on modem-sleep mode - https://github.com/espressif/arduino-esp32/issues/1142#issuecomment-512428852 diff --git a/src/esp32/MeshBluetoothService.cpp b/src/esp32/MeshBluetoothService.cpp index 0f3b512e2..9bc41459a 100644 --- a/src/esp32/MeshBluetoothService.cpp +++ b/src/esp32/MeshBluetoothService.cpp @@ -49,8 +49,6 @@ class ToRadioCharacteristic : public CallbackCharacteristic void onWrite(BLECharacteristic *c) { - DEBUG_MSG("Got on write\n"); - bluetoothPhoneAPI->handleToRadio(c->getData(), c->getValue().length()); } }; diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 37233a3a0..e1ea45dd6 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -101,10 +101,12 @@ void NodeDB::resetRadioConfig() crypto->setKey(channelSettings.psk.size, channelSettings.psk.bytes); // temp hack for quicker testing + /* radioConfig.preferences.screen_on_secs = 30; radioConfig.preferences.wait_bluetooth_secs = 30; - radioConfig.preferences.position_broadcast_secs = 15; + radioConfig.preferences.position_broadcast_secs = 6 * 60; + radioConfig.preferences.ls_secs = 60; */ } diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index ce8b13d22..ec071fa5f 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -42,8 +42,9 @@ void PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) if (pb_decode_from_bytes(buf, bufLength, ToRadio_fields, &toRadioScratch)) { switch (toRadioScratch.which_variant) { case ToRadio_packet_tag: { - // If our phone is sending a position, see if we can use it to set our RTC MeshPacket &p = toRadioScratch.variant.packet; + DEBUG_MSG("PACKET FROM PHONE: id=%d, to=%x, want_ack=%d, which1=%d, which2=%d, typ=%d, buflen=%d\n", p.id, p.to, p.want_ack, p.which_payload, + p.decoded.which_payload, p.decoded.data.typ, bufLength); service.handleToRadio(p); break; } From 112a94e572e9ec6d640e5576845485bc3ebef325 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 13 Jun 2020 16:48:34 -0700 Subject: [PATCH 15/15] 0.7.5 --- bin/version.sh | 2 +- docs/software/TODO.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/version.sh b/bin/version.sh index befa884d6..b918e13a1 100644 --- a/bin/version.sh +++ b/bin/version.sh @@ -1,3 +1,3 @@ -export VERSION=0.7.4 \ No newline at end of file +export VERSION=0.7.5 \ No newline at end of file diff --git a/docs/software/TODO.md b/docs/software/TODO.md index d646b589f..0c742665d 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -1,7 +1,6 @@ # High priority - why is the net so chatty now? -- three bakc to back sends are getting overritten - shows up as three separate writes with the same payload - might be a bug on the android side or the device side - probably android - do a release - device wakes, turns BLE on and phone doesn't notice (while phone was sitting in auto-connect) - E22 bringup