btle leak per sleep now down to about 500 bytes.

This commit is contained in:
geeksville 2020-02-23 16:41:27 -08:00
parent 8dfd7a4a71
commit 621beadb5c
6 changed files with 74 additions and 26 deletions

View File

@ -44,6 +44,7 @@
"*.xbm": "cpp" "*.xbm": "cpp"
}, },
"cSpell.words": [ "cSpell.words": [
"Meshtastic" "Meshtastic",
"descs"
] ]
} }

View File

@ -3,6 +3,8 @@
Items to complete before the first alpha release. Items to complete before the first alpha release.
* the BLE stack is leaking about 7KB each time we go to light sleep * the BLE stack is leaking about 7KB each time we go to light sleep
* manually delete characteristics/descs
* sync sleep windows to gps time
* have state machine properly enter deep sleep based on loss of mesh and phone comms * have state machine properly enter deep sleep based on loss of mesh and phone comms
* default to enter deep sleep if no LORA received for two hours (indicates user has probably left the meshS) * default to enter deep sleep if no LORA received for two hours (indicates user has probably left the meshS)
* implement CustomRF95::canSleep * implement CustomRF95::canSleep

View File

@ -124,18 +124,20 @@ BLEService *createUpdateService(BLEServer *server)
BLEService *service = server->createService("cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30"); BLEService *service = server->createService("cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30");
assert(!resultC); assert(!resultC);
resultC = new (btPool) BLECharacteristic("5e134862-7411-4424-ac4a-210937432c77", BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); resultC = new BLECharacteristic("5e134862-7411-4424-ac4a-210937432c77", BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
addWithDesc(service, new (btPool) TotalSizeCharacteristic, "total image size"); addWithDesc(service, new TotalSizeCharacteristic, "total image size");
addWithDesc(service, new (btPool) DataCharacteristic, "data"); addWithDesc(service, new DataCharacteristic, "data");
addWithDesc(service, new (btPool) CRC32Characteristic, "crc32"); addWithDesc(service, new CRC32Characteristic, "crc32");
addWithDesc(service, resultC, "result code"); addWithDesc(service, resultC, "result code");
resultC->addDescriptor(new (btPool) BLE2902()); // Needed so clients can request notification resultC->addDescriptor(addBLEDescriptor(new BLE2902())); // Needed so clients can request notification
return service; return service;
} }
void destroyUpdateService() { void destroyUpdateService() {
assert(resultC);
resultC = NULL; resultC = NULL;
} }

View File

