mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-11-22 05:00:55 +01:00
Add feature: remove service (#17)
* Get service handles on server start * remove service + indicate service changed * Reset gatt services when no connections active and services changed. * NimBLEServer::createService can now be used any time and will send service changed indication if server was already active. * Add ability to remove advertised serviceUUIDS * Adds addService() method to server to be allow user to re-add a service previously removed * Add destructior to NimBLEServer, NimBLEService and NimBLECharacteristic to release allocated resources.
This commit is contained in:
parent
5857879612
commit
2a5df0c905
8 changed files with 275 additions and 75 deletions
|
@ -43,6 +43,14 @@ as a type specified by the user.
|
||||||
A new method `NimBLEServer::advertiseOnDisconnect(bool)` has been implemented to control this, true(default) = enabled.
|
A new method `NimBLEServer::advertiseOnDisconnect(bool)` has been implemented to control this, true(default) = enabled.
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
`NimBLEServer::removeService` takes an additional parameter `bool deleteSvc` that if true will delete the service
|
||||||
|
and all characteristics / descriptors belonging to it and invalidating any pointers to them.
|
||||||
|
|
||||||
|
If false the service is only removed from visibility by clients. The pointers to the service and
|
||||||
|
it's characteristics / descriptors will remain valid and the service can be re-added in the future
|
||||||
|
using `NimBLEServer::addService`.
|
||||||
|
<br/>
|
||||||
|
|
||||||
# Client
|
# Client
|
||||||
|
|
||||||
NimBLERemoteCharacteristic::readValue(time_t\*, bool)
|
NimBLERemoteCharacteristic::readValue(time_t\*, bool)
|
||||||
|
|
|
@ -63,6 +63,7 @@ NimBLEAdvertising::NimBLEAdvertising() {
|
||||||
*/
|
*/
|
||||||
void NimBLEAdvertising::addServiceUUID(const NimBLEUUID &serviceUUID) {
|
void NimBLEAdvertising::addServiceUUID(const NimBLEUUID &serviceUUID) {
|
||||||
m_serviceUUIDs.push_back(serviceUUID);
|
m_serviceUUIDs.push_back(serviceUUID);
|
||||||
|
m_advDataSet = false;
|
||||||
} // addServiceUUID
|
} // addServiceUUID
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,6 +76,22 @@ void NimBLEAdvertising::addServiceUUID(const char* serviceUUID) {
|
||||||
} // addServiceUUID
|
} // addServiceUUID
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a service uuid to exposed list of services.
|
||||||
|
* @param [in] serviceUUID The UUID of the service to expose.
|
||||||
|
*/
|
||||||
|
void NimBLEAdvertising::removeServiceUUID(const NimBLEUUID &serviceUUID) {
|
||||||
|
//m_serviceUUIDs.erase(std::remove_if(m_serviceUUIDs.begin(), m_serviceUUIDs.end(),[serviceUUID](const NimBLEUUID &s) {return serviceUUID == s;}), m_serviceUUIDs.end());
|
||||||
|
for(auto it = m_serviceUUIDs.begin(); it != m_serviceUUIDs.end(); ++it) {
|
||||||
|
if((*it) == serviceUUID) {
|
||||||
|
m_serviceUUIDs.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_advDataSet = false;
|
||||||
|
} // addServiceUUID
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the device appearance in the advertising data.
|
* @brief Set the device appearance in the advertising data.
|
||||||
* The codes for distinct appearances can be found here:\n
|
* The codes for distinct appearances can be found here:\n
|
||||||
|
|
|
@ -75,6 +75,7 @@ public:
|
||||||
NimBLEAdvertising();
|
NimBLEAdvertising();
|
||||||
void addServiceUUID(const NimBLEUUID &serviceUUID);
|
void addServiceUUID(const NimBLEUUID &serviceUUID);
|
||||||
void addServiceUUID(const char* serviceUUID);
|
void addServiceUUID(const char* serviceUUID);
|
||||||
|
void removeServiceUUID(const NimBLEUUID &serviceUUID);
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
void setAppearance(uint16_t appearance);
|
void setAppearance(uint16_t appearance);
|
||||||
|
|
|
@ -58,6 +58,9 @@ NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t prop
|
||||||
* @brief Destructor.
|
* @brief Destructor.
|
||||||
*/
|
*/
|
||||||
NimBLECharacteristic::~NimBLECharacteristic() {
|
NimBLECharacteristic::~NimBLECharacteristic() {
|
||||||
|
for(auto &it : m_dscVec) {
|
||||||
|
delete it;
|
||||||
|
}
|
||||||
} // ~NimBLECharacteristic
|
} // ~NimBLECharacteristic
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
#include "NimBLEDevice.h"
|
#include "NimBLEDevice.h"
|
||||||
#include "NimBLELog.h"
|
#include "NimBLELog.h"
|
||||||
|
|
||||||
|
#include "services/gap/ble_svc_gap.h"
|
||||||
|
#include "services/gatt/ble_svc_gatt.h"
|
||||||
|
|
||||||
|
|
||||||
static const char* LOG_TAG = "NimBLEServer";
|
static const char* LOG_TAG = "NimBLEServer";
|
||||||
static NimBLEServerCallbacks defaultCallbacks;
|
static NimBLEServerCallbacks defaultCallbacks;
|
||||||
|
|
||||||
|
@ -37,9 +41,20 @@ NimBLEServer::NimBLEServer() {
|
||||||
m_pServerCallbacks = &defaultCallbacks;
|
m_pServerCallbacks = &defaultCallbacks;
|
||||||
m_gattsStarted = false;
|
m_gattsStarted = false;
|
||||||
m_advertiseOnDisconnect = true;
|
m_advertiseOnDisconnect = true;
|
||||||
|
m_svcChanged = false;
|
||||||
} // NimBLEServer
|
} // NimBLEServer
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor: frees all resources / attributes created.
|
||||||
|
*/
|
||||||
|
NimBLEServer::~NimBLEServer() {
|
||||||
|
for(auto &it : m_svcVec) {
|
||||||
|
delete it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a %BLE Service.
|
* @brief Create a %BLE Service.
|
||||||
* @param [in] uuid The UUID of the new service.
|
* @param [in] uuid The UUID of the new service.
|
||||||
|
@ -71,6 +86,12 @@ NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid, uint32_t numH
|
||||||
NimBLEService* pService = new NimBLEService(uuid, numHandles, this);
|
NimBLEService* pService = new NimBLEService(uuid, numHandles, this);
|
||||||
m_svcVec.push_back(pService); // Save a reference to this service being on this server.
|
m_svcVec.push_back(pService); // Save a reference to this service being on this server.
|
||||||
|
|
||||||
|
if(m_gattsStarted) {
|
||||||
|
ble_svc_gatt_changed(0x0001, 0xffff);
|
||||||
|
m_svcChanged = true;
|
||||||
|
resetGATT();
|
||||||
|
}
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< createService");
|
NIMBLE_LOGD(LOG_TAG, "<< createService");
|
||||||
return pService;
|
return pService;
|
||||||
} // createService
|
} // createService
|
||||||
|
@ -146,8 +167,16 @@ void NimBLEServer::start() {
|
||||||
|
|
||||||
NIMBLE_LOGI(LOG_TAG, "Service changed characterisic handle: %d", m_svcChgChrHdl);
|
NIMBLE_LOGI(LOG_TAG, "Service changed characterisic handle: %d", m_svcChgChrHdl);
|
||||||
*/
|
*/
|
||||||
// Build a vector of characteristics with Notify / Indicate capabilities for event handling
|
// Get the assigned service handles and build a vector of characteristics
|
||||||
|
// with Notify / Indicate capabilities for event handling
|
||||||
for(auto &svc : m_svcVec) {
|
for(auto &svc : m_svcVec) {
|
||||||
|
if(svc->m_removed == 0) {
|
||||||
|
rc = ble_gatts_find_svc(&svc->getUUID().getNative()->u, &svc->m_handle);
|
||||||
|
if(rc != 0) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(auto &chr : svc->m_chrVec) {
|
for(auto &chr : svc->m_chrVec) {
|
||||||
// if Notify / Indicate is enabled but we didn't create the descriptor
|
// if Notify / Indicate is enabled but we didn't create the descriptor
|
||||||
// we do it now.
|
// we do it now.
|
||||||
|
@ -260,6 +289,11 @@ size_t NimBLEServer::getConnectedCount() {
|
||||||
server->m_connectedPeersVec.end(),
|
server->m_connectedPeersVec.end(),
|
||||||
event->disconnect.conn.conn_handle),
|
event->disconnect.conn.conn_handle),
|
||||||
server->m_connectedPeersVec.end());
|
server->m_connectedPeersVec.end());
|
||||||
|
|
||||||
|
if(server->m_svcChanged) {
|
||||||
|
server->resetGATT();
|
||||||
|
}
|
||||||
|
|
||||||
server->m_pServerCallbacks->onDisconnect(server);
|
server->m_pServerCallbacks->onDisconnect(server);
|
||||||
|
|
||||||
if(server->m_advertiseOnDisconnect) {
|
if(server->m_advertiseOnDisconnect) {
|
||||||
|
@ -445,6 +479,111 @@ void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks) {
|
||||||
} // setCallbacks
|
} // setCallbacks
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove a service from the server.
|
||||||
|
*
|
||||||
|
* @details Immediately removes access to the service by clients, sends a service changed indication,
|
||||||
|
* and removes the service (if applicable) from the advertisments.
|
||||||
|
* The service is not deleted unless the deleteSvc parameter is true, otherwise the service remains
|
||||||
|
* available and can be re-added in the future. If desired a removed but not deleted service can
|
||||||
|
* be deleted later by calling this method with deleteSvc set to true.
|
||||||
|
*
|
||||||
|
* @note The service will not be removed from the database until all open connections are closed
|
||||||
|
* as it requires resetting the GATT server. In the interim the service will have it's visibility disabled.
|
||||||
|
*
|
||||||
|
* @note Advertising will need to be restarted by the user after calling this as we must stop
|
||||||
|
* advertising in order to remove the service.
|
||||||
|
*
|
||||||
|
* @param [in] service The service object to remove.
|
||||||
|
* @param [in] deleteSvc true if the service should be deleted.
|
||||||
|
*/
|
||||||
|
void NimBLEServer::removeService(NimBLEService* service, bool deleteSvc) {
|
||||||
|
// Check if the service was already removed and if so check if this
|
||||||
|
// is being called to delete the object and do so if requested.
|
||||||
|
// Otherwise, ignore the call and return.
|
||||||
|
if(service->m_removed > 0) {
|
||||||
|
if(deleteSvc) {
|
||||||
|
for(auto it = m_svcVec.begin(); it != m_svcVec.end(); ++it) {
|
||||||
|
if ((*it)->getUUID() == service->getUUID()) {
|
||||||
|
delete *it;
|
||||||
|
m_svcVec.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = ble_gatts_svc_set_visibility(service->getHandle(), 0);
|
||||||
|
if(rc !=0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
service->m_removed = deleteSvc ? 2 : 1;
|
||||||
|
m_svcChanged = true;
|
||||||
|
|
||||||
|
ble_svc_gatt_changed(0x0001, 0xffff);
|
||||||
|
resetGATT();
|
||||||
|
NimBLEDevice::getAdvertising()->removeServiceUUID(service->getUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds a service which was already created, but removed from availability.
|
||||||
|
*
|
||||||
|
* @note If it is desired to advertise the service it must be added by
|
||||||
|
* calling NimBLEAdvertising::addServiceUUID.
|
||||||
|
*
|
||||||
|
* @param [in} service The service object to add.
|
||||||
|
*/
|
||||||
|
void NimBLEServer::addService(NimBLEService* service) {
|
||||||
|
// If adding a service that was not removed just return.
|
||||||
|
if(service->m_removed == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
service->m_removed = 0;
|
||||||
|
m_svcChanged = true;
|
||||||
|
|
||||||
|
ble_svc_gatt_changed(0x0001, 0xffff);
|
||||||
|
resetGATT();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resets the GATT server, used when services are added/removed after initialization.
|
||||||
|
*/
|
||||||
|
void NimBLEServer::resetGATT() {
|
||||||
|
if(getConnectedCount() > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NimBLEDevice::stopAdvertising();
|
||||||
|
ble_gatts_reset();
|
||||||
|
ble_svc_gap_init();
|
||||||
|
ble_svc_gatt_init();
|
||||||
|
|
||||||
|
for(auto it = m_svcVec.begin(); it != m_svcVec.end(); ) {
|
||||||
|
if ((*it)->m_removed > 0) {
|
||||||
|
if ((*it)->m_removed == 2) {
|
||||||
|
delete *it;
|
||||||
|
it = m_svcVec.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*it)->start();
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_svcChanged = false;
|
||||||
|
m_gattsStarted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start advertising.
|
* @brief Start advertising.
|
||||||
*
|
*
|
||||||
|
|
|
@ -41,6 +41,8 @@ public:
|
||||||
NimBLEService* createService(const char* uuid);
|
NimBLEService* createService(const char* uuid);
|
||||||
NimBLEService* createService(const NimBLEUUID &uuid, uint32_t numHandles=15,
|
NimBLEService* createService(const NimBLEUUID &uuid, uint32_t numHandles=15,
|
||||||
uint8_t inst_id=0);
|
uint8_t inst_id=0);
|
||||||
|
void removeService(NimBLEService* service, bool deleteSvc = false);
|
||||||
|
void addService(NimBLEService* service);
|
||||||
NimBLEAdvertising* getAdvertising();
|
NimBLEAdvertising* getAdvertising();
|
||||||
void setCallbacks(NimBLEServerCallbacks* pCallbacks);
|
void setCallbacks(NimBLEServerCallbacks* pCallbacks);
|
||||||
void startAdvertising();
|
void startAdvertising();
|
||||||
|
@ -59,12 +61,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NimBLEServer();
|
NimBLEServer();
|
||||||
|
~NimBLEServer();
|
||||||
friend class NimBLECharacteristic;
|
friend class NimBLECharacteristic;
|
||||||
friend class NimBLEDevice;
|
friend class NimBLEDevice;
|
||||||
friend class NimBLEAdvertising;
|
friend class NimBLEAdvertising;
|
||||||
|
|
||||||
bool m_gattsStarted;
|
bool m_gattsStarted;
|
||||||
bool m_advertiseOnDisconnect;
|
bool m_advertiseOnDisconnect;
|
||||||
|
bool m_svcChanged;
|
||||||
NimBLEServerCallbacks* m_pServerCallbacks;
|
NimBLEServerCallbacks* m_pServerCallbacks;
|
||||||
std::vector<uint16_t> m_connectedPeersVec;
|
std::vector<uint16_t> m_connectedPeersVec;
|
||||||
|
|
||||||
|
@ -74,6 +78,7 @@ private:
|
||||||
std::vector<NimBLECharacteristic*> m_notifyChrVec;
|
std::vector<NimBLECharacteristic*> m_notifyChrVec;
|
||||||
|
|
||||||
static int handleGapEvent(struct ble_gap_event *event, void *arg);
|
static int handleGapEvent(struct ble_gap_event *event, void *arg);
|
||||||
|
void resetGATT();
|
||||||
}; // NimBLEServer
|
}; // NimBLEServer
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,13 +49,35 @@ NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer
|
||||||
* @param [in] a pointer to the server instance that this service belongs to.
|
* @param [in] a pointer to the server instance that this service belongs to.
|
||||||
*/
|
*/
|
||||||
NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer) {
|
NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer) {
|
||||||
m_uuid = uuid;
|
m_uuid = uuid;
|
||||||
m_handle = NULL_HANDLE;
|
m_handle = NULL_HANDLE;
|
||||||
m_pServer = pServer;
|
m_pServer = pServer;
|
||||||
m_numHandles = numHandles;
|
m_numHandles = numHandles;
|
||||||
|
m_pSvcDef = nullptr;
|
||||||
|
m_removed = 0;
|
||||||
|
|
||||||
} // NimBLEService
|
} // NimBLEService
|
||||||
|
|
||||||
|
|
||||||
|
NimBLEService::~NimBLEService() {
|
||||||
|
if(m_pSvcDef != nullptr) {
|
||||||
|
if(m_pSvcDef->characteristics != nullptr) {
|
||||||
|
for(int i=0; m_pSvcDef->characteristics[i].uuid != NULL; ++i) {
|
||||||
|
if(m_pSvcDef->characteristics[i].descriptors) {
|
||||||
|
delete(m_pSvcDef->characteristics[i].descriptors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete(m_pSvcDef->characteristics);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(m_pSvcDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto &it : m_chrVec) {
|
||||||
|
delete it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Dump details of this BLE GATT service.
|
* @brief Dump details of this BLE GATT service.
|
||||||
* @return N/A.
|
* @return N/A.
|
||||||
|
@ -94,98 +116,101 @@ NimBLEUUID NimBLEService::getUUID() {
|
||||||
* and registers it with the NimBLE stack.
|
* and registers it with the NimBLE stack.
|
||||||
* @return bool success/failure .
|
* @return bool success/failure .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool NimBLEService::start() {
|
bool NimBLEService::start() {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: %s", toString().c_str());
|
NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: %s", toString().c_str());
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
// Nimble requires an array of services to be sent to the api
|
|
||||||
// Since we are adding 1 at a time we create an array of 2 and set the type
|
|
||||||
// of the second service to 0 to indicate the end of the array.
|
|
||||||
ble_gatt_svc_def* svc = new ble_gatt_svc_def[2];
|
|
||||||
ble_gatt_chr_def* pChr_a = nullptr;
|
|
||||||
ble_gatt_dsc_def* pDsc_a = nullptr;
|
|
||||||
|
|
||||||
svc[0].type = BLE_GATT_SVC_TYPE_PRIMARY;
|
if(m_pSvcDef == nullptr) {
|
||||||
svc[0].uuid = &m_uuid.getNative()->u;
|
// Nimble requires an array of services to be sent to the api
|
||||||
svc[0].includes = NULL;
|
// Since we are adding 1 at a time we create an array of 2 and set the type
|
||||||
|
// of the second service to 0 to indicate the end of the array.
|
||||||
|
ble_gatt_svc_def* svc = new ble_gatt_svc_def[2];
|
||||||
|
ble_gatt_chr_def* pChr_a = nullptr;
|
||||||
|
ble_gatt_dsc_def* pDsc_a = nullptr;
|
||||||
|
|
||||||
size_t numChrs = m_chrVec.size();
|
svc[0].type = BLE_GATT_SVC_TYPE_PRIMARY;
|
||||||
|
svc[0].uuid = &m_uuid.getNative()->u;
|
||||||
|
svc[0].includes = NULL;
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str());
|
size_t numChrs = m_chrVec.size();
|
||||||
|
|
||||||
if(!numChrs){
|
NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str());
|
||||||
svc[0].characteristics = NULL;
|
|
||||||
}else{
|
|
||||||
// Nimble requires the last characteristic to have it's uuid = 0 to indicate the end
|
|
||||||
// of the characteristics for the service. We create 1 extra and set it to null
|
|
||||||
// for this purpose.
|
|
||||||
pChr_a = new ble_gatt_chr_def[numChrs+1];
|
|
||||||
NimBLECharacteristic* pCharacteristic = *m_chrVec.begin();
|
|
||||||
|
|
||||||
for(uint8_t i=0; i < numChrs;) {
|
if(!numChrs){
|
||||||
uint8_t numDscs = pCharacteristic->m_dscVec.size();
|
svc[0].characteristics = NULL;
|
||||||
if(numDscs) {
|
}else{
|
||||||
// skip 2902 as it's automatically created by NimBLE
|
// Nimble requires the last characteristic to have it's uuid = 0 to indicate the end
|
||||||
// if Indicate or Notify flags are set
|
// of the characteristics for the service. We create 1 extra and set it to null
|
||||||
if(((pCharacteristic->m_properties & BLE_GATT_CHR_F_INDICATE) ||
|
// for this purpose.
|
||||||
(pCharacteristic->m_properties & BLE_GATT_CHR_F_NOTIFY)) &&
|
pChr_a = new ble_gatt_chr_def[numChrs+1];
|
||||||
pCharacteristic->getDescriptorByUUID("2902") != nullptr)
|
NimBLECharacteristic* pCharacteristic = *m_chrVec.begin();
|
||||||
{
|
|
||||||
numDscs--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!numDscs){
|
for(uint8_t i=0; i < numChrs;) {
|
||||||
pChr_a[i].descriptors = NULL;
|
uint8_t numDscs = pCharacteristic->m_dscVec.size();
|
||||||
} else {
|
if(numDscs) {
|
||||||
// Must have last descriptor uuid = 0 so we have to create 1 extra
|
// skip 2902 as it's automatically created by NimBLE
|
||||||
//NIMBLE_LOGD(LOG_TAG, "Adding %d descriptors", numDscs);
|
// if Indicate or Notify flags are set
|
||||||
pDsc_a = new ble_gatt_dsc_def[numDscs+1];
|
if(((pCharacteristic->m_properties & BLE_GATT_CHR_F_INDICATE) ||
|
||||||
NimBLEDescriptor* pDescriptor = *pCharacteristic->m_dscVec.begin();
|
(pCharacteristic->m_properties & BLE_GATT_CHR_F_NOTIFY)) &&
|
||||||
for(uint8_t d=0; d < numDscs;) {
|
pCharacteristic->getDescriptorByUUID("2902") != nullptr)
|
||||||
// skip 2902
|
{
|
||||||
if(pDescriptor->m_uuid == NimBLEUUID(uint16_t(0x2902))) {
|
numDscs--;
|
||||||
//NIMBLE_LOGD(LOG_TAG, "Skipped 0x2902");
|
|
||||||
pDescriptor = *(pCharacteristic->m_dscVec.begin()+d+1);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
pDsc_a[d].uuid = &pDescriptor->m_uuid.getNative()->u;
|
|
||||||
pDsc_a[d].att_flags = pDescriptor->m_properties;
|
|
||||||
pDsc_a[d].min_key_size = 0;
|
|
||||||
pDsc_a[d].access_cb = NimBLEDescriptor::handleGapEvent;
|
|
||||||
pDsc_a[d].arg = pDescriptor;
|
|
||||||
d++;
|
|
||||||
pDescriptor = *(pCharacteristic->m_dscVec.begin() + d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pDsc_a[numDscs].uuid = NULL;
|
if(!numDscs){
|
||||||
pChr_a[i].descriptors = pDsc_a;
|
pChr_a[i].descriptors = NULL;
|
||||||
|
} else {
|
||||||
|
// Must have last descriptor uuid = 0 so we have to create 1 extra
|
||||||
|
//NIMBLE_LOGD(LOG_TAG, "Adding %d descriptors", numDscs);
|
||||||
|
pDsc_a = new ble_gatt_dsc_def[numDscs+1];
|
||||||
|
NimBLEDescriptor* pDescriptor = *pCharacteristic->m_dscVec.begin();
|
||||||
|
for(uint8_t d=0; d < numDscs;) {
|
||||||
|
// skip 2902
|
||||||
|
if(pDescriptor->m_uuid == NimBLEUUID(uint16_t(0x2902))) {
|
||||||
|
//NIMBLE_LOGD(LOG_TAG, "Skipped 0x2902");
|
||||||
|
pDescriptor = *(pCharacteristic->m_dscVec.begin()+d+1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pDsc_a[d].uuid = &pDescriptor->m_uuid.getNative()->u;
|
||||||
|
pDsc_a[d].att_flags = pDescriptor->m_properties;
|
||||||
|
pDsc_a[d].min_key_size = 0;
|
||||||
|
pDsc_a[d].access_cb = NimBLEDescriptor::handleGapEvent;
|
||||||
|
pDsc_a[d].arg = pDescriptor;
|
||||||
|
d++;
|
||||||
|
pDescriptor = *(pCharacteristic->m_dscVec.begin() + d);
|
||||||
|
}
|
||||||
|
|
||||||
|
pDsc_a[numDscs].uuid = NULL;
|
||||||
|
pChr_a[i].descriptors = pDsc_a;
|
||||||
|
}
|
||||||
|
|
||||||
|
pChr_a[i].uuid = &pCharacteristic->m_uuid.getNative()->u;
|
||||||
|
pChr_a[i].access_cb = NimBLECharacteristic::handleGapEvent;
|
||||||
|
pChr_a[i].arg = pCharacteristic;
|
||||||
|
pChr_a[i].flags = pCharacteristic->m_properties;
|
||||||
|
pChr_a[i].min_key_size = 0;
|
||||||
|
pChr_a[i].val_handle = &pCharacteristic->m_handle;
|
||||||
|
i++;
|
||||||
|
pCharacteristic = *(m_chrVec.begin() + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
pChr_a[i].uuid = &pCharacteristic->m_uuid.getNative()->u;
|
pChr_a[numChrs].uuid = NULL;
|
||||||
pChr_a[i].access_cb = NimBLECharacteristic::handleGapEvent;
|
svc[0].characteristics = pChr_a;
|
||||||
pChr_a[i].arg = pCharacteristic;
|
|
||||||
pChr_a[i].flags = pCharacteristic->m_properties;
|
|
||||||
pChr_a[i].min_key_size = 0;
|
|
||||||
pChr_a[i].val_handle = &pCharacteristic->m_handle;
|
|
||||||
i++;
|
|
||||||
pCharacteristic = *(m_chrVec.begin() + i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pChr_a[numChrs].uuid = NULL;
|
// end of services must indicate to api with type = 0
|
||||||
svc[0].characteristics = pChr_a;
|
svc[1].type = 0;
|
||||||
|
m_pSvcDef = svc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of services must indicate to api with type = 0
|
rc = ble_gatts_count_cfg((const ble_gatt_svc_def*)m_pSvcDef);
|
||||||
svc[1].type = 0;
|
|
||||||
|
|
||||||
rc = ble_gatts_count_cfg((const ble_gatt_svc_def*)svc);
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "ble_gatts_count_cfg failed, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
NIMBLE_LOGE(LOG_TAG, "ble_gatts_count_cfg failed, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ble_gatts_add_svcs((const ble_gatt_svc_def*)svc);
|
rc = ble_gatts_add_svcs((const ble_gatt_svc_def*)m_pSvcDef);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "ble_gatts_add_svcs, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
NIMBLE_LOGE(LOG_TAG, "ble_gatts_add_svcs, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -57,6 +57,7 @@ public:
|
||||||
private:
|
private:
|
||||||
NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer);
|
NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer);
|
||||||
NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer);
|
NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer);
|
||||||
|
~NimBLEService();
|
||||||
|
|
||||||
friend class NimBLEServer;
|
friend class NimBLEServer;
|
||||||
friend class NimBLEDevice;
|
friend class NimBLEDevice;
|
||||||
|
@ -65,7 +66,8 @@ private:
|
||||||
NimBLEServer* m_pServer;
|
NimBLEServer* m_pServer;
|
||||||
NimBLEUUID m_uuid;
|
NimBLEUUID m_uuid;
|
||||||
uint16_t m_numHandles;
|
uint16_t m_numHandles;
|
||||||
|
ble_gatt_svc_def* m_pSvcDef;
|
||||||
|
uint8_t m_removed;
|
||||||
std::vector<NimBLECharacteristic*> m_chrVec;
|
std::vector<NimBLECharacteristic*> m_chrVec;
|
||||||
|
|
||||||
}; // NimBLEService
|
}; // NimBLEService
|
||||||
|
|
Loading…
Reference in a new issue