BLE: GattServer PIMPL

pull/13475/head
Vincent Coubard 2020-08-21 12:15:13 +01:00
parent 2b48d4826e
commit cf3ede0191
4 changed files with 342 additions and 246 deletions

View File

@ -95,6 +95,10 @@ namespace ble {
* the nature of the server initiated is not relevant. * the nature of the server initiated is not relevant.
*/ */
#if !defined(DOXYGEN_ONLY) #if !defined(DOXYGEN_ONLY)
namespace impl {
class GattServer;
}
namespace interface { namespace interface {
#endif // !defined(DOXYGEN_ONLY) #endif // !defined(DOXYGEN_ONLY)
class GattServer { class GattServer {
@ -415,7 +419,10 @@ public:
* function. * function.
*/ */
template <typename T> template <typename T>
void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)); void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count))
{
onDataSent({objPtr, memberPtr});
}
/** /**
* Access the callchain of data sent event handlers. * Access the callchain of data sent event handlers.
@ -448,7 +455,10 @@ public:
void onDataWritten( void onDataWritten(
T *objPtr, T *objPtr,
void (T::*memberPtr)(const GattWriteCallbackParams *context) void (T::*memberPtr)(const GattWriteCallbackParams *context)
); )
{
onDataWritten({objPtr, memberPtr});
}
/** /**
* Access the callchain of data written event handlers. * Access the callchain of data written event handlers.
@ -495,7 +505,10 @@ public:
ble_error_t onDataRead( ble_error_t onDataRead(
T *objPtr, T *objPtr,
void (T::*memberPtr)(const GattReadCallbackParams *context) void (T::*memberPtr)(const GattReadCallbackParams *context)
); )
{
onDataRead({objPtr, memberPtr});
}
/** /**
* Access the callchain of data read event handlers. * Access the callchain of data read event handlers.
@ -537,7 +550,10 @@ public:
* function. * function.
*/ */
template <typename T> template <typename T>
void onShutdown(T *objPtr, void (T::*memberPtr)(const GattServer *)); void onShutdown(T *objPtr, void (T::*memberPtr)(const GattServer *))
{
onShutdown({objPtr, memberPtr});
}
/** /**
* Access the callchain of shutdown event handlers. * Access the callchain of shutdown event handlers.
@ -578,72 +594,8 @@ public:
*/ */
void onConfirmationReceived(EventCallback_t callback); void onConfirmationReceived(EventCallback_t callback);
/* Entry points for the underlying stack to report events back to the user. */ private:
protected: impl::GattServer *impl;
/**
* Helper function that notifies all registered handlers of an occurrence
* of a data written event.
*
* @attention Vendor implementation must invoke this function after one of
* the GattServer attributes has been written.
*
* @param[in] params The data written parameters passed to the registered
* handlers.
*/
void handleDataWrittenEvent(const GattWriteCallbackParams *params);
/**
* Helper function that notifies all registered handlers of an occurrence
* of a data read event.
*
* @attention Vendor implementation must invoke this function after one of
* the GattServer attributes has been read.
*
* @param[in] params The data read parameters passed to the registered
* handlers.
*/
void handleDataReadEvent(const GattReadCallbackParams *params);
/**
* Helper function that notifies the registered handler of an occurrence
* of updates enabled, updates disabled or confirmation received events.
*
* @attention Vendor implementation must invoke this function when a client
* subscribes to characteristic updates, unsubscribes from characteristic
* updates or a notification confirmation has been received.
*
* @param[in] type The type of event that occurred.
* @param[in] attributeHandle The handle of the attribute concerned by the
* event.
*/
void handleEvent(
GattServerEvents::gattEvent_e type,
GattAttribute::Handle_t attributeHandle
);
/**
* Helper function that notifies all registered handlers of an occurrence
* of a data sent event.
*
* @attention Vendor implementation must invoke this function after the
* emission of a notification or an indication.
*
* @param[in] count Number of packets sent.
*/
void handleDataSentEvent(unsigned count);
/**
* Get preferred connection paramters.
*
*/
Gap::PreferredConnectionParams_t getPreferredConnectionParams();
/**
* Set preferred connection parameters.
*
* @param[in] params Preferred connection parameter values to set.
*/
void setPreferredConnectionParams(const Gap::PreferredConnectionParams_t& params);
}; };
/** /**
@ -655,13 +607,16 @@ protected:
#if !defined(DOXYGEN_ONLY) #if !defined(DOXYGEN_ONLY)
} // namespace interface } // namespace interface
#endif // !defined(DOXYGEN_ONLY) #endif // !defined(DOXYGEN_ONLY)
using ble::interface::GattServer;
} // ble } // ble
/* This includes the concrete class implementation, to provide a an alternative API implementation /* This includes the concrete class implementation, to provide a an alternative API implementation
* disable ble-api-implementation and place your header in a path with the same structure */ * disable ble-api-implementation and place your header in a path with the same structure */
#include "ble/internal/GattServerImpl.h" //#include "ble/internal/GattServerImpl.h"
/** @deprecated Use the namespaced ble::GattServer instead of the global GattServer. */ /** @deprecated Use the namespaced ble::GattServer instead of the global GattServer. */
using ble::GattServer; using ble::interface::GattServer;
#endif /* ifndef MBED_GATT_SERVER_H__ */ #endif /* ifndef MBED_GATT_SERVER_H__ */

View File

