[Server] Add ability to create static attributes.

This allows creating instances of services/characteristics and decriptors without
needing to call the parent createX() methods. This allows creation of the attibutes
within a class or other structure and the attributes can be linked to the parent by
calling the parent addX() method.

Additonally this increases the backward compatibility with the original bluedroid library
to further support user migration.
This commit is contained in:
h2zero 2021-05-23 13:07:00 -06:00
parent 30d6c399b8
commit d9d794ae40
8 changed files with 103 additions and 52 deletions

View file

@ -42,6 +42,7 @@ struct BLE2904_Data {
*/ */
class NimBLE2904: public NimBLEDescriptor { class NimBLE2904: public NimBLEDescriptor {
public: public:
NimBLE2904(NimBLECharacteristic* pCharacterisitic = nullptr);
static const uint8_t FORMAT_BOOLEAN = 1; static const uint8_t FORMAT_BOOLEAN = 1;
static const uint8_t FORMAT_UINT2 = 2; static const uint8_t FORMAT_UINT2 = 2;
static const uint8_t FORMAT_UINT4 = 3; static const uint8_t FORMAT_UINT4 = 3;
@ -77,7 +78,6 @@ public:
void setUnit(uint16_t unit); void setUnit(uint16_t unit);
private: private:
NimBLE2904(NimBLECharacteristic* pCharacterisitic);
friend class NimBLECharacteristic; friend class NimBLECharacteristic;
BLE2904_Data m_data; BLE2904_Data m_data;
}; // BLE2904 }; // BLE2904

View file

@ -94,9 +94,20 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid,
pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this); pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this);
} }
m_dscVec.push_back(pDescriptor); addDescriptor(pDescriptor);
return 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 } // getService
void NimBLECharacteristic::setService(NimBLEService *pService) {
m_pService = pService;
}
/** /**
* @brief Get the UUID of the characteristic. * @brief Get the UUID of the characteristic.
* @return The UUID of the characteristic. * @return The UUID of the characteristic.

View file

@ -59,6 +59,18 @@ class NimBLECharacteristicCallbacks;
*/ */
class NimBLECharacteristic { class NimBLECharacteristic {
public: 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(); uint16_t getHandle();
NimBLEUUID getUUID(); NimBLEUUID getUUID();
@ -83,6 +95,7 @@ public:
NIMBLE_PROPERTY::WRITE, NIMBLE_PROPERTY::WRITE,
uint16_t max_len = 100); uint16_t max_len = 100);
void addDescriptor(NimBLEDescriptor *pDescriptor);
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);
@ -117,30 +130,15 @@ public:
setValue((uint8_t*)&s, sizeof(T)); setValue((uint8_t*)&s, sizeof(T));
} }
NimBLEService* getService();
uint16_t getProperties();
private: private:
friend class NimBLEServer; friend class NimBLEServer;
friend class NimBLEService; friend class NimBLEService;
NimBLECharacteristic(const char* uuid, void setService(NimBLEService *pService);
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 setSubscribe(struct ble_gap_event *event); void setSubscribe(struct ble_gap_event *event);
static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, static int 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);

View file

@ -37,6 +37,7 @@ NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16
: NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) { : NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) {
} }
/** /**
* @brief NimBLEDescriptor constructor. * @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_len = 0; // Initial length is 0.
m_value.attr_max_len = max_len; // Maximum length of the data. m_value.attr_max_len = max_len; // Maximum length of the data.
m_handle = NULL_HANDLE; // Handle is initially unknown. m_handle = NULL_HANDLE; // Handle is initially unknown.
m_pCharacteristic = nullptr; // No initial characteristic. m_pCharacteristic = pCharacteristic;
m_pCallbacks = &defaultCallbacks; // No initial callback. m_pCallbacks = &defaultCallbacks; // No initial callback.
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;
@ -122,6 +123,7 @@ uint8_t* NimBLEDescriptor::getValue() {
return m_value.attr_value; return m_value.attr_value;
} // getValue } // getValue
/** /**
* @brief Get the value of this descriptor as a string. * @brief Get the value of this descriptor as a string.
* @return A std::string instance containing a copy of the descriptor's value. * @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); 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, int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, struct ble_gatt_access_ctxt *ctxt, void *arg) {
void *arg) {
const ble_uuid_t *uuid; const ble_uuid_t *uuid;
int rc; int rc;
NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg; NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg;
@ -237,6 +248,14 @@ void NimBLEDescriptor::setValue(const std::string &value) {
setValue((uint8_t*) value.data(), value.length()); setValue((uint8_t*) value.data(), value.length());
} // setValue } // 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. * @brief Return a string representation of the descriptor.

View file

@ -43,46 +43,48 @@ class NimBLEDescriptorCallbacks;
*/ */
class NimBLEDescriptor { class NimBLEDescriptor {
public: public:
uint16_t getHandle(); NimBLEDescriptor(const char* uuid, uint16_t properties,
NimBLEUUID getUUID(); uint16_t max_len,
std::string toString(); NimBLECharacteristic* pCharacteristic = nullptr);
void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties,
uint16_t max_len,
NimBLECharacteristic* pCharacteristic = nullptr);
size_t getLength(); ~NimBLEDescriptor();
uint8_t* getValue();
std::string getStringValue(); 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 <type\>val. * @brief Convenience template to set the descriptor value to <type\>val.
* @param [in] s The value to set. * @param [in] s The value to set.
*/ */
template<typename T> template<typename T>
void setValue(const T &s) { void setValue(const T &s) {
setValue((uint8_t*)&s, sizeof(T)); setValue((uint8_t*)&s, sizeof(T));
} }
private: private:
friend class NimBLECharacteristic; friend class NimBLECharacteristic;
friend class NimBLEService; friend class NimBLEService;
friend class NimBLE2902;
friend class NimBLE2904; 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, static int 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);
void setHandle(uint16_t handle); void setHandle(uint16_t handle);
void setCharacteristic(NimBLECharacteristic* pChar);
NimBLEUUID m_uuid; NimBLEUUID m_uuid;
uint16_t m_handle; uint16_t m_handle;

View file

@ -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. * @param [in] service The service object to add.
* @note If it is desired to advertise the service it must be added by * @note If it is desired to advertise the service it must be added by
* calling NimBLEAdvertising::addServiceUUID. * calling NimBLEAdvertising::addServiceUUID.
*/ */
void NimBLEServer::addService(NimBLEService* service) { 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) { if(service->m_removed == 0) {
m_svcVec.push_back(service);
return; return;
} }

View file

@ -246,6 +246,11 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid
} // createCharacteristic } // 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. * @brief Get a pointer to the characteristic object with the specified UUID.
* @param [in] uuid The UUID of the characteristic. * @param [in] uuid The UUID of the characteristic.

View file

@ -36,6 +36,10 @@ class NimBLECharacteristic;
class NimBLEService { class NimBLEService {
public: public:
NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer);
NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer);
~NimBLEService();
NimBLEServer* getServer(); NimBLEServer* getServer();
NimBLEUUID getUUID(); NimBLEUUID getUUID();
@ -55,6 +59,7 @@ public:
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::WRITE); NIMBLE_PROPERTY::WRITE);
void addCharacteristic(NimBLECharacteristic* pCharacteristic);
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);
@ -65,9 +70,6 @@ public:
private: 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 NimBLEServer;
friend class NimBLEDevice; friend class NimBLEDevice;