diff --git a/src/NimBLE2904.h b/src/NimBLE2904.h index 0a6d036..d8800dd 100644 --- a/src/NimBLE2904.h +++ b/src/NimBLE2904.h @@ -42,6 +42,7 @@ struct BLE2904_Data { */ class NimBLE2904: public NimBLEDescriptor { public: + NimBLE2904(NimBLECharacteristic* pCharacterisitic = nullptr); static const uint8_t FORMAT_BOOLEAN = 1; static const uint8_t FORMAT_UINT2 = 2; static const uint8_t FORMAT_UINT4 = 3; @@ -77,7 +78,6 @@ public: void setUnit(uint16_t unit); private: - NimBLE2904(NimBLECharacteristic* pCharacterisitic); friend class NimBLECharacteristic; BLE2904_Data m_data; }; // BLE2904 diff --git a/src/NimBLECharacteristic.cpp b/src/NimBLECharacteristic.cpp index 9e31255..39e7edf 100644 --- a/src/NimBLECharacteristic.cpp +++ b/src/NimBLECharacteristic.cpp @@ -94,9 +94,20 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this); } - m_dscVec.push_back(pDescriptor); + addDescriptor(pDescriptor); + return pDescriptor; -} // createCharacteristic +} // createDescriptor + + +/** + * @brief Add a descriptor to the characteristic. + * @param [in] A pointer to the descriptor to add. + */ +void NimBLECharacteristic::addDescriptor(NimBLEDescriptor *pDescriptor) { + pDescriptor->setCharacteristic(this); + m_dscVec.push_back(pDescriptor); +} /** @@ -164,6 +175,11 @@ NimBLEService* NimBLECharacteristic::getService() { } // getService +void NimBLECharacteristic::setService(NimBLEService *pService) { + m_pService = pService; +} + + /** * @brief Get the UUID of the characteristic. * @return The UUID of the characteristic. diff --git a/src/NimBLECharacteristic.h b/src/NimBLECharacteristic.h index aee21b0..7685b2a 100644 --- a/src/NimBLECharacteristic.h +++ b/src/NimBLECharacteristic.h @@ -59,6 +59,18 @@ class NimBLECharacteristicCallbacks; */ class NimBLECharacteristic { public: + NimBLECharacteristic(const char* uuid, + uint16_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + NimBLECharacteristic(const NimBLEUUID &uuid, + uint16_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + + ~NimBLECharacteristic(); uint16_t getHandle(); NimBLEUUID getUUID(); @@ -83,6 +95,7 @@ public: NIMBLE_PROPERTY::WRITE, uint16_t max_len = 100); + void addDescriptor(NimBLEDescriptor *pDescriptor); NimBLEDescriptor* getDescriptorByUUID(const char* uuid); NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid); NimBLEDescriptor* getDescriptorByHandle(uint16_t handle); @@ -117,30 +130,15 @@ public: setValue((uint8_t*)&s, sizeof(T)); } - - - + NimBLEService* getService(); + uint16_t getProperties(); private: - friend class NimBLEServer; - friend class NimBLEService; + friend class NimBLEServer; + friend class NimBLEService; - NimBLECharacteristic(const char* uuid, - uint16_t properties = - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE, - NimBLEService* pService = nullptr); - NimBLECharacteristic(const NimBLEUUID &uuid, - uint16_t properties = - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE, - NimBLEService* pService = nullptr); - - ~NimBLECharacteristic(); - - NimBLEService* getService(); - uint16_t getProperties(); + void setService(NimBLEService *pService); void setSubscribe(struct ble_gap_event *event); static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); diff --git a/src/NimBLEDescriptor.cpp b/src/NimBLEDescriptor.cpp index 5f3e97f..db7aea5 100644 --- a/src/NimBLEDescriptor.cpp +++ b/src/NimBLEDescriptor.cpp @@ -37,6 +37,7 @@ NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16 : NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) { } + /** * @brief NimBLEDescriptor constructor. */ @@ -47,7 +48,7 @@ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_ m_value.attr_len = 0; // Initial length is 0. m_value.attr_max_len = max_len; // Maximum length of the data. m_handle = NULL_HANDLE; // Handle is initially unknown. - m_pCharacteristic = nullptr; // No initial characteristic. + m_pCharacteristic = pCharacteristic; m_pCallbacks = &defaultCallbacks; // No initial callback. m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value. m_valMux = portMUX_INITIALIZER_UNLOCKED; @@ -122,6 +123,7 @@ uint8_t* NimBLEDescriptor::getValue() { return m_value.attr_value; } // getValue + /** * @brief Get the value of this descriptor as a string. * @return A std::string instance containing a copy of the descriptor's value. @@ -130,9 +132,18 @@ std::string NimBLEDescriptor::getStringValue() { return std::string((char *) m_value.attr_value, m_value.attr_len); } + +/** + * @brief Get the characteristic this descriptor belongs to. + * @return A pointer to the characteristic this descriptor belongs to. + */ +NimBLECharacteristic* NimBLEDescriptor::getCharacteristic() { + return m_pCharacteristic; +} // getCharacteristic + + int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) { + struct ble_gatt_access_ctxt *ctxt, void *arg) { const ble_uuid_t *uuid; int rc; NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg; @@ -237,6 +248,14 @@ void NimBLEDescriptor::setValue(const std::string &value) { setValue((uint8_t*) value.data(), value.length()); } // setValue +/** + * @brief Set the characteristic this descriptor belongs to. + * @param [in] pChar A pointer to the characteristic this descriptior belongs to. + */ +void NimBLEDescriptor::setCharacteristic(NimBLECharacteristic* pChar) { + m_pCharacteristic = pChar; +} // setCharacteristic + /** * @brief Return a string representation of the descriptor. diff --git a/src/NimBLEDescriptor.h b/src/NimBLEDescriptor.h index 76318b7..d325c7b 100644 --- a/src/NimBLEDescriptor.h +++ b/src/NimBLEDescriptor.h @@ -43,46 +43,48 @@ class NimBLEDescriptorCallbacks; */ class NimBLEDescriptor { public: - uint16_t getHandle(); - NimBLEUUID getUUID(); - std::string toString(); + NimBLEDescriptor(const char* uuid, uint16_t properties, + uint16_t max_len, + NimBLECharacteristic* pCharacteristic = nullptr); - void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); + NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, + uint16_t max_len, + NimBLECharacteristic* pCharacteristic = nullptr); - size_t getLength(); - uint8_t* getValue(); - std::string getStringValue(); + ~NimBLEDescriptor(); + + uint16_t getHandle(); + NimBLEUUID getUUID(); + std::string toString(); + + void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); + + size_t getLength(); + uint8_t* getValue(); + std::string getStringValue(); + + void setValue(const uint8_t* data, size_t size); + void setValue(const std::string &value); + NimBLECharacteristic* getCharacteristic(); - void setValue(const uint8_t* data, size_t size); - void setValue(const std::string &value); /** * @brief Convenience template to set the descriptor value to val. * @param [in] s The value to set. */ template - void setValue(const T &s) { + void setValue(const T &s) { setValue((uint8_t*)&s, sizeof(T)); } private: friend class NimBLECharacteristic; friend class NimBLEService; - friend class NimBLE2902; friend class NimBLE2904; - NimBLEDescriptor(const char* uuid, uint16_t properties, - uint16_t max_len, - NimBLECharacteristic* pCharacteristic); - - NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, - uint16_t max_len, - NimBLECharacteristic* pCharacteristic); - - ~NimBLEDescriptor(); - static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); void setHandle(uint16_t handle); + void setCharacteristic(NimBLECharacteristic* pChar); NimBLEUUID m_uuid; uint16_t m_handle; diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index 1b88503..ca4729d 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -650,14 +650,23 @@ void NimBLEServer::removeService(NimBLEService* service, bool deleteSvc) { /** - * @brief Adds a service which was already created, but removed from availability. + * @brief Adds a service which was either already created but removed from availability,\n + * or created and later added to services list. * @param [in] service The service object to add. * @note If it is desired to advertise the service it must be added by * calling NimBLEAdvertising::addServiceUUID. */ void NimBLEServer::addService(NimBLEService* service) { - // If adding a service that was not removed just return. + // Check that a service with the supplied UUID does not already exist. + if(getServiceByUUID(service->getUUID()) != nullptr) { + NIMBLE_LOGW(LOG_TAG, "Warning creating a duplicate service UUID: %s", + std::string(service->getUUID()).c_str()); + } + + // If adding a service that was not removed add it and return. + // Else reset GATT and send service changed notification. if(service->m_removed == 0) { + m_svcVec.push_back(service); return; } diff --git a/src/NimBLEService.cpp b/src/NimBLEService.cpp index a830eec..422eefe 100644 --- a/src/NimBLEService.cpp +++ b/src/NimBLEService.cpp @@ -246,6 +246,11 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid } // createCharacteristic +void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) { + pCharacteristic->setService(this); + m_chrVec.push_back(pCharacteristic); +} + /** * @brief Get a pointer to the characteristic object with the specified UUID. * @param [in] uuid The UUID of the characteristic. diff --git a/src/NimBLEService.h b/src/NimBLEService.h index 1203d3e..57e92c0 100644 --- a/src/NimBLEService.h +++ b/src/NimBLEService.h @@ -36,6 +36,10 @@ class NimBLECharacteristic; class NimBLEService { public: + NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer); + NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer); + ~NimBLEService(); + NimBLEServer* getServer(); NimBLEUUID getUUID(); @@ -55,6 +59,7 @@ public: NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE); + void addCharacteristic(NimBLECharacteristic* pCharacteristic); NimBLECharacteristic* getCharacteristic(const char* uuid, uint16_t instanceId = 0); NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid, uint16_t instanceId = 0); NimBLECharacteristic* getCharacteristicByHandle(uint16_t handle); @@ -65,9 +70,6 @@ public: private: - NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer); - NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer); - ~NimBLEService(); friend class NimBLEServer; friend class NimBLEDevice;