@ -27,6 +27,7 @@
#include "ble/common/ble/GattCallbackParamTypes.h" #include "ble/common/ble/GattCallbackParamTypes.h"
#include <stddef.h> #include <stddef.h>
#include <ble/GattServer.h>
#include "ble/common/ble/blecommon.h" #include "ble/common/ble/blecommon.h"
#include "ble/Gap.h" #include "ble/Gap.h"
#include "wsf_types.h" #include "wsf_types.h"
@ -42,29 +43,31 @@ namespace ble {
class PalAttClient; class PalAttClient;
class BLE; class BLE;
class GattServer : namespace impl {
public ble::interface::GattServer, class GattServer : public PalSigningMonitor {
public PalSigningMonitor
{
friend ble::BLE; friend ble::BLE;
friend ble::PalAttClient; friend ble::PalAttClient;
friend PalSigningMonitor; friend PalSigningMonitor;
friend BLEInstanceBase; friend BLEInstanceBase;
friend PalGenericAccessService; friend PalGenericAccessService;
// inherited typedefs have the wrong types so we have to redefine them using EventHandler = ble::GattServer::EventHandler;
public: using DataSentCallback_t = ble::GattServer::DataSentCallback_t ;
using DataSentCallbackChain_t = ble::GattServer::DataSentCallbackChain_t ;
using DataWrittenCallback_t = ble::GattServer::DataWrittenCallback_t ;
using DataWrittenCallbackChain_t = ble::GattServer::DataWrittenCallbackChain_t ;
using DataReadCallback_t = ble::GattServer::DataReadCallback_t;
using DataReadCallbackChain_t = ble::GattServer::DataReadCallbackChain_t;
using GattServerShutdownCallback_t = ble::GattServer::GattServerShutdownCallback_t;
using GattServerShutdownCallbackChain_t = ble::GattServer::GattServerShutdownCallbackChain_t;
using EventCallback_t = ble::GattServer::EventCallback_t;
typedef FunctionPointerWithContext<const GattServer *> // inherited typedefs have the wrong types so we have to redefine them
GattServerShutdownCallback_t;
typedef CallChainOfFunctionPointersWithContext<const GattServer*>
GattServerShutdownCallbackChain_t;
public: public:
void setEventHandler(EventHandler *handler); void setEventHandler(EventHandler *handler);
ble_error_t reset(void); ble_error_t reset(ble::GattServer* server);
ble_error_t addService(GattService &service); ble_error_t addService(GattService &service);
@ -107,49 +110,30 @@ public:
bool *enabledP bool *enabledP
); );
Gap::PreferredConnectionParams_t getPreferredConnectionParams(); ble::Gap::PreferredConnectionParams_t getPreferredConnectionParams();
void setPreferredConnectionParams(const Gap::PreferredConnectionParams_t& params); void setPreferredConnectionParams(const ble::Gap::PreferredConnectionParams_t &params);
bool isOnDataReadAvailable() const; bool isOnDataReadAvailable() const;
void onDataSent(const DataSentCallback_t &callback); void onDataSent(const DataSentCallback_t &callback);
template <typename T>
void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count));
DataSentCallbackChain_t &onDataSent(); DataSentCallbackChain_t &onDataSent();
void onDataWritten(const DataWrittenCallback_t &callback) { void onDataWritten(const DataWrittenCallback_t &callback)
{
dataWrittenCallChain.add(callback); dataWrittenCallChain.add(callback);
} }
template <typename T>
void onDataWritten(
T *objPtr,
void (T::*memberPtr)(const GattWriteCallbackParams *context)
) {
dataWrittenCallChain.add(objPtr, memberPtr);
};
DataWrittenCallbackChain_t &onDataWritten(); DataWrittenCallbackChain_t &onDataWritten();
ble_error_t onDataRead(const DataReadCallback_t &callback); ble_error_t onDataRead(const DataReadCallback_t &callback);
template <typename T>
ble_error_t onDataRead(
T *objPtr,
void (T::*memberPtr)(const GattReadCallbackParams *context)
);
DataReadCallbackChain_t &onDataRead(); DataReadCallbackChain_t &onDataRead();
void onShutdown(const GattServerShutdownCallback_t &callback); void onShutdown(const GattServerShutdownCallback_t &callback);
template <typename T> GattServerShutdownCallbackChain_t &onShutdown();
void onShutdown(T *objPtr, void (T::*memberPtr)(const GattServer *));
GattServerShutdownCallbackChain_t& onShutdown();
void onUpdatesEnabled(EventCallback_t callback); void onUpdatesEnabled(EventCallback_t callback);
@ -158,7 +142,7 @@ public:
void onConfirmationReceived(EventCallback_t callback); void onConfirmationReceived(EventCallback_t callback);
/* Entry points for the underlying stack to report events back to the user. */ /* Entry points for the underlying stack to report events back to the user. */
protected: protected:
void handleDataWrittenEvent(const GattWriteCallbackParams *params); void handleDataWrittenEvent(const GattWriteCallbackParams *params);
@ -174,8 +158,8 @@ protected:
/* ===================================================================== */ /* ===================================================================== */
/* private implementation follows */ /* private implementation follows */
#if 0 // Disabled until reworked and reintroduced to GattServer API #if 0 // Disabled until reworked and reintroduced to GattServer API
public: public:
/** /**
* @see ble::GattServer::setDeviceName * @see ble::GattServer::setDeviceName
*/ */
@ -196,13 +180,15 @@ public:
*/ */
GapAdvertisingData::Appearance getAppearance(); GapAdvertisingData::Appearance getAppearance();
#endif // Disabled until reworked and reintroduced to GattServer API #endif // Disabled until reworked and reintroduced to GattServer API
private: private:
GattServer(); GattServer();
GattServer(const GattServer &); GattServer(const GattServer &);
const GattServer& operator=(const GattServer &);
const GattServer &operator=(const GattServer &);
/** /**
* Return the singleton of the Cordio implementation of ble::GattServer. * Return the singleton of the Cordio implementation of ble::GattServer.
@ -219,14 +205,14 @@ private:
PalSigningMonitorEventHandler *signing_event_handler PalSigningMonitorEventHandler *signing_event_handler
); );
EventHandler* getEventHandler(); EventHandler *getEventHandler();
void add_default_services(); void add_default_services();
static uint16_t compute_attributes_count(GattService& service); static uint16_t compute_attributes_count(GattService &service);
void insert_service_attribute( void insert_service_attribute(
GattService& service, GattService &service,
attsAttr_t *&attribute_it attsAttr_t *&attribute_it
); );
@ -249,9 +235,9 @@ private:
ble_error_t insert_descriptor( ble_error_t insert_descriptor(
GattCharacteristic *characteristic, GattCharacteristic *characteristic,
GattAttribute* descriptor, GattAttribute *descriptor,
attsAttr_t *&attribute_it, attsAttr_t *&attribute_it,
bool& cccd_created bool &cccd_created
); );
ble_error_t insert_cccd( ble_error_t insert_cccd(
@ -260,20 +246,39 @@ private:
); );
static void cccd_cb(attsCccEvt_t *pEvt); static void cccd_cb(attsCccEvt_t *pEvt);
static void att_cb(const attEvt_t *pEvt); static void att_cb(const attEvt_t *pEvt);
static uint8_t atts_read_cb(dmConnId_t connId, uint16_t handle, uint8_t operation, uint16_t offset, attsAttr_t *pAttr); static uint8_t atts_read_cb(dmConnId_t connId, uint16_t handle, uint8_t operation, uint16_t offset, attsAttr_t *pAttr);
static uint8_t atts_write_cb(dmConnId_t connId, uint16_t handle, uint8_t operation, uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr);
static uint8_t atts_write_cb(
dmConnId_t connId,
uint16_t handle,
uint8_t operation,
uint16_t offset,
uint16_t len,
uint8_t *pValue,
attsAttr_t *pAttr
);
static uint8_t atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t handle); static uint8_t atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t handle);
void add_generic_access_service(); void add_generic_access_service();
void add_generic_attribute_service(); void add_generic_attribute_service();
void* alloc_block(size_t block_size);
GattCharacteristic* get_auth_char(uint16_t value_handle); void *alloc_block(size_t block_size);
bool get_cccd_index_by_cccd_handle(GattAttribute::Handle_t cccd_handle, uint8_t& idx) const;
bool get_cccd_index_by_value_handle(GattAttribute::Handle_t char_handle, uint8_t& idx) const; GattCharacteristic *get_auth_char(uint16_t value_handle);
bool get_cccd_index_by_cccd_handle(GattAttribute::Handle_t cccd_handle, uint8_t &idx) const;
bool get_cccd_index_by_value_handle(GattAttribute::Handle_t char_handle, uint8_t &idx) const;
bool is_update_authorized(connection_handle_t connection, GattAttribute::Handle_t value_handle); bool is_update_authorized(connection_handle_t connection, GattAttribute::Handle_t value_handle);
struct alloc_block_t { struct alloc_block_t {
alloc_block_t* next; alloc_block_t *next;
uint8_t data[1]; uint8_t data[1];
}; };
@ -357,7 +362,8 @@ private:
uint8_t ppcp_declaration_value[5]; uint8_t ppcp_declaration_value[5];
uint8_t ppcp[8]; uint8_t ppcp[8];
uint8_t*& device_name_value() { uint8_t *&device_name_value()
{
return attributes[2].pValue; return attributes[2].pValue;
} }
} generic_access_service; } generic_access_service;
@ -368,14 +374,15 @@ private:
uint8_t service_changed_declaration[5]; uint8_t service_changed_declaration[5];
} generic_attribute_service; } generic_attribute_service;
internal_service_t* registered_service; internal_service_t *registered_service;
alloc_block_t* allocated_blocks; alloc_block_t *allocated_blocks;
uint16_t currentHandle; uint16_t currentHandle;
bool default_services_added; bool default_services_added;
}; };
} // namespace impl
} // ble } // ble
#endif /* ifndef MBED_CORDIO_GATT_SERVER_H__ */ #endif /* ifndef MBED_CORDIO_GATT_SERVER_H__ */

