mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-11-22 05:00:55 +01:00
[Server] Implement remove Characteristics/Descriptors. (#54)
This allows for adding and removing of characteristics and descriptors after initial setup of the server. When used it will send a service changed notification to all clients. The changes will not take effect until all clients have disconnected and advertising restarted.
This commit is contained in:
parent
0a2714c169
commit
6be6a111d0
8 changed files with 195 additions and 55 deletions
|
@ -45,14 +45,15 @@ NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties
|
||||||
* @param [in] pService - pointer to the service instance this characteristic belongs to.
|
* @param [in] pService - pointer to the service instance this characteristic belongs to.
|
||||||
*/
|
*/
|
||||||
NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties, NimBLEService* pService) {
|
NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties, NimBLEService* pService) {
|
||||||
m_uuid = uuid;
|
m_uuid = uuid;
|
||||||
m_handle = NULL_HANDLE;
|
m_handle = NULL_HANDLE;
|
||||||
m_properties = properties;
|
m_properties = properties;
|
||||||
m_pCallbacks = &defaultCallback;
|
m_pCallbacks = &defaultCallback;
|
||||||
m_pService = pService;
|
m_pService = pService;
|
||||||
m_value = "";
|
m_value = "";
|
||||||
m_valMux = portMUX_INITIALIZER_UNLOCKED;
|
m_valMux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
m_timestamp = 0;
|
m_timestamp = 0;
|
||||||
|
m_removed = 0;
|
||||||
} // NimBLECharacteristic
|
} // NimBLECharacteristic
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,21 +96,63 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
addDescriptor(pDescriptor);
|
addDescriptor(pDescriptor);
|
||||||
|
|
||||||
return pDescriptor;
|
return pDescriptor;
|
||||||
} // createDescriptor
|
} // createDescriptor
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add a descriptor to the characteristic.
|
* @brief Add a descriptor to the characteristic.
|
||||||
* @param [in] A pointer to the descriptor to add.
|
* @param [in] pDescriptor A pointer to the descriptor to add.
|
||||||
*/
|
*/
|
||||||
void NimBLECharacteristic::addDescriptor(NimBLEDescriptor *pDescriptor) {
|
void NimBLECharacteristic::addDescriptor(NimBLEDescriptor *pDescriptor) {
|
||||||
|
bool foundRemoved = false;
|
||||||
|
|
||||||
|
if(pDescriptor->m_removed > 0) {
|
||||||
|
for(auto& it : m_dscVec) {
|
||||||
|
if(it == pDescriptor) {
|
||||||
|
foundRemoved = true;
|
||||||
|
pDescriptor->m_removed = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!foundRemoved) {
|
||||||
|
m_dscVec.push_back(pDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
pDescriptor->setCharacteristic(this);
|
pDescriptor->setCharacteristic(this);
|
||||||
m_dscVec.push_back(pDescriptor);
|
NimBLEDevice::getServer()->serviceChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove a descriptor from the characterisitc.
|
||||||
|
* @param[in] pDescriptor A pointer to the descriptor instance to remove from the characterisitc.
|
||||||
|
* @param[in] deleteDsc If true it will delete the descriptor instance and free it's resources.
|
||||||
|
*/
|
||||||
|
void NimBLECharacteristic::removeDescriptor(NimBLEDescriptor *pDescriptor, bool deleteDsc) {
|
||||||
|
// Check if the descriptor 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(pDescriptor->m_removed > 0) {
|
||||||
|
if(deleteDsc) {
|
||||||
|
for(auto it = m_dscVec.begin(); it != m_dscVec.end(); ++it) {
|
||||||
|
if ((*it) == pDescriptor) {
|
||||||
|
delete *it;
|
||||||
|
m_dscVec.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDescriptor->m_removed = deleteDsc ? NIMBLE_ATT_REMOVE_DELETE : NIMBLE_ATT_REMOVE_HIDE;
|
||||||
|
NimBLEDevice::getServer()->serviceChanged();
|
||||||
|
} // removeDescriptor
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the BLE Descriptor for the given UUID.
|
* @brief Return the BLE Descriptor for the given UUID.
|
||||||
* @param [in] uuid The UUID of the descriptor.
|
* @param [in] uuid The UUID of the descriptor.
|
||||||
|
|
|
@ -99,6 +99,7 @@ public:
|
||||||
NimBLEDescriptor* getDescriptorByUUID(const char* uuid);
|
NimBLEDescriptor* getDescriptorByUUID(const char* uuid);
|
||||||
NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid);
|
NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid);
|
||||||
NimBLEDescriptor* getDescriptorByHandle(uint16_t handle);
|
NimBLEDescriptor* getDescriptorByHandle(uint16_t handle);
|
||||||
|
void removeDescriptor(NimBLEDescriptor *pDescriptor, bool deleteDsc = false);
|
||||||
|
|
||||||
std::string getValue(time_t *timestamp = nullptr);
|
std::string getValue(time_t *timestamp = nullptr);
|
||||||
size_t getDataLength();
|
size_t getDataLength();
|
||||||
|
@ -152,6 +153,7 @@ private:
|
||||||
std::vector<NimBLEDescriptor*> m_dscVec;
|
std::vector<NimBLEDescriptor*> m_dscVec;
|
||||||
portMUX_TYPE m_valMux;
|
portMUX_TYPE m_valMux;
|
||||||
time_t m_timestamp;
|
time_t m_timestamp;
|
||||||
|
uint8_t m_removed;
|
||||||
|
|
||||||
std::vector<std::pair<uint16_t, uint16_t>> m_subscribedVec;
|
std::vector<std::pair<uint16_t, uint16_t>> m_subscribedVec;
|
||||||
}; // NimBLECharacteristic
|
}; // NimBLECharacteristic
|
||||||
|
|
|
@ -53,6 +53,7 @@ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_
|
||||||
m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value.
|
m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value.
|
||||||
m_valMux = portMUX_INITIALIZER_UNLOCKED;
|
m_valMux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
m_properties = 0;
|
m_properties = 0;
|
||||||
|
m_removed = 0;
|
||||||
|
|
||||||
if (properties & BLE_GATT_CHR_F_READ) { // convert uint16_t properties to uint8_t
|
if (properties & BLE_GATT_CHR_F_READ) { // convert uint16_t properties to uint8_t
|
||||||
m_properties |= BLE_ATT_F_READ;
|
m_properties |= BLE_ATT_F_READ;
|
||||||
|
|
|
@ -93,6 +93,7 @@ private:
|
||||||
uint8_t m_properties;
|
uint8_t m_properties;
|
||||||
attr_value_t m_value;
|
attr_value_t m_value;
|
||||||
portMUX_TYPE m_valMux;
|
portMUX_TYPE m_valMux;
|
||||||
|
uint8_t m_removed;
|
||||||
}; // NimBLEDescriptor
|
}; // NimBLEDescriptor
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -91,12 +91,7 @@ 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.
|
||||||
|
serviceChanged();
|
||||||
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;
|
||||||
|
@ -157,6 +152,18 @@ NimBLEAdvertising* NimBLEServer::getAdvertising() {
|
||||||
} // getAdvertising
|
} // getAdvertising
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sends a service changed notification and resets the GATT server.
|
||||||
|
*/
|
||||||
|
void NimBLEServer::serviceChanged() {
|
||||||
|
if(m_gattsStarted) {
|
||||||
|
m_svcChanged = true;
|
||||||
|
ble_svc_gatt_changed(0x0001, 0xffff);
|
||||||
|
resetGATT();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start the GATT server. Required to be called after setup of all
|
* @brief Start the GATT server. Required to be called after setup of all
|
||||||
* services and characteristics / descriptors for the NimBLE host to register them.
|
* services and characteristics / descriptors for the NimBLE host to register them.
|
||||||
|
@ -630,7 +637,7 @@ void NimBLEServer::removeService(NimBLEService* service, bool deleteSvc) {
|
||||||
if(service->m_removed > 0) {
|
if(service->m_removed > 0) {
|
||||||
if(deleteSvc) {
|
if(deleteSvc) {
|
||||||
for(auto it = m_svcVec.begin(); it != m_svcVec.end(); ++it) {
|
for(auto it = m_svcVec.begin(); it != m_svcVec.end(); ++it) {
|
||||||
if ((*it)->getUUID() == service->getUUID()) {
|
if ((*it) == service) {
|
||||||
delete *it;
|
delete *it;
|
||||||
m_svcVec.erase(it);
|
m_svcVec.erase(it);
|
||||||
break;
|
break;
|
||||||
|
@ -646,11 +653,8 @@ void NimBLEServer::removeService(NimBLEService* service, bool deleteSvc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
service->m_removed = deleteSvc ? 2 : 1;
|
service->m_removed = deleteSvc ? NIMBLE_ATT_REMOVE_DELETE : NIMBLE_ATT_REMOVE_HIDE;
|
||||||
m_svcChanged = true;
|
serviceChanged();
|
||||||
|
|
||||||
ble_svc_gatt_changed(0x0001, 0xffff);
|
|
||||||
resetGATT();
|
|
||||||
NimBLEDevice::getAdvertising()->removeServiceUUID(service->getUUID());
|
NimBLEDevice::getAdvertising()->removeServiceUUID(service->getUUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,10 +681,7 @@ void NimBLEServer::addService(NimBLEService* service) {
|
||||||
}
|
}
|
||||||
|
|
||||||
service->m_removed = 0;
|
service->m_removed = 0;
|
||||||
m_svcChanged = true;
|
serviceChanged();
|
||||||
|
|
||||||
ble_svc_gatt_changed(0x0001, 0xffff);
|
|
||||||
resetGATT();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -699,7 +700,7 @@ void NimBLEServer::resetGATT() {
|
||||||
|
|
||||||
for(auto it = m_svcVec.begin(); it != m_svcVec.end(); ) {
|
for(auto it = m_svcVec.begin(); it != m_svcVec.end(); ) {
|
||||||
if ((*it)->m_removed > 0) {
|
if ((*it)->m_removed > 0) {
|
||||||
if ((*it)->m_removed == 2) {
|
if ((*it)->m_removed == NIMBLE_ATT_REMOVE_DELETE) {
|
||||||
delete *it;
|
delete *it;
|
||||||
it = m_svcVec.erase(it);
|
it = m_svcVec.erase(it);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
|
||||||
|
#define NIMBLE_ATT_REMOVE_HIDE 1
|
||||||
|
#define NIMBLE_ATT_REMOVE_DELETE 2
|
||||||
|
|
||||||
#include "NimBLEUtils.h"
|
#include "NimBLEUtils.h"
|
||||||
#include "NimBLEAddress.h"
|
#include "NimBLEAddress.h"
|
||||||
#include "NimBLEAdvertising.h"
|
#include "NimBLEAdvertising.h"
|
||||||
|
@ -69,6 +72,7 @@ private:
|
||||||
NimBLEServer();
|
NimBLEServer();
|
||||||
~NimBLEServer();
|
~NimBLEServer();
|
||||||
friend class NimBLECharacteristic;
|
friend class NimBLECharacteristic;
|
||||||
|
friend class NimBLEService;
|
||||||
friend class NimBLEDevice;
|
friend class NimBLEDevice;
|
||||||
friend class NimBLEAdvertising;
|
friend class NimBLEAdvertising;
|
||||||
|
|
||||||
|
@ -86,6 +90,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 serviceChanged();
|
||||||
void resetGATT();
|
void resetGATT();
|
||||||
bool setIndicateWait(uint16_t conn_handle);
|
bool setIndicateWait(uint16_t conn_handle);
|
||||||
void clearIndicateWait(uint16_t conn_handle);
|
void clearIndicateWait(uint16_t conn_handle);
|
||||||
|
|
|
@ -35,7 +35,7 @@ static const char* LOG_TAG = "NimBLEService"; // Tag for logging.
|
||||||
* @brief Construct an instance of the NimBLEService
|
* @brief Construct an instance of the NimBLEService
|
||||||
* @param [in] uuid The UUID of the service.
|
* @param [in] uuid The UUID of the service.
|
||||||
* @param [in] numHandles The maximum number of handles associated with the service.
|
* @param [in] numHandles The maximum number of handles associated with the service.
|
||||||
* @param [in] a pointer to the server instance that this service belongs to.
|
* @param [in] pServer A pointer to the server instance that this service belongs to.
|
||||||
*/
|
*/
|
||||||
NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer)
|
NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer)
|
||||||
: NimBLEService(NimBLEUUID(uuid), numHandles, pServer) {
|
: NimBLEService(NimBLEUUID(uuid), numHandles, pServer) {
|
||||||
|
@ -46,7 +46,7 @@ NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer
|
||||||
* @brief Construct an instance of the BLEService
|
* @brief Construct an instance of the BLEService
|
||||||
* @param [in] uuid The UUID of the service.
|
* @param [in] uuid The UUID of the service.
|
||||||
* @param [in] numHandles The maximum number of handles associated with the service.
|
* @param [in] numHandles The maximum number of handles associated with the service.
|
||||||
* @param [in] a pointer to the server instance that this service belongs to.
|
* @param [in] pServer 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;
|
||||||
|
@ -118,7 +118,12 @@ NimBLEUUID NimBLEService::getUUID() {
|
||||||
*/
|
*/
|
||||||
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;
|
|
||||||
|
// Rebuild the service definition if the server attributes have changed.
|
||||||
|
if(getServer()->m_svcChanged && m_pSvcDef != nullptr) {
|
||||||
|
delete(m_pSvcDef);
|
||||||
|
m_pSvcDef = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if(m_pSvcDef == nullptr) {
|
if(m_pSvcDef == nullptr) {
|
||||||
// Nimble requires an array of services to be sent to the api
|
// Nimble requires an array of services to be sent to the api
|
||||||
|
@ -132,8 +137,23 @@ bool NimBLEService::start() {
|
||||||
svc[0].uuid = &m_uuid.getNative()->u;
|
svc[0].uuid = &m_uuid.getNative()->u;
|
||||||
svc[0].includes = NULL;
|
svc[0].includes = NULL;
|
||||||
|
|
||||||
size_t numChrs = m_chrVec.size();
|
int removedCount = 0;
|
||||||
|
for(auto it = m_chrVec.begin(); it != m_chrVec.end(); ) {
|
||||||
|
if ((*it)->m_removed > 0) {
|
||||||
|
if ((*it)->m_removed == NIMBLE_ATT_REMOVE_DELETE) {
|
||||||
|
delete *it;
|
||||||
|
it = m_chrVec.erase(it);
|
||||||
|
} else {
|
||||||
|
++removedCount;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t numChrs = m_chrVec.size() - removedCount;
|
||||||
NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str());
|
NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str());
|
||||||
|
|
||||||
if(!numChrs){
|
if(!numChrs){
|
||||||
|
@ -142,40 +162,60 @@ bool NimBLEService::start() {
|
||||||
// Nimble requires the last characteristic to have it's uuid = 0 to indicate the end
|
// 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
|
// of the characteristics for the service. We create 1 extra and set it to null
|
||||||
// for this purpose.
|
// for this purpose.
|
||||||
pChr_a = new ble_gatt_chr_def[numChrs+1];
|
pChr_a = new ble_gatt_chr_def[numChrs + 1];
|
||||||
NimBLECharacteristic* pCharacteristic = *m_chrVec.begin();
|
uint8_t i = 0;
|
||||||
|
for(auto chr_it = m_chrVec.begin(); chr_it != m_chrVec.end(); ++chr_it) {
|
||||||
|
if((*chr_it)->m_removed > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for(uint8_t i=0; i < numChrs;) {
|
removedCount = 0;
|
||||||
uint8_t numDscs = pCharacteristic->m_dscVec.size();
|
for(auto it = (*chr_it)->m_dscVec.begin(); it != (*chr_it)->m_dscVec.end(); ) {
|
||||||
|
if ((*it)->m_removed > 0) {
|
||||||
|
if ((*it)->m_removed == NIMBLE_ATT_REMOVE_DELETE) {
|
||||||
|
delete *it;
|
||||||
|
it = (*chr_it)->m_dscVec.erase(it);
|
||||||
|
} else {
|
||||||
|
++removedCount;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t numDscs = (*chr_it)->m_dscVec.size() - removedCount;
|
||||||
|
|
||||||
if(!numDscs){
|
if(!numDscs){
|
||||||
pChr_a[i].descriptors = NULL;
|
pChr_a[i].descriptors = NULL;
|
||||||
} else {
|
} else {
|
||||||
// Must have last descriptor uuid = 0 so we have to create 1 extra
|
// Must have last descriptor uuid = 0 so we have to create 1 extra
|
||||||
pDsc_a = new ble_gatt_dsc_def[numDscs+1];
|
pDsc_a = new ble_gatt_dsc_def[numDscs+1];
|
||||||
NimBLEDescriptor* pDescriptor = *pCharacteristic->m_dscVec.begin();
|
uint8_t d = 0;
|
||||||
for(uint8_t d=0; d < numDscs;) {
|
for(auto dsc_it = (*chr_it)->m_dscVec.begin(); dsc_it != (*chr_it)->m_dscVec.end(); ++dsc_it ) {
|
||||||
pDsc_a[d].uuid = &pDescriptor->m_uuid.getNative()->u;
|
if((*dsc_it)->m_removed > 0) {
|
||||||
pDsc_a[d].att_flags = pDescriptor->m_properties;
|
continue;
|
||||||
|
}
|
||||||
|
pDsc_a[d].uuid = &(*dsc_it)->m_uuid.getNative()->u;
|
||||||
|
pDsc_a[d].att_flags = (*dsc_it)->m_properties;
|
||||||
pDsc_a[d].min_key_size = 0;
|
pDsc_a[d].min_key_size = 0;
|
||||||
pDsc_a[d].access_cb = NimBLEDescriptor::handleGapEvent;
|
pDsc_a[d].access_cb = NimBLEDescriptor::handleGapEvent;
|
||||||
pDsc_a[d].arg = pDescriptor;
|
pDsc_a[d].arg = (*dsc_it);
|
||||||
d++;
|
++d;
|
||||||
pDescriptor = *(pCharacteristic->m_dscVec.begin() + d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pDsc_a[numDscs].uuid = NULL;
|
pDsc_a[numDscs].uuid = NULL;
|
||||||
pChr_a[i].descriptors = pDsc_a;
|
pChr_a[i].descriptors = pDsc_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
pChr_a[i].uuid = &pCharacteristic->m_uuid.getNative()->u;
|
pChr_a[i].uuid = &(*chr_it)->m_uuid.getNative()->u;
|
||||||
pChr_a[i].access_cb = NimBLECharacteristic::handleGapEvent;
|
pChr_a[i].access_cb = NimBLECharacteristic::handleGapEvent;
|
||||||
pChr_a[i].arg = pCharacteristic;
|
pChr_a[i].arg = (*chr_it);
|
||||||
pChr_a[i].flags = pCharacteristic->m_properties;
|
pChr_a[i].flags = (*chr_it)->m_properties;
|
||||||
pChr_a[i].min_key_size = 0;
|
pChr_a[i].min_key_size = 0;
|
||||||
pChr_a[i].val_handle = &pCharacteristic->m_handle;
|
pChr_a[i].val_handle = &(*chr_it)->m_handle;
|
||||||
i++;
|
++i;
|
||||||
pCharacteristic = *(m_chrVec.begin() + i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pChr_a[numChrs].uuid = NULL;
|
pChr_a[numChrs].uuid = NULL;
|
||||||
|
@ -187,7 +227,7 @@ bool NimBLEService::start() {
|
||||||
m_pSvcDef = svc;
|
m_pSvcDef = svc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ble_gatts_count_cfg((const ble_gatt_svc_def*)m_pSvcDef);
|
int rc = ble_gatts_count_cfg((const ble_gatt_svc_def*)m_pSvcDef);
|
||||||
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;
|
||||||
|
@ -239,17 +279,63 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid
|
||||||
std::string(uuid).c_str());
|
std::string(uuid).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember this characteristic in our vector of characteristics.
|
addCharacteristic(pCharacteristic);
|
||||||
m_chrVec.push_back(pCharacteristic);
|
|
||||||
|
|
||||||
return pCharacteristic;
|
return pCharacteristic;
|
||||||
} // createCharacteristic
|
} // createCharacteristic
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a characteristic to the service.
|
||||||
|
* @param[in] pCharacteristic A pointer to the characteristic instance to add to the service.
|
||||||
|
*/
|
||||||
void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) {
|
void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) {
|
||||||
|
bool foundRemoved = false;
|
||||||
|
|
||||||
|
if(pCharacteristic->m_removed > 0) {
|
||||||
|
for(auto& it : m_chrVec) {
|
||||||
|
if(it == pCharacteristic) {
|
||||||
|
foundRemoved = true;
|
||||||
|
pCharacteristic->m_removed = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!foundRemoved) {
|
||||||
|
m_chrVec.push_back(pCharacteristic);
|
||||||
|
}
|
||||||
|
|
||||||
pCharacteristic->setService(this);
|
pCharacteristic->setService(this);
|
||||||
m_chrVec.push_back(pCharacteristic);
|
getServer()->serviceChanged();
|
||||||
}
|
} // addCharacteristic
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove a characteristic from the service.
|
||||||
|
* @param[in] pCharacteristic A pointer to the characteristic instance to remove from the service.
|
||||||
|
* @param[in] deleteChr If true it will delete the characteristic instance and free it's resources.
|
||||||
|
*/
|
||||||
|
void NimBLEService::removeCharacteristic(NimBLECharacteristic* pCharacteristic, bool deleteChr) {
|
||||||
|
// Check if the characteristic 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(pCharacteristic->m_removed > 0) {
|
||||||
|
if(deleteChr) {
|
||||||
|
for(auto it = m_chrVec.begin(); it != m_chrVec.end(); ++it) {
|
||||||
|
if ((*it) == pCharacteristic) {
|
||||||
|
m_chrVec.erase(it);
|
||||||
|
delete *it;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCharacteristic->m_removed = deleteChr ? NIMBLE_ATT_REMOVE_DELETE : NIMBLE_ATT_REMOVE_HIDE;
|
||||||
|
getServer()->serviceChanged();
|
||||||
|
} // removeCharacteristic
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a pointer to the characteristic object with the specified UUID.
|
* @brief Get a pointer to the characteristic object with the specified UUID.
|
||||||
|
|
|
@ -60,6 +60,7 @@ public:
|
||||||
NIMBLE_PROPERTY::WRITE);
|
NIMBLE_PROPERTY::WRITE);
|
||||||
|
|
||||||
void addCharacteristic(NimBLECharacteristic* pCharacteristic);
|
void addCharacteristic(NimBLECharacteristic* pCharacteristic);
|
||||||
|
void removeCharacteristic(NimBLECharacteristic* pCharacteristic, bool deleteChr = false);
|
||||||
NimBLECharacteristic* getCharacteristic(const char* uuid, uint16_t instanceId = 0);
|
NimBLECharacteristic* getCharacteristic(const char* uuid, uint16_t instanceId = 0);
|
||||||
NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid, uint16_t instanceId = 0);
|
NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid, uint16_t instanceId = 0);
|
||||||
NimBLECharacteristic* getCharacteristicByHandle(uint16_t handle);
|
NimBLECharacteristic* getCharacteristicByHandle(uint16_t handle);
|
||||||
|
|
Loading…
Reference in a new issue