@ -16,8 +16,8 @@ BLEService *createDeviceInfomationService(BLEServer *server, std::string hwVendo
{ {
BLEService *deviceInfoService = server->createService(BLEUUID((uint16_t)ESP_GATT_UUID_DEVICE_INFO_SVC)); BLEService *deviceInfoService = server->createService(BLEUUID((uint16_t)ESP_GATT_UUID_DEVICE_INFO_SVC));
BLECharacteristic *swC = new (btPool) BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_SW_VERSION_STR), BLECharacteristic::PROPERTY_READ); BLECharacteristic *swC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_SW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
BLECharacteristic *mfC = new (btPool) BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_MANU_NAME), 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); // BLECharacteristic SerialNumberCharacteristic(BLEUUID((uint16_t) ESP_GATT_UUID_SERIAL_NUMBER_STR), BLECharacteristic::PROPERTY_READ);
/* /*
@ -30,14 +30,14 @@ BLEService *createDeviceInfomationService(BLEServer *server, std::string hwVendo
m_pnpCharacteristic->setValue(pnp, sizeof(pnp)); m_pnpCharacteristic->setValue(pnp, sizeof(pnp));
*/ */
swC->setValue(swVersion); swC->setValue(swVersion);
deviceInfoService->addCharacteristic(swC); deviceInfoService->addCharacteristic(addBLECharacteristic(swC));
mfC->setValue(hwVendor); mfC->setValue(hwVendor);
deviceInfoService->addCharacteristic(mfC); deviceInfoService->addCharacteristic(addBLECharacteristic(mfC));
if (!hwVersion.empty()) if (!hwVersion.empty())
{ {
BLECharacteristic *hwvC = new (btPool) BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_HW_VERSION_STR), BLECharacteristic::PROPERTY_READ); BLECharacteristic *hwvC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_HW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
hwvC->setValue(hwVersion); hwvC->setValue(hwVersion);
deviceInfoService->addCharacteristic(hwvC); deviceInfoService->addCharacteristic(addBLECharacteristic(hwvC));
} }
//SerialNumberCharacteristic.setValue("FIXME"); //SerialNumberCharacteristic.setValue("FIXME");
//deviceInfoService->addCharacteristic(&SerialNumberCharacteristic); //deviceInfoService->addCharacteristic(&SerialNumberCharacteristic);
@ -68,18 +68,45 @@ class MyServerCallbacks : public BLEServerCallbacks
} }
}; };
#define MAX_DESCRIPTORS 32
#define MAX_CHARACTERISTICS 32
static BLECharacteristic *chars[MAX_CHARACTERISTICS];
static size_t numChars;
static BLEDescriptor *descs[MAX_DESCRIPTORS];
static size_t numDescs;
/// Add a characteristic that we will delete when we restart
BLECharacteristic *addBLECharacteristic(BLECharacteristic *c)
{
assert(numChars < MAX_CHARACTERISTICS);
chars[numChars++] = c;
return c;
}
/// Add a characteristic that we will delete when we restart
BLEDescriptor *addBLEDescriptor(BLEDescriptor *c)
{
assert(numDescs < MAX_DESCRIPTORS);
descs[numDescs++] = c;
return c;
}
// Help routine to add a description to any BLECharacteristic and add it to the service // Help routine to add a description to any BLECharacteristic and add it to the service
// We default to require an encrypted BOND for all these these characterstics // We default to require an encrypted BOND for all these these characterstics
void addWithDesc(BLEService *service, BLECharacteristic *c, const char *description) void addWithDesc(BLEService *service, BLECharacteristic *c, const char *description)
{ {
c->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED); c->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
BLEDescriptor *desc = new (btPool) BLEDescriptor(BLEUUID((uint16_t)ESP_GATT_UUID_CHAR_DESCRIPTION), strlen(description) + 1); BLEDescriptor *desc = new BLEDescriptor(BLEUUID((uint16_t)ESP_GATT_UUID_CHAR_DESCRIPTION), strlen(description) + 1);
assert(desc); assert(desc);
desc->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED); desc->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
desc->setValue(description); desc->setValue(description);
c->addDescriptor(desc); c->addDescriptor(desc);
service->addCharacteristic(c); service->addCharacteristic(c);
addBLECharacteristic(c);
addBLEDescriptor(desc);
} }
static BLECharacteristic *batteryLevelC; static BLECharacteristic *batteryLevelC;
@ -92,10 +119,10 @@ BLEService *createBatteryService(BLEServer *server)
// Create the BLE Service // Create the BLE Service
BLEService *pBattery = server->createService(BLEUUID((uint16_t)0x180F)); BLEService *pBattery = server->createService(BLEUUID((uint16_t)0x180F));
batteryLevelC = new (btPool) BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_BATTERY_LEVEL), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY); batteryLevelC = new BLECharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_BATTERY_LEVEL), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
addWithDesc(pBattery, batteryLevelC, "Percentage 0 - 100"); addWithDesc(pBattery, batteryLevelC, "Percentage 0 - 100");
batteryLevelC->addDescriptor(new (btPool) BLE2902()); // Needed so clients can request notification batteryLevelC->addDescriptor(addBLEDescriptor(new BLE2902())); // Needed so clients can request notification
// I don't think we need to advertise this // I don't think we need to advertise this
// server->getAdvertising()->addServiceUUID(pBattery->getUUID()); // server->getAdvertising()->addServiceUUID(pBattery->getUUID());
@ -210,6 +237,14 @@ void deinitBLE()
batteryLevelC = NULL; // Don't let anyone generate bogus notifies batteryLevelC = NULL; // Don't let anyone generate bogus notifies
destroyUpdateService(); destroyUpdateService();
for (int i = 0; i < numChars; i++)
delete chars[i];
numChars = 0;
for (int i = 0; i < numDescs; i++)
delete descs[i];
numDescs = 0;
btPool.reset(); btPool.reset();
} }