View File

@ -18,12 +18,13 @@
#include "BLERoles.h" #include "BLERoles.h"
#include <algorithm> #include <algorithm>
#include "ble/GattServer.h" #include "ble/internal/GattServerImpl.h"
#include "ble/internal/BLEInstanceBase.h" #include "ble/internal/BLEInstanceBase.h"
#include "wsf_types.h" #include "wsf_types.h"
#include "att_api.h" #include "att_api.h"
namespace ble { namespace ble {
namespace impl {
namespace { namespace {
@ -93,7 +94,7 @@ ble_error_t GattServer::addService(GattService &service)
// Create cordio attribute list // Create cordio attribute list
att_service->attGroup.pAttr = att_service->attGroup.pAttr =
(attsAttr_t*) alloc_block(attributes_count * sizeof(attsAttr_t)); (attsAttr_t *) alloc_block(attributes_count * sizeof(attsAttr_t));
if (att_service->attGroup.pAttr == nullptr) { if (att_service->attGroup.pAttr == nullptr) {
delete att_service; delete att_service;
return BLE_ERROR_BUFFER_OVERFLOW; return BLE_ERROR_BUFFER_OVERFLOW;
@ -135,11 +136,11 @@ ble_error_t GattServer::addService(GattService &service)
// register services and update cccds // register services and update cccds
AttsAddGroup(&att_service->attGroup); AttsAddGroup(&att_service->attGroup);
AttsCccRegister(cccd_cnt, (attsCccSet_t*)cccds, cccd_cb); AttsCccRegister(cccd_cnt, (attsCccSet_t *) cccds, cccd_cb);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
uint16_t GattServer::compute_attributes_count(GattService& service) uint16_t GattServer::compute_attributes_count(GattService &service)
{ {
// start at 1, one attribute is required for the service itself // start at 1, one attribute is required for the service itself
uint16_t attributes_count = 1; uint16_t attributes_count = 1;
@ -167,12 +168,12 @@ uint16_t GattServer::compute_attributes_count(GattService& service)
} }
void GattServer::insert_service_attribute( void GattServer::insert_service_attribute(
GattService& service, GattService &service,
attsAttr_t *&attribute_it attsAttr_t *&attribute_it
) )
{ {
++currentHandle; ++currentHandle;
const UUID& service_uuid = service.getUUID(); const UUID &service_uuid = service.getUUID();
attribute_it->pUuid = attPrimSvcUuid; attribute_it->pUuid = attPrimSvcUuid;
if (service_uuid.shortOrLong() == UUID::UUID_TYPE_LONG) { if (service_uuid.shortOrLong() == UUID::UUID_TYPE_LONG) {
@ -180,7 +181,7 @@ void GattServer::insert_service_attribute(
} else { } else {
attribute_it->maxLen = sizeof(UUID::ShortUUIDBytes_t); attribute_it->maxLen = sizeof(UUID::ShortUUIDBytes_t);
} }
attribute_it->pValue = (uint8_t*) alloc_block(attribute_it->maxLen); attribute_it->pValue = (uint8_t *) alloc_block(attribute_it->maxLen);
memcpy(attribute_it->pValue, service_uuid.getBaseUUID(), attribute_it->maxLen); memcpy(attribute_it->pValue, service_uuid.getBaseUUID(), attribute_it->maxLen);
attribute_it->pLen = &attribute_it->maxLen; attribute_it->pLen = &attribute_it->maxLen;
attribute_it->settings = 0; attribute_it->settings = 0;
@ -259,7 +260,8 @@ bool GattServer::is_characteristic_valid(GattCharacteristic *characteristic)
#if BLE_FEATURE_SIGNING #if BLE_FEATURE_SIGNING
// check for invalid permissions // check for invalid permissions
if ((properties == SIGNED_WRITE_PROPERTY) && if ((properties == SIGNED_WRITE_PROPERTY) &&
(characteristic->getWriteSecurityRequirement() == att_security_requirement_t::NONE (
characteristic->getWriteSecurityRequirement() == att_security_requirement_t::NONE
#if BLE_FEATURE_SECURE_CONNECTIONS #if BLE_FEATURE_SECURE_CONNECTIONS
|| characteristic->getWriteSecurityRequirement() == att_security_requirement_t::SC_AUTHENTICATED || characteristic->getWriteSecurityRequirement() == att_security_requirement_t::SC_AUTHENTICATED
@ -278,7 +280,7 @@ void GattServer::insert_characteristic_declaration_attribute(
attsAttr_t *&attribute_it attsAttr_t *&attribute_it
) )
{ {
const UUID& value_uuid = characteristic->getValueAttribute().getUUID(); const UUID &value_uuid = characteristic->getValueAttribute().getUUID();
// move the current handle to point to the value handle // move the current handle to point to the value handle
currentHandle += 2; currentHandle += 2;
@ -288,7 +290,7 @@ void GattServer::insert_characteristic_declaration_attribute(
attribute_it->pUuid = attChUuid; attribute_it->pUuid = attChUuid;
attribute_it->maxLen = 1 + sizeof(currentHandle) + value_uuid.getLen(); attribute_it->maxLen = 1 + sizeof(currentHandle) + value_uuid.getLen();
attribute_it->pLen = &attribute_it->maxLen; attribute_it->pLen = &attribute_it->maxLen;
attribute_it->pValue = (uint8_t*) alloc_block(attribute_it->maxLen); attribute_it->pValue = (uint8_t *) alloc_block(attribute_it->maxLen);
attribute_it->settings = 0; attribute_it->settings = 0;
attribute_it->permissions = ATTS_PERMIT_READ; attribute_it->permissions = ATTS_PERMIT_READ;
@ -315,9 +317,9 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
// Create Value Attribute // Create Value Attribute
attribute_it->pUuid = value_attribute.getUUID().getBaseUUID(); attribute_it->pUuid = value_attribute.getUUID().getBaseUUID();
attribute_it->maxLen = characteristic->getValueAttribute().getMaxLength(); attribute_it->maxLen = characteristic->getValueAttribute().getMaxLength();
attribute_it->pLen = (uint16_t*) alloc_block(attribute_it->maxLen + sizeof(uint16_t)); attribute_it->pLen = (uint16_t *) alloc_block(attribute_it->maxLen + sizeof(uint16_t));
*attribute_it->pLen = value_attribute.getLength(); *attribute_it->pLen = value_attribute.getLength();
attribute_it->pValue = (uint8_t*) ((uint16_t*)attribute_it->pLen + 1); attribute_it->pValue = (uint8_t *) ((uint16_t *) attribute_it->pLen + 1);
memcpy(attribute_it->pValue, value_attribute.getValuePtr(), *attribute_it->pLen); memcpy(attribute_it->pValue, value_attribute.getValuePtr(), *attribute_it->pLen);
memset(attribute_it->pValue + *attribute_it->pLen, 0, attribute_it->maxLen - *attribute_it->pLen); memset(attribute_it->pValue + *attribute_it->pLen, 0, attribute_it->maxLen - *attribute_it->pLen);
@ -412,7 +414,7 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
characteristic->isReadAuthorizationEnabled() || characteristic->isReadAuthorizationEnabled() ||
characteristic->isWriteAuthorizationEnabled() characteristic->isWriteAuthorizationEnabled()
) { ) {
if ( _auth_char_count >= MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CHARACTERISTIC_AUTHORISATION_COUNT) { if (_auth_char_count >= MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CHARACTERISTIC_AUTHORISATION_COUNT) {
return BLE_ERROR_NO_MEM; return BLE_ERROR_NO_MEM;
} }
_auth_char[_auth_char_count] = characteristic; _auth_char[_auth_char_count] = characteristic;
@ -426,9 +428,9 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
ble_error_t GattServer::insert_descriptor( ble_error_t GattServer::insert_descriptor(
GattCharacteristic *characteristic, GattCharacteristic *characteristic,
GattAttribute* descriptor, GattAttribute *descriptor,
attsAttr_t *&attribute_it, attsAttr_t *&attribute_it,
bool& cccd_created bool &cccd_created
) )
{ {
uint8_t properties = characteristic->getProperties(); uint8_t properties = characteristic->getProperties();
@ -439,9 +441,9 @@ ble_error_t GattServer::insert_descriptor(
attribute_it->pUuid = descriptor->getUUID().getBaseUUID(); attribute_it->pUuid = descriptor->getUUID().getBaseUUID();
attribute_it->maxLen = descriptor->getMaxLength(); attribute_it->maxLen = descriptor->getMaxLength();
attribute_it->pLen = (uint16_t*) alloc_block(attribute_it->maxLen + sizeof(uint16_t)); attribute_it->pLen = (uint16_t *) alloc_block(attribute_it->maxLen + sizeof(uint16_t));
*attribute_it->pLen = descriptor->getLength(); *attribute_it->pLen = descriptor->getLength();
attribute_it->pValue = (uint8_t*) ((uint16_t*)attribute_it->pLen + 1); attribute_it->pValue = (uint8_t *) ((uint16_t *) attribute_it->pLen + 1);
memcpy(attribute_it->pValue, descriptor->getValuePtr(), *attribute_it->pLen); memcpy(attribute_it->pValue, descriptor->getValuePtr(), *attribute_it->pLen);
memset(attribute_it->pValue + *attribute_it->pLen, 0, attribute_it->maxLen - *attribute_it->pLen); memset(attribute_it->pValue + *attribute_it->pLen, 0, attribute_it->maxLen - *attribute_it->pLen);
@ -569,7 +571,7 @@ ble_error_t GattServer::insert_cccd(
currentHandle++; currentHandle++;
attribute_it->pUuid = CCCD_UUID.getBaseUUID(); attribute_it->pUuid = CCCD_UUID.getBaseUUID();
attribute_it->pValue = (uint8_t*) &cccd_values[cccd_cnt]; attribute_it->pValue = (uint8_t *) &cccd_values[cccd_cnt];
attribute_it->maxLen = CCCD_SIZE; attribute_it->maxLen = CCCD_SIZE;
attribute_it->pLen = &attribute_it->maxLen; attribute_it->pLen = &attribute_it->maxLen;
attribute_it->settings = ATTS_SET_CCC; attribute_it->settings = ATTS_SET_CCC;
@ -595,11 +597,11 @@ ble_error_t GattServer::insert_cccd(
ble_error_t GattServer::read( ble_error_t GattServer::read(
GattAttribute::Handle_t att_handle, GattAttribute::Handle_t att_handle,
uint8_t buffer[], uint8_t buffer[],
uint16_t * buffer_length uint16_t *buffer_length
) )
{ {
uint16_t att_length = 0; uint16_t att_length = 0;
uint8_t* att_value = nullptr; uint8_t *att_value = nullptr;
if (AttsGetAttr(att_handle, &att_length, &att_value) != ATT_SUCCESS) { if (AttsGetAttr(att_handle, &att_length, &att_value) != ATT_SUCCESS) {
return BLE_ERROR_PARAM_OUT_OF_RANGE; return BLE_ERROR_PARAM_OUT_OF_RANGE;
@ -670,7 +672,7 @@ ble_error_t GattServer::write(
} }
// write the value to the attribute handle // write the value to the attribute handle
if (AttsSetAttr(att_handle, len, (uint8_t*)buffer) != ATT_SUCCESS) { if (AttsSetAttr(att_handle, len, (uint8_t *) buffer) != ATT_SUCCESS) {
return BLE_ERROR_PARAM_OUT_OF_RANGE; return BLE_ERROR_PARAM_OUT_OF_RANGE;
} }
@ -690,11 +692,11 @@ ble_error_t GattServer::write(
if (is_update_authorized(conn_id, att_handle)) { if (is_update_authorized(conn_id, att_handle)) {
uint16_t cccd_config = AttsCccEnabled(conn_id, cccd_index); uint16_t cccd_config = AttsCccEnabled(conn_id, cccd_index);
if (cccd_config & ATT_CLIENT_CFG_NOTIFY) { if (cccd_config & ATT_CLIENT_CFG_NOTIFY) {
AttsHandleValueNtf(conn_id, att_handle, len, (uint8_t*)buffer); AttsHandleValueNtf(conn_id, att_handle, len, (uint8_t *) buffer);
updates_sent++; updates_sent++;
} }
if (cccd_config & ATT_CLIENT_CFG_INDICATE) { if (cccd_config & ATT_CLIENT_CFG_INDICATE) {
AttsHandleValueInd(conn_id, att_handle, len, (uint8_t*)buffer); AttsHandleValueInd(conn_id, att_handle, len, (uint8_t *) buffer);
updates_sent++; updates_sent++;
} }
} }
@ -727,7 +729,7 @@ ble_error_t GattServer::write(
} }
// write the value to the attribute handle // write the value to the attribute handle
if (AttsSetAttr(att_handle, len, (uint8_t*)buffer) != ATT_SUCCESS) { if (AttsSetAttr(att_handle, len, (uint8_t *) buffer) != ATT_SUCCESS) {
return BLE_ERROR_PARAM_OUT_OF_RANGE; return BLE_ERROR_PARAM_OUT_OF_RANGE;
} }
@ -743,11 +745,11 @@ ble_error_t GattServer::write(
if (is_update_authorized(connection, att_handle)) { if (is_update_authorized(connection, att_handle)) {
uint16_t cccEnabled = AttsCccEnabled(connection, cccd_index); uint16_t cccEnabled = AttsCccEnabled(connection, cccd_index);
if (cccEnabled & ATT_CLIENT_CFG_NOTIFY) { if (cccEnabled & ATT_CLIENT_CFG_NOTIFY) {
AttsHandleValueNtf(connection, att_handle, len, (uint8_t*)buffer); AttsHandleValueNtf(connection, att_handle, len, (uint8_t *) buffer);
updates_sent++; updates_sent++;
} }
if (cccEnabled & ATT_CLIENT_CFG_INDICATE) { if (cccEnabled & ATT_CLIENT_CFG_INDICATE) {
AttsHandleValueInd(connection, att_handle, len, (uint8_t*)buffer); AttsHandleValueInd(connection, att_handle, len, (uint8_t *) buffer);
updates_sent++; updates_sent++;
} }
} }
@ -810,9 +812,9 @@ bool GattServer::isOnDataReadAvailable() const
return true; return true;
} }
Gap::PreferredConnectionParams_t GattServer::getPreferredConnectionParams() ble::Gap::PreferredConnectionParams_t GattServer::getPreferredConnectionParams()
{ {
Gap::PreferredConnectionParams_t params = { 0 }; ble::Gap::PreferredConnectionParams_t params = {0};
memcpy(&params.minConnectionInterval, generic_access_service.ppcp, 2); memcpy(&params.minConnectionInterval, generic_access_service.ppcp, 2);
memcpy(&params.maxConnectionInterval, generic_access_service.ppcp + 2, 2); memcpy(&params.maxConnectionInterval, generic_access_service.ppcp + 2, 2);
memcpy(&params.slaveLatency, generic_access_service.ppcp + 4, 2); memcpy(&params.slaveLatency, generic_access_service.ppcp + 4, 2);
@ -820,7 +822,7 @@ Gap::PreferredConnectionParams_t GattServer::getPreferredConnectionParams()
return params; return params;
} }
void GattServer::setPreferredConnectionParams(const Gap::PreferredConnectionParams_t& params) void GattServer::setPreferredConnectionParams(const ble::Gap::PreferredConnectionParams_t &params)
{ {
memcpy(generic_access_service.ppcp, &params.minConnectionInterval, 2); memcpy(generic_access_service.ppcp, &params.minConnectionInterval, 2);
memcpy(generic_access_service.ppcp + 2, &params.maxConnectionInterval, 2); memcpy(generic_access_service.ppcp + 2, &params.maxConnectionInterval, 2);
@ -873,10 +875,10 @@ GapAdvertisingData::Appearance GattServer::getAppearance()
#endif // Disabled until reworked and reintroduced to GattServer API #endif // Disabled until reworked and reintroduced to GattServer API
ble_error_t GattServer::reset(void) ble_error_t GattServer::reset(ble::GattServer* server)
{ {
/* Notify that the instance is about to shutdown */ /* Notify that the instance is about to shutdown */
shutdownCallChain.call(this); shutdownCallChain.call(server);
shutdownCallChain.clear(); shutdownCallChain.clear();
serviceCount = 0; serviceCount = 0;
@ -890,14 +892,14 @@ ble_error_t GattServer::reset(void)
confirmationReceivedCallback = nullptr; confirmationReceivedCallback = nullptr;
while (registered_service) { while (registered_service) {
internal_service_t* s = registered_service; internal_service_t *s = registered_service;
registered_service = s->next; registered_service = s->next;
AttsRemoveGroup(s->attGroup.startHandle); AttsRemoveGroup(s->attGroup.startHandle);
delete s; delete s;
} }
while (allocated_blocks) { while (allocated_blocks) {
alloc_block_t* b = allocated_blocks; alloc_block_t *b = allocated_blocks;
allocated_blocks = b->next; allocated_blocks = b->next;
free(b); free(b);
} }
@ -911,7 +913,7 @@ ble_error_t GattServer::reset(void)
_auth_char_count = 0; _auth_char_count = 0;
AttsCccRegister(cccd_cnt, (attsCccSet_t*)cccds, cccd_cb); AttsCccRegister(cccd_cnt, (attsCccSet_t *) cccds, cccd_cb);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -946,7 +948,7 @@ uint8_t GattServer::atts_read_cb(
attsAttr_t *pAttr attsAttr_t *pAttr
) )
{ {
GattCharacteristic* auth_char = getInstance().get_auth_char(handle); GattCharacteristic *auth_char = getInstance().get_auth_char(handle);
if (auth_char && auth_char->isReadAuthorizationEnabled()) { if (auth_char && auth_char->isReadAuthorizationEnabled()) {
GattReadAuthCallbackParams read_auth_params = { GattReadAuthCallbackParams read_auth_params = {
connId, connId,
@ -1078,7 +1080,7 @@ uint8_t GattServer::atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t han
#if BLE_FEATURE_SECURITY #if BLE_FEATURE_SECURITY
// this CB is triggered when read or write of an attribute (either a value // this CB is triggered when read or write of an attribute (either a value
// handle or a descriptor) requires secure connection security. // handle or a descriptor) requires secure connection security.
SecurityManager& security_manager = BLEInstanceBase::deviceInstance().getSecurityManager(); ble::SecurityManager &security_manager = BLEInstanceBase::deviceInstance().getSecurityManager();
link_encryption_t encryption(link_encryption_t::NOT_ENCRYPTED); link_encryption_t encryption(link_encryption_t::NOT_ENCRYPTED);
ble_error_t err = security_manager.getLinkEncryption(connId, &encryption); ble_error_t err = security_manager.getLinkEncryption(connId, &encryption);
@ -1108,11 +1110,11 @@ void GattServer::add_generic_access_service()
// bind attributes to the service // bind attributes to the service
generic_access_service.service.pAttr = generic_access_service.attributes; generic_access_service.service.pAttr = generic_access_service.attributes;
attsAttr_t* current_attribute = generic_access_service.attributes; attsAttr_t *current_attribute = generic_access_service.attributes;
// service attribute // service attribute
current_attribute->pUuid = attPrimSvcUuid; current_attribute->pUuid = attPrimSvcUuid;
current_attribute->pValue = (uint8_t*) attGapSvcUuid; current_attribute->pValue = (uint8_t *) attGapSvcUuid;
current_attribute->maxLen = sizeof(attGapSvcUuid); current_attribute->maxLen = sizeof(attGapSvcUuid);
current_attribute->pLen = &current_attribute->maxLen; current_attribute->pLen = &current_attribute->maxLen;
current_attribute->settings = 0; current_attribute->settings = 0;
@ -1170,7 +1172,7 @@ void GattServer::add_generic_access_service()
current_attribute->pUuid = attApChUuid; current_attribute->pUuid = attApChUuid;
current_attribute->maxLen = sizeof(generic_access_service.appearance); current_attribute->maxLen = sizeof(generic_access_service.appearance);
current_attribute->pLen = &current_attribute->maxLen; current_attribute->pLen = &current_attribute->maxLen;
current_attribute->pValue = (uint8_t*) &generic_access_service.appearance; current_attribute->pValue = (uint8_t *) &generic_access_service.appearance;
current_attribute->settings = 0; current_attribute->settings = 0;
current_attribute->permissions = ATTS_PERMIT_READ; current_attribute->permissions = ATTS_PERMIT_READ;
@ -1224,11 +1226,11 @@ void GattServer::add_generic_attribute_service()
// bind attributes to the service // bind attributes to the service
generic_attribute_service.service.pAttr = generic_attribute_service.attributes; generic_attribute_service.service.pAttr = generic_attribute_service.attributes;
attsAttr_t* current_attribute = generic_attribute_service.attributes; attsAttr_t *current_attribute = generic_attribute_service.attributes;
// service attribute // service attribute
current_attribute->pUuid = attPrimSvcUuid; current_attribute->pUuid = attPrimSvcUuid;
current_attribute->pValue = (uint8_t*) attGattSvcUuid; current_attribute->pValue = (uint8_t *) attGattSvcUuid;
current_attribute->maxLen = sizeof(attGattSvcUuid); current_attribute->maxLen = sizeof(attGattSvcUuid);
current_attribute->pLen = &current_attribute->maxLen; current_attribute->pLen = &current_attribute->maxLen;
current_attribute->settings = 0; current_attribute->settings = 0;
@ -1264,7 +1266,7 @@ void GattServer::add_generic_attribute_service()
// CCCD // CCCD
++current_attribute; ++current_attribute;
current_attribute->pUuid = attCliChCfgUuid; current_attribute->pUuid = attCliChCfgUuid;
current_attribute->pValue = (uint8_t*)&cccd_values[cccd_cnt]; current_attribute->pValue = (uint8_t *) &cccd_values[cccd_cnt];
current_attribute->maxLen = 2; current_attribute->maxLen = 2;
current_attribute->pLen = &current_attribute->maxLen; current_attribute->pLen = &current_attribute->maxLen;
current_attribute->settings = ATTS_SET_CCC; current_attribute->settings = ATTS_SET_CCC;
@ -1278,12 +1280,12 @@ void GattServer::add_generic_attribute_service()
generic_attribute_service.service.endHandle = currentHandle; generic_attribute_service.service.endHandle = currentHandle;
AttsAddGroup(&generic_attribute_service.service); AttsAddGroup(&generic_attribute_service.service);
AttsCccRegister(cccd_cnt, (attsCccSet_t*)cccds, cccd_cb); AttsCccRegister(cccd_cnt, (attsCccSet_t *) cccds, cccd_cb);
} }
void* GattServer::alloc_block(size_t block_size) void *GattServer::alloc_block(size_t block_size)
{ {
alloc_block_t* block = (alloc_block_t*) malloc(sizeof(alloc_block_t) + block_size); alloc_block_t *block = (alloc_block_t *) malloc(sizeof(alloc_block_t) + block_size);
if (block == nullptr) { if (block == nullptr) {
return nullptr; return nullptr;
} }
@ -1299,7 +1301,7 @@ void* GattServer::alloc_block(size_t block_size)
return block->data; return block->data;
} }
GattCharacteristic* GattServer::get_auth_char(uint16_t value_handle) GattCharacteristic *GattServer::get_auth_char(uint16_t value_handle)
{ {
for (size_t i = 0; i < _auth_char_count; ++i) { for (size_t i = 0; i < _auth_char_count; ++i) {
if (_auth_char[i]->getValueHandle() == value_handle) { if (_auth_char[i]->getValueHandle() == value_handle) {
@ -1309,7 +1311,7 @@ GattCharacteristic* GattServer::get_auth_char(uint16_t value_handle)
return nullptr; return nullptr;
} }
bool GattServer::get_cccd_index_by_cccd_handle(GattAttribute::Handle_t cccd_handle, uint8_t& idx) const bool GattServer::get_cccd_index_by_cccd_handle(GattAttribute::Handle_t cccd_handle, uint8_t &idx) const
{ {
for (idx = 0; idx < cccd_cnt; idx++) { for (idx = 0; idx < cccd_cnt; idx++) {
if (cccd_handle == cccds[idx].handle) { if (cccd_handle == cccds[idx].handle) {
@ -1319,7 +1321,7 @@ bool GattServer::get_cccd_index_by_cccd_handle(GattAttribute::Handle_t cccd_hand
return false; return false;
} }
bool GattServer::get_cccd_index_by_value_handle(GattAttribute::Handle_t char_handle, uint8_t& idx) const bool GattServer::get_cccd_index_by_value_handle(GattAttribute::Handle_t char_handle, uint8_t &idx) const
{ {
for (idx = 0; idx < cccd_cnt; ++idx) { for (idx = 0; idx < cccd_cnt; ++idx) {
if (char_handle == cccd_handles[idx]) { if (char_handle == cccd_handles[idx]) {
@ -1334,7 +1336,7 @@ bool GattServer::is_update_authorized(
GattAttribute::Handle_t value_handle GattAttribute::Handle_t value_handle
) )
{ {
GattCharacteristic* auth_char = get_auth_char(value_handle); GattCharacteristic *auth_char = get_auth_char(value_handle);
if (!auth_char) { if (!auth_char) {
return true; return true;
} }
@ -1347,7 +1349,7 @@ bool GattServer::is_update_authorized(
} }
#if BLE_FEATURE_SECURITY #if BLE_FEATURE_SECURITY
SecurityManager& security_manager = BLEInstanceBase::deviceInstance().getSecurityManager(); ble::SecurityManager &security_manager = BLEInstanceBase::deviceInstance().getSecurityManager();
link_encryption_t encryption(link_encryption_t::NOT_ENCRYPTED); link_encryption_t encryption(link_encryption_t::NOT_ENCRYPTED);
ble_error_t err = security_manager.getLinkEncryption(connection, &encryption); ble_error_t err = security_manager.getLinkEncryption(connection, &encryption);
if (err) { if (err) {
@ -1419,12 +1421,6 @@ void GattServer::onDataSent(const DataSentCallback_t &callback)
dataSentCallChain.add(callback); dataSentCallChain.add(callback);
} }
template <typename T>
void GattServer::onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count))
{
dataSentCallChain.add(objPtr, memberPtr);
}
ble::GattServer::DataSentCallbackChain_t &GattServer::onDataSent() ble::GattServer::DataSentCallbackChain_t &GattServer::onDataSent()
{ {
return dataSentCallChain; return dataSentCallChain;
@ -1445,20 +1441,6 @@ ble_error_t GattServer::onDataRead(const DataReadCallback_t &callback)
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
template <typename T>
ble_error_t GattServer::onDataRead(
T *objPtr,
void (T::*memberPtr)(const GattReadCallbackParams *context)
)
{
if (!isOnDataReadAvailable()) {
return BLE_ERROR_NOT_IMPLEMENTED;
}
dataReadCallChain.add(objPtr, memberPtr);
return BLE_ERROR_NONE;
}
ble::GattServer::DataReadCallbackChain_t &GattServer::onDataRead() ble::GattServer::DataReadCallbackChain_t &GattServer::onDataRead()
{ {
return dataReadCallChain; return dataReadCallChain;
@ -1469,13 +1451,7 @@ void GattServer::onShutdown(const GattServerShutdownCallback_t &callback)
shutdownCallChain.add(callback); shutdownCallChain.add(callback);
} }
template <typename T> GattServer::GattServerShutdownCallbackChain_t &GattServer::onShutdown()
void GattServer::onShutdown(T *objPtr, void (T::*memberPtr)(const ble::GattServer *))
{
shutdownCallChain.add(objPtr, memberPtr);
}
ble::GattServer::GattServerShutdownCallbackChain_t& GattServer::onShutdown()
{ {
return shutdownCallChain; return shutdownCallChain;
} }
@ -1500,7 +1476,7 @@ void GattServer::setEventHandler(EventHandler *handler)
eventHandler = handler; eventHandler = handler;
} }
GattServer::EventHandler* GattServer::getEventHandler() GattServer::EventHandler *GattServer::getEventHandler()
{ {
return eventHandler; return eventHandler;
} }
@ -1552,4 +1528,5 @@ void GattServer::handleDataSentEvent(unsigned count)
dataSentCallChain.call(count); dataSentCallChain.call(count);
} }
} // namespace impl
} // namespace ble } // namespace ble

View File

@ -0,0 +1,157 @@
/* mbed Microcontroller Library
* Copyright (c) 2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ble/GattServer.h"
#include "ble/internal/GattServerImpl.h"
namespace ble {
namespace interface {
void GattServer::setEventHandler(EventHandler *handler)
{
return impl->setEventHandler(handler);
}
ble_error_t GattServer::reset()
{
return impl->reset(this);
}
ble_error_t GattServer::addService(GattService &service)
{
return impl->addService(service);
}
ble_error_t GattServer::read(
GattAttribute::Handle_t attributeHandle,
uint8_t buffer[],
uint16_t *lengthP
)
{
return impl->read(attributeHandle, buffer, lengthP);
}
ble_error_t GattServer::read(
ble::connection_handle_t connectionHandle,
GattAttribute::Handle_t attributeHandle,
uint8_t *buffer,
uint16_t *lengthP
)
{
return impl->read(connectionHandle, attributeHandle, buffer, lengthP);
}
ble_error_t GattServer::write(
GattAttribute::Handle_t attributeHandle,
const uint8_t *value,
uint16_t size,
bool localOnly
)
{
return impl->write(attributeHandle, value, size, localOnly);
}
ble_error_t GattServer::write(
ble::connection_handle_t connectionHandle,
GattAttribute::Handle_t attributeHandle,
const uint8_t *value,
uint16_t size,
bool localOnly
)
{
return impl->write(connectionHandle, attributeHandle, value, size, localOnly);
}
ble_error_t GattServer::areUpdatesEnabled(
const GattCharacteristic &characteristic,
bool *enabledP
)
{
return impl->areUpdatesEnabled(characteristic, enabledP);
}
ble_error_t GattServer::areUpdatesEnabled(
ble::connection_handle_t connectionHandle,
const GattCharacteristic &characteristic,
bool *enabledP
)
{
return impl->areUpdatesEnabled(connectionHandle, characteristic, enabledP);
}
bool GattServer::isOnDataReadAvailable() const
{
return impl->isOnDataReadAvailable();
}
void GattServer::onDataSent(const DataSentCallback_t &callback)
{
return impl->onDataSent(callback);
}
GattServer::DataSentCallbackChain_t &GattServer::onDataSent()
{
return impl->onDataSent();
}
void GattServer::onDataWritten(const DataWrittenCallback_t &callback)
{
return impl->onDataWritten(callback);
}
GattServer::DataWrittenCallbackChain_t &GattServer::onDataWritten()
{
return impl->onDataWritten();
}
ble_error_t GattServer::onDataRead(const DataReadCallback_t &callback)
{
return impl->onDataRead(callback);
}
GattServer::DataReadCallbackChain_t &GattServer::onDataRead()
{
return impl->onDataRead();
}
void GattServer::onShutdown(const GattServerShutdownCallback_t &callback)
{
return impl->onShutdown(callback);
}
GattServer::GattServerShutdownCallbackChain_t& GattServer::onShutdown()
{
return impl->onShutdown();
}
void GattServer::onUpdatesEnabled(EventCallback_t callback)
{
return impl->onUpdatesEnabled(callback);
}
void GattServer::onUpdatesDisabled(EventCallback_t callback)
{
return impl->onUpdatesDisabled(callback);
}
void GattServer::onConfirmationReceived(EventCallback_t callback)
{
return impl->onConfirmationReceived(callback);
}
} // namespace interface
} // ble