In my application I use three services and one of them contains several characteristics.
The issue is that not all of them are advertised.
I've read that it can happen when you have multiple requests of adding characteristics / descriptors / services and you should wait for onDescriptorWrite event in BluetoothGattCallback to avoid this.
But how exactly ?
I actually use the kolban's libraries and I don't understand how to monitor such events within them.
Here below is my setup code.
BTW: In this case just the first three characteristics are visibile and working. Tested by nRF Android app.
Code: Select all
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
BLECharacteristic* pChar_Flow=NULL;
BLECharacteristic* pChar_SingleShotVolume=NULL;
BLECharacteristic* pChar_DailyConsume=NULL;
BLECharacteristic* pChar_WeekDay=NULL;
BLECharacteristic* pChar_Time=NULL;
BLECharacteristic* pChar_K=NULL;
BLECharacteristic* pChar_Message=NULL;
BLECharacteristic* pChar_DetailedConsume=NULL;
BLECharacteristic* pChar_BatteryLevel=NULL;
BLECharacteristic* pOtaCharacteristic=NULL;
void setup()
{
BLEDescriptor *pDescriptor;
BLE2902 *pDescriptor2902;
esp_log_level_set("*", ESP_LOG_VERBOSE);
esp_log_set_vprintf(print_F);
Serial.begin(115200);
if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED))
{
Serial.println("SPIFFS Mount Failed");
return;
}
setupOTA();
BLEDevice::init("SWater");
BLEDevice::setMTU(BLEMTU);
pServer = BLEDevice::createServer();
pServer->setCallbacks(new ServerCallbacks());
BLEService *pService = pServer->createService(SERVICE_UUID);
pChar_Flow = pService->createCharacteristic(
CHAR_UUID_FLOWRATE,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_NOTIFY
);
pDescriptor = new BLEDescriptor((uint16_t)0x2901); // Characteristic User Description
pDescriptor->setValue("Flow rate");
pDescriptor2902=new BLE2902();
pDescriptor2902->setNotifications(true);
pChar_Flow->addDescriptor(pDescriptor);
pChar_Flow->addDescriptor(pDescriptor2902);
pChar_Flow->setCallbacks(new UpdateFlow());
pChar_SingleShotVolume = pService->createCharacteristic(
CHAR_UUID_SINGLESHOTVOLUME,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
pDescriptor = new BLEDescriptor((uint16_t)0x2901); // Characteristic User Description
pDescriptor->setValue("Single shot volume");
pDescriptor2902=new BLE2902();
pDescriptor2902->setNotifications(true);
pChar_SingleShotVolume->addDescriptor(pDescriptor);
pChar_SingleShotVolume->addDescriptor(pDescriptor2902);
pChar_SingleShotVolume->setCallbacks(new UpdateSSV());
pChar_DailyConsume = pService->createCharacteristic(
CHAR_UUID_DAILYCONSUME,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_NOTIFY
);
pDescriptor = new BLEDescriptor((uint16_t)0x2901); // Characteristic User Description
pDescriptor->setValue("Daily consume");
pDescriptor2902=new BLE2902();
pDescriptor2902->setNotifications(true);
pChar_DailyConsume->addDescriptor(pDescriptor);
pChar_DailyConsume->addDescriptor(pDescriptor2902);
pChar_DailyConsume->setCallbacks(new UpdateWC());
pChar_DetailedConsume = pService->createCharacteristic(
CHAR_UUID_DETAILEDCONSUME,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_NOTIFY
);
pDescriptor = new BLEDescriptor((uint16_t)0x2901); // Characteristic User Description
pDescriptor->setValue("Detailed consume");
pDescriptor2902=new BLE2902();
pDescriptor2902->setNotifications(true);
pChar_DetailedConsume->addDescriptor(pDescriptor);
pChar_DetailedConsume->addDescriptor(pDescriptor2902);
pChar_DetailedConsume->setCallbacks(new UpdateDC());
pChar_K = pService->createCharacteristic(CHAR_UUID_KFLOW,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
pDescriptor = new BLEDescriptor((uint16_t)0x2901); // Characteristic User Description
pDescriptor->setValue("Generic control");
pDescriptor2902=new BLE2902();
pDescriptor2902->setNotifications(true);
pChar_K->addDescriptor(pDescriptor);
pChar_K->addDescriptor(pDescriptor2902);
pChar_K->setCallbacks(new UpdateK());
pChar_K->setValue(KFlowStr);
pChar_Time = pService->createCharacteristic(CHAR_UUID_TIME,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
pDescriptor = new BLEDescriptor((uint16_t)0x2901); // Characteristic User Description
pDescriptor->setValue("DateTime");
pDescriptor2902=new BLE2902();
pDescriptor2902->setNotifications(true);
pChar_Time->addDescriptor(pDescriptor);
pChar_Time->addDescriptor(pDescriptor2902);
pChar_Time->setCallbacks(new UpdateTime());
pChar_Message = pService->createCharacteristic(CHAR_UUID_MESSAGE,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
pDescriptor = new BLEDescriptor((uint16_t)0x2901); // Characteristic User Description
pDescriptor->setValue("Message");
pDescriptor2902=new BLE2902();
pDescriptor2902->setNotifications(true);
PacketReadMsg=false;
pChar_Message->addDescriptor(pDescriptor);
pChar_Message->addDescriptor(pDescriptor2902);
pChar_Message->setCallbacks(new UpdateMessage());
pChar_Message->setValue("");
pService->start();
BLEService *pServiceBat = pServer->createService(SERVICE_BATTERYUUID);
pChar_BatteryLevel = pServiceBat->createCharacteristic(
CHAR_UUID_BATTERYLEVEL,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_NOTIFY
);
pChar_BatteryLevel->addDescriptor(new BLE2902());
pChar_BatteryLevel->setCallbacks(new UpdateBatteryLevel());
pServiceBat->start();
BLEService *pServiceOTA = pServer->createService(SERVICE_UUID_OTA);
pOtaCharacteristic = pServiceOTA->createCharacteristic(
CHARACTERISTIC_UUID_FW,
BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_WRITE_NR
);
//pOtaCharacteristic->addDescriptor(new BLE2902());
pOtaCharacteristic->setCallbacks(new otaCallback());
pServiceOTA->start();
Serial.println("Create services...done");
// BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->addServiceUUID(SERVICE_BATTERYUUID);
pAdvertising->addServiceUUID(SERVICE_UUID_OTA);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue (0x06)
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();