View File

@ -21,5 +21,11 @@ void loopBLE();
BLEServer *initBLE(std::string devName, std::string hwVendor, std::string swVersion, std::string hwVersion = ""); BLEServer *initBLE(std::string devName, std::string hwVendor, std::string swVersion, std::string hwVersion = "");
void deinitBLE(); void deinitBLE();
/// Add a characteristic that we will delete when we restart
BLECharacteristic *addBLECharacteristic(BLECharacteristic *c);
/// Add a characteristic that we will delete when we restart
BLEDescriptor *addBLEDescriptor(BLEDescriptor *c);
/// Any bluetooth objects you allocate _must_ come from this pool if you want to be able to call deinitBLE() /// Any bluetooth objects you allocate _must_ come from this pool if you want to be able to call deinitBLE()
extern SimpleAllocator btPool; extern SimpleAllocator btPool;

View File

@ -300,24 +300,25 @@ BLEService *createMeshBluetoothService(BLEServer *server)
BLEService *service = server->createService(BLEUUID("6ba1b218-15a8-461f-9fa8-5dcae273eafd"), 25, 0); BLEService *service = server->createService(BLEUUID("6ba1b218-15a8-461f-9fa8-5dcae273eafd"), 25, 0);
assert(!meshFromNumCharacteristic); assert(!meshFromNumCharacteristic);
meshFromNumCharacteristic = new (btPool) FromNumCharacteristic; meshFromNumCharacteristic = new FromNumCharacteristic;
addWithDesc(service, meshFromNumCharacteristic, "fromRadio"); addWithDesc(service, meshFromNumCharacteristic, "fromRadio");
addWithDesc(service, new (btPool) ToRadioCharacteristic, "toRadio"); addWithDesc(service, new ToRadioCharacteristic, "toRadio");
addWithDesc(service, new (btPool) FromRadioCharacteristic, "fromNum"); addWithDesc(service, new FromRadioCharacteristic, "fromNum");
addWithDesc(service, new (btPool) ProtobufCharacteristic("ea9f3f82-8dc4-4733-9452-1f6da28892a2", BLECharacteristic::PROPERTY_READ, MyNodeInfo_fields, &myNodeInfo), "myNode"); addWithDesc(service, new ProtobufCharacteristic("ea9f3f82-8dc4-4733-9452-1f6da28892a2", BLECharacteristic::PROPERTY_READ, MyNodeInfo_fields, &myNodeInfo), "myNode");
addWithDesc(service, new (btPool) RadioCharacteristic, "radio"); addWithDesc(service, new RadioCharacteristic, "radio");
addWithDesc(service, new (btPool) OwnerCharacteristic, "owner"); addWithDesc(service, new OwnerCharacteristic, "owner");
addWithDesc(service, new (btPool) NodeInfoCharacteristic, "nodeinfo"); addWithDesc(service, new NodeInfoCharacteristic, "nodeinfo");
meshFromNumCharacteristic->addDescriptor(new (btPool) BLE2902()); // Needed so clients can request notification meshFromNumCharacteristic->addDescriptor(addBLEDescriptor(new BLE2902())); // Needed so clients can request notification
service->start(); service->start();
// We only add to advertisting once, because the ESP32 arduino code is dumb and that object never dies // We only add to advertisting once, because the ESP32 arduino code is dumb and that object never dies
static bool firstTime = true; static bool firstTime = true;
if(firstTime) { if (firstTime)
{
firstTime = false; firstTime = false;
server->getAdvertising()->addServiceUUID(service->getUUID()); server->getAdvertising()->addServiceUUID(service->getUUID());
} }
@ -329,7 +330,8 @@ BLEService *createMeshBluetoothService(BLEServer *server)
return service; return service;
} }
void destroyMeshBluetoothService() { void destroyMeshBluetoothService()
{
assert(meshService); assert(meshService);
delete meshService; delete meshService;