Add tracing to BLE Gatt Server (#14107)

* Add traces to GattServerImpl.cpp

* Update BLGS traces

* Add context to BLGS traces

* Set value of TRACE_WRITE_VALUES to 0

* Add param logs to BLGS traces

* Apply changes from code review

* Add trace helper for UUIDs

* C++ string library is not needed

* Update to_string function for UUIDs

The previous implementation had a memory leak and did not format 128-bit UUIDs

* Possibly faster ternary

* Add more context to adding/inserting of services/characteristic

* Add trace to events and event path

* Refactor to_string helper for UUIDs
pull/14198/head
Abbas Bracken Ziad 2021-01-27 11:10:14 +00:00 committed by Paul Szczepanek
parent f4febdcb9d
commit db9428f18f
2 changed files with 275 additions and 14 deletions

View File

@ -18,6 +18,7 @@
#ifndef BLE_CLIAPP_BLE_TRACE_HELPERS_H
#define BLE_CLIAPP_BLE_TRACE_HELPERS_H
#include "ble/BLE.h"
#include "ble/SecurityManager.h"
#include "mbed-trace/mbed_trace.h"
#include "pal/GapTypes.h"
@ -26,7 +27,6 @@
#include "common/UUID.h"
namespace ble {
#if MBED_CONF_MBED_TRACE_ENABLE
void trace_le_supported_features(uint64_t feat);
@ -45,9 +45,47 @@ static inline const char* tr_as_array(T item)
return (mbed_trace_array)((const uint8_t*)&item, sizeof(item));
}
static inline const char* to_string(UUID uuid)
static inline char* to_string(const UUID& uuid)
{
return (mbed_trace_array)(uuid.getBaseUUID(), uuid.getLen());
const uint8_t* Buffer = uuid.getBaseUUID();
const uint8_t Length = uuid.getLen();
const size_t Row_Count = 4;
const char *Hex = "0123456789ABCDEF";
static char string_buffer[Row_Count][UUID::LENGTH_OF_LONG_UUID + /* Number of hyphen delimiters =*/ 4];
static uint8_t idx = 0;
if (idx == Row_Count) {
idx= 0;
} else {
idx++;
}
char* p1 = (char *)Buffer + Length - 1;
char* p2 = string_buffer[idx];
if (Length == UUID::LENGTH_OF_LONG_UUID) {
const uint8_t format[] = {4, 2, 2, 2, 6};
for ( uint8_t i: format) {
size_t j = 0;
for (; j < i; ++j) {
*p2++ = Hex[(*p1 >> 4) & 0xF];
*p2++ = Hex[(*p1--) & 0xF];
}
*p2++ = '-';
}
*--p2 = 0;
} else {
size_t i = 0;
for (; i < Length; ++i) {
*p2++ = Hex[(*p1 >> 4) & 0xF];
*p2++ = Hex[(*p1--) & 0xF];
}
*p2 = 0;
}
return string_buffer[idx];
}
static inline constexpr const char* to_string(bool v)
@ -173,7 +211,7 @@ static inline const char* to_string(Keypress_t keypress)
}
}
static inline const char *to_string(ble::pairing_failure_t reason)
static inline const char* to_string(ble::pairing_failure_t reason)
{
switch (reason.value()) {
case ble::pairing_failure_t::PASSKEY_ENTRY_FAILED:
@ -209,7 +247,7 @@ static inline const char *to_string(ble::pairing_failure_t reason)
}
}
static inline const char *to_string(target_peer_address_type_t type)
static inline const char* to_string(target_peer_address_type_t type)
{
if (type == target_peer_address_type_t::PUBLIC) {
return "PUBLIC";
@ -218,7 +256,7 @@ static inline const char *to_string(target_peer_address_type_t type)
}
}
static inline const char *to_string(privacy_mode_t mode)
static inline const char* to_string(privacy_mode_t mode)
{
if (mode == privacy_mode_t::NETWORK) {
return "NETWORK";
@ -679,8 +717,7 @@ static inline const char* to_string(ble::direct_address_type_t direct_address_ty
}
}
static inline const char* to_string(ble::advertising_data_status_t data_status)
{
static inline const char* to_string(ble::advertising_data_status_t data_status) {
switch (data_status.value()) {
case ble::advertising_data_status_t::COMPLETE:
return "COMPLETE";
@ -692,6 +729,73 @@ static inline const char* to_string(ble::advertising_data_status_t data_status)
return "unknown";
}
}
static inline const char* to_string(ble::att_security_requirement_t security_requirement)
{
switch (security_requirement.value()) {
case ble::att_security_requirement_t::NONE:
return "NONE";
case ble::att_security_requirement_t::UNAUTHENTICATED:
return "UNAUTHENTICATED";
case ble::att_security_requirement_t::AUTHENTICATED:
return "AUTHENTICATED";
case ble::att_security_requirement_t::SC_AUTHENTICATED:
return "SC_AUTHENTICATED";
default:
return "unknown";
}
}
static inline const char* to_string(GattAuthCallbackReply_t authorization_reply)
{
switch (authorization_reply) {
case AUTH_CALLBACK_REPLY_SUCCESS:
return "SUCCESS";
case AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE:
return "INVALID_HANDLE";
case AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED:
return "READ_NOT_PERMITTED";
case AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED:
return "WRITE_NOT_PERMITTED";
case AUTH_CALLBACK_REPLY_ATTERR_INVALID_PDU:
return "INVALID_PDU";
case AUTH_CALLBACK_REPLY_ATTERR_INSUFFICIENT_AUTHENTICATION:
return "INSUFFICIENT_AUTHENTICATION";
case AUTH_CALLBACK_REPLY_ATTERR_REQUEST_NOT_SUPPORTED:
return "REQUEST_NOT_SUPPORTED";
case AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET:
return "INVALID_OFFSET";
case AUTH_CALLBACK_REPLY_ATTERR_INSUFFICIENT_AUTHORIZATION:
return "INSUFFICIENT_AUTHORIZATION";
case AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL:
return "PREPARE_QUEUE_FULL";
case AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND:
return "ATTRIBUTE_NOT_FOUND";
case AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG:
return "ATTRIBUTE_NOT_LONG";
case AUTH_CALLBACK_REPLY_ATTERR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
return "INSUFFICIENT_ENCRYPTION_KEY_SIZE";
case AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATTRIBUTE_VALUE_LENGTH:
return "INVALID_ATTRIBUTE_VALUE_LENGTH";
case AUTH_CALLBACK_REPLY_ATTERR_UNLIKELY_ERROR:
return "UNLIKELY_ERROR";
case AUTH_CALLBACK_REPLY_ATTERR_INSUFFICIENT_ENCRYPTION:
return "INSUFFICIENT_ENCRYPTION";
case AUTH_CALLBACK_REPLY_ATTERR_UNSUPPORTED_GROUP_TYPE:
return "UNSUPPORTED_GROUP_TYPE";
case AUTH_CALLBACK_REPLY_ATTERR_INSUFFICIENT_RESOURCES:
return "INSUFFICIENT_RESOURCES";
case AUTH_CALLBACK_REPLY_ATTERR_WRITE_REQUEST_REJECTED:
return "WRITE_REQUEST_REJECTED";
case AUTH_CALLBACK_REPLY_ATTERR_CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR_IMPROPERLY_CONFIGURED:
return "CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR_IMPROPERLY_CONFIGURED";
case AUTH_CALLBACK_REPLY_ATTERR_PROCEDURE_ALREADY_IN_PROGRESS:
return "PROCEDURE_ALREADY_IN_PROGRESS";
case AUTH_CALLBACK_REPLY_ATTERR_OUT_OF_RANGE:
return "OUT_OF_RANGE";
default:
return "unknown";
}
}
} // namespace ble

View File

@ -25,6 +25,11 @@
#include <new>
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLGS"
namespace ble {
namespace impl {
@ -84,6 +89,10 @@ void GattServer::add_default_services()
ble_error_t GattServer::addService(GattService &service)
{
tr_info("Add service with UUID=%s and %d characteristic(s) to the Gatt Server",
to_string(service.getUUID()),
service.getCharacteristicCount());
add_default_services();
// create and fill the service structure
internal_service_t *att_service = new internal_service_t;
@ -98,6 +107,7 @@ ble_error_t GattServer::addService(GattService &service)
att_service->attGroup.pAttr =
(attsAttr_t *) alloc_block(attributes_count * sizeof(attsAttr_t));
if (att_service->attGroup.pAttr == nullptr) {
tr_error("Failed to create Cordio attribute list");
delete att_service;
return BLE_ERROR_BUFFER_OVERFLOW;
}
@ -121,6 +131,7 @@ ble_error_t GattServer::addService(GattService &service)
// - att_service->attGroup.pAttr
// - blocks allocated for characteristics value
// NOTE: those are rightfully released when reset() is called.
tr_error("Failed to insert characteristic");
delete att_service;
return err;
}
@ -197,8 +208,43 @@ ble_error_t GattServer::insert_characteristic(
attsAttr_t *&attribute_it
)
{
tr_info("Insert characteristic %s - "
"valuePtr=%p, "
"lenMax=%d, "
"len=%d, "
"hasVariableLength=%s, "
"read_security=%s, "
"write_security=%s, "
"properties=[ %s%s%s%s%s%s%s%s], "
"descriptor_count=%d",
to_string(characteristic->getValueAttribute().getUUID()),
characteristic->getValueAttribute().getValuePtr(),
characteristic->getValueAttribute().getMaxLength(),
characteristic->getValueAttribute().getLength(),
to_string(characteristic->getValueAttribute().hasVariableLength()),
to_string(characteristic->getValueAttribute().getReadSecurityRequirement()),
to_string(characteristic->getValueAttribute().getWriteSecurityRequirement()),
characteristic->getProperties() & GattCharacteristic::Properties_t::BLE_GATT_CHAR_PROPERTIES_BROADCAST
? "BROADCAST " : "",
characteristic->getProperties() & GattCharacteristic::Properties_t::BLE_GATT_CHAR_PROPERTIES_READ
? "READ " : "",
characteristic->getProperties() & GattCharacteristic::Properties_t::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE
? "WRITE_WITHOUT_RESPONSE " : "",
characteristic->getProperties() & GattCharacteristic::Properties_t::BLE_GATT_CHAR_PROPERTIES_WRITE
? "WRITE " : "",
characteristic->getProperties() & GattCharacteristic::Properties_t::BLE_GATT_CHAR_PROPERTIES_NOTIFY
? "NOTIFY " : "",
characteristic->getProperties() & GattCharacteristic::Properties_t::BLE_GATT_CHAR_PROPERTIES_INDICATE
? "INDICATE " : "",
characteristic->getProperties() & GattCharacteristic::Properties_t::BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES
? "AUTHENTICATED_SIGNED_WRITES " : "",
characteristic->getProperties() & GattCharacteristic::Properties_t::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES
? "EXTENDED_PROPERTIES " : "",
characteristic->getDescriptorCount());
bool valid = is_characteristic_valid(characteristic);
if (!valid) {
tr_error("Characteristic is not valid");
return BLE_ERROR_INVALID_PARAM;
}
@ -208,6 +254,7 @@ ble_error_t GattServer::insert_characteristic(
insert_characteristic_declaration_attribute(characteristic, attribute_it);
ble_error_t err = insert_characteristic_value_attribute(characteristic, attribute_it);
if (err) {
tr_error("Failed to insert value attribute");
return err;
}
@ -223,6 +270,7 @@ ble_error_t GattServer::insert_characteristic(
);
if (err) {
return err;
tr_error("Failed to insert descriptor");
}
}
@ -230,10 +278,14 @@ ble_error_t GattServer::insert_characteristic(
if ((properties & UPDATE_PROPERTIES) && (cccd_created == false)) {
err = insert_cccd(characteristic, attribute_it);
if (err) {
tr_error("Failed to insert implicit CCCD");
return err;
}
}
tr_info("Successfully inserted characteristic %s: handle=%d",
to_string(characteristic->getValueAttribute().getUUID()),
characteristic->getValueHandle());
return BLE_ERROR_NONE;
}
@ -282,6 +334,9 @@ void GattServer::insert_characteristic_declaration_attribute(
attsAttr_t *&attribute_it
)
{
tr_info("Insert declaration attribute in characteristic %s",
to_string(characteristic->getValueAttribute().getUUID()));
const UUID &value_uuid = characteristic->getValueAttribute().getUUID();
// move the current handle to point to the value handle
@ -311,6 +366,9 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
attsAttr_t *&attribute_it
)
{
tr_info("Insert value attribute in characteristic %s",
to_string(characteristic->getValueAttribute().getUUID()));
GattAttribute &value_attribute = characteristic->getValueAttribute();
uint8_t properties = characteristic->getProperties();
@ -417,12 +475,15 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
characteristic->isWriteAuthorizationEnabled()
) {
if (_auth_callbacks_count >= MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CHARACTERISTIC_AUTHORISATION_COUNT) {
tr_error("Authorisation characteristic count cannot be greater than %d",
MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CHARACTERISTIC_AUTHORISATION_COUNT);
return BLE_ERROR_NO_MEM;
}
char_auth_callback *new_cb = (char_auth_callback *) alloc_block(sizeof(char_auth_callback));
if (!new_cb) {
tr_error("Failed to allocate space on the heap for new R/W authorisation callbacks");
return BLE_ERROR_NO_MEM;
}
@ -458,6 +519,9 @@ ble_error_t GattServer::insert_descriptor(
bool &cccd_created
)
{
tr_info("Insert descriptor in characteristic %s",
to_string(characteristic->getValueAttribute().getUUID()));
uint8_t properties = characteristic->getProperties();
currentHandle++;
@ -481,16 +545,21 @@ ble_error_t GattServer::insert_descriptor(
// handle the special case of a CCCD
if (descriptor->getUUID() == UUID(BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG)) {
if (cccd_cnt >= MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CCCD_COUNT) {
tr_error("CCCD count cannot be greater than/equal to %d",
MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CCCD_COUNT);
return BLE_ERROR_NO_MEM;
}
if (descriptor->isReadAllowed() == false ||
descriptor->getReadSecurityRequirement() != att_security_requirement_t::NONE
) {
tr_error("The attribute must be readable and secure");
return BLE_ERROR_INVALID_PARAM;
}
cccd_created = true;
tr_info("cccd_created=%s", to_string(cccd_created));
attribute_it->settings |= ATTS_SET_CCC;
cccds[cccd_cnt].handle = currentHandle;
@ -587,7 +656,11 @@ ble_error_t GattServer::insert_cccd(
attsAttr_t *&attribute_it
)
{
tr_info("Insert CCCD in characteristic %s",
to_string(characteristic->getValueAttribute().getUUID()));
if (cccd_cnt >= MBED_CONF_BLE_API_IMPLEMENTATION_MAX_CCCD_COUNT) {
tr_error("failed insert cccd: table full");
return BLE_ERROR_NO_MEM;
}
@ -626,6 +699,7 @@ ble_error_t GattServer::insert_cccd(
false);
if(implicit_cccd == nullptr) {
tr_error("failed to create implicit CCCD");
currentHandle--;
return BLE_ERROR_NO_MEM;
}
@ -651,6 +725,7 @@ ble_error_t GattServer::read(
uint8_t *att_value = nullptr;
if (AttsGetAttr(att_handle, &att_length, &att_value) != ATT_SUCCESS) {
tr_error("Failed to read attribute %d: attribute not found", att_handle);
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
@ -660,6 +735,9 @@ ble_error_t GattServer::read(
*buffer_length = att_length;
tr_debug("Read attribute %d - value=%s",
att_handle,
mbed_trace_array(buffer, *buffer_length));
return BLE_ERROR_NONE;
}
@ -674,6 +752,9 @@ ble_error_t GattServer::read(
uint8_t cccd_index;
if (get_cccd_index_by_cccd_handle(att_handle, cccd_index)) {
if (connection == DM_CONN_ID_NONE) {
tr_error("Failed to read attribute %d on connection %d: unknown connection ID",
att_handle,
connection);
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
uint16_t cccd_value = AttsCccGet(connection, cccd_index);
@ -684,6 +765,11 @@ ble_error_t GattServer::read(
}
*buffer_length = cccd_length;
tr_debug("Connection %d: read attribute %d - value=%s",
connection,
att_handle,
mbed_trace_array(buffer, *buffer_length));
return BLE_ERROR_NONE;
}
@ -698,11 +784,19 @@ ble_error_t GattServer::write(
bool local_only
)
{
tr_info("Write attribute %d - "
"value=%s, "
"local_only=%s",
att_handle,
mbed_trace_array(buffer, len),
to_string(local_only));
// Check to see if this is a CCCD, if it is the case update the value for all
// connections
uint8_t cccd_index;
if (get_cccd_index_by_cccd_handle(att_handle, cccd_index)) {
if (len != sizeof(uint16_t)) {
tr_error("CCCDs must be 16 bits");
return BLE_ERROR_INVALID_PARAM;
}
@ -720,6 +814,7 @@ ble_error_t GattServer::write(
// write the value to the attribute handle
if (AttsSetAttr(att_handle, len, (uint8_t *) buffer) != ATT_SUCCESS) {
tr_error("Invalid attribute length");
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
@ -762,10 +857,19 @@ ble_error_t GattServer::write(
bool local_only
)
{
tr_info("Connection %d: write attribute %d - "
"value=%s, "
"local_only=%s",
connection,
att_handle,
mbed_trace_array(buffer, len),
to_string(local_only));
// Check to see if this is a CCCD
uint8_t cccd_index;
if (get_cccd_index_by_cccd_handle(att_handle, cccd_index)) {
if ((connection == DM_CONN_ID_NONE) || (len != 2)) { // CCCDs are always 16 bits
tr_error("Unknown connection ID/length not 16 bits");
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
@ -777,6 +881,7 @@ ble_error_t GattServer::write(
// write the value to the attribute handle
if (AttsSetAttr(att_handle, len, (uint8_t *) buffer) != ATT_SUCCESS) {
tr_error("Invalid attribute length");
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
@ -817,16 +922,21 @@ ble_error_t GattServer::areUpdatesEnabled(
uint16_t cccd_value = AttsCccGet(conn_id, idx);
if (cccd_value & (ATT_CLIENT_CFG_NOTIFY | ATT_CLIENT_CFG_INDICATE)) {
*enabled = true;
tr_debug("Updates are enabled in characteristic %s",
to_string(characteristic.getValueAttribute().getUUID()));
return BLE_ERROR_NONE;
}
}
}
*enabled = false;
tr_debug("Updates are not enabled in characteristic %s",
to_string(characteristic.getValueAttribute().getUUID()));
return BLE_ERROR_NONE;
}
}
tr_error("Failed to determine if updates are enabled: characteristic %s not in CCCD table",
to_string(characteristic.getValueAttribute().getUUID()));
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
@ -837,6 +947,7 @@ ble_error_t GattServer::areUpdatesEnabled(
)
{
if (connectionHandle == DM_CONN_ID_NONE) {
tr_error("Connection %d: failed to determine if updates are enabled - unknown connection ID", connectionHandle);
return BLE_ERROR_INVALID_PARAM;
}
@ -848,9 +959,17 @@ ble_error_t GattServer::areUpdatesEnabled(
} else {
*enabled = false;
}
tr_debug("Connection %d: updates are%s enabled in characteristic %s",
connectionHandle,
*enabled ? "" : " not",
to_string(characteristic.getValueAttribute().getUUID()));
return BLE_ERROR_NONE;
}
}
tr_error("Connection %d: failed to determine if updates are enabled - characteristic %s not in CCCD table",
connectionHandle,
to_string(characteristic.getValueAttribute().getUUID()));
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
@ -925,7 +1044,7 @@ GapAdvertisingData::Appearance GattServer::getAppearance()
ble_error_t GattServer::reset(ble::GattServer* server)
{
/* Notify that the instance is about to shutdown */
if(eventHandler) {
if (eventHandler) {
eventHandler->onShutdown(*server);
}
@ -1016,6 +1135,11 @@ uint8_t GattServer::atts_read_cb(
auth_cb->read_cb.call(&read_auth_params);
if (read_auth_params.authorizationReply != AUTH_CALLBACK_REPLY_SUCCESS) {
tr_error("Request to read attribute %d on connection %d declined with authorization reply %s",
handle,
connId,
to_string(read_auth_params.authorizationReply & 0xFF));
return read_auth_params.authorizationReply & 0xFF;
}
@ -1023,6 +1147,11 @@ uint8_t GattServer::atts_read_cb(
*pAttr->pLen = read_auth_params.len;
}
tr_info("Read attribute %d on connection %d - value=%s",
handle,
connId,
mbed_trace_array(pAttr->pValue, *pAttr->pLen));
GattReadCallbackParams read_params = {
connId,
handle,
@ -1046,6 +1175,11 @@ uint8_t GattServer::atts_write_cb(
attsAttr_t *pAttr
)
{
tr_info("Write attribute %d on connection %d - value=%s",
handle,
connId,
mbed_trace_array(pValue, len));
char_auth_callback* auth_cb = getInstance().get_auth_callback(handle);
if (auth_cb && auth_cb->write_cb) {
GattWriteAuthCallbackParams write_auth_params = {
@ -1060,6 +1194,11 @@ uint8_t GattServer::atts_write_cb(
auth_cb->write_cb.call(&write_auth_params);
if (write_auth_params.authorizationReply != AUTH_CALLBACK_REPLY_SUCCESS) {
tr_error("Request to write attribute %d on connection %d declined with authorization reply %s",
handle,
connId,
to_string(write_auth_params.authorizationReply & 0xFF));
return write_auth_params.authorizationReply & 0xFF;
}
}
@ -1131,6 +1270,8 @@ uint8_t GattServer::atts_write_cb(
uint8_t GattServer::atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t handle)
{
tr_info("Authenticate R/W request for attribute %d on connection %d", handle, connId);
#if BLE_FEATURE_SECURITY
// this CB is triggered when read or write of an attribute (either a value
// handle or a descriptor) requires secure connection security.
@ -1139,10 +1280,12 @@ uint8_t GattServer::atts_auth_cb(dmConnId_t connId, uint8_t permit, uint16_t han
link_encryption_t encryption(link_encryption_t::NOT_ENCRYPTED);
ble_error_t err = security_manager.getLinkEncryption(connId, &encryption);
if (err) {
tr_error("Insufficient authentication");
return ATT_ERR_AUTH;
}
if (encryption != link_encryption_t::ENCRYPTED_WITH_SC_AND_MITM) {
tr_error("The link must be secure and authenticated with a secure connection key");
return ATT_ERR_AUTH;
}
@ -1174,6 +1317,8 @@ void GattServer::add_generic_access_service()
current_attribute->settings = 0;
current_attribute->permissions = ATTS_PERMIT_READ;
tr_info("Add Generic Access Service to the Gatt Server: handle=%d", currentHandle);
// device name declaration
currentHandle += 2; // note: incremented by two to get a pointer to the value handle
++current_attribute;
@ -1202,6 +1347,8 @@ void GattServer::add_generic_access_service()
current_attribute->settings = ATTS_SET_VARIABLE_LEN;
current_attribute->permissions = ATTS_PERMIT_READ;
tr_info("Add Device Name characteristic: handle=%d", currentHandle);
// appearance declaration
currentHandle += 2; // note: incremented by two to get a pointer to the value handle
++current_attribute;
@ -1230,6 +1377,7 @@ void GattServer::add_generic_access_service()
current_attribute->settings = 0;
current_attribute->permissions = ATTS_PERMIT_READ;
tr_info("Add Appearance characteristic: handle=%d", currentHandle);
// peripheral preferred connection parameters declaration
currentHandle += 2; // note: incremented by two to get a pointer to the value handle
@ -1265,6 +1413,8 @@ void GattServer::add_generic_access_service()
current_attribute->settings = 0;
current_attribute->permissions = ATTS_PERMIT_READ;
tr_info("Add Peripheral Preferred Connection characteristic: handle=%d", currentHandle);
generic_access_service.service.endHandle = currentHandle;
AttsAddGroup(&generic_access_service.service);
}
@ -1290,6 +1440,8 @@ void GattServer::add_generic_attribute_service()
current_attribute->settings = 0;
current_attribute->permissions = ATTS_PERMIT_READ;
tr_info("Add Generic Attribute Service to the Gatt Server: handle=%d", currentHandle);
// service changed declaration
currentHandle += 2; // note: incremented by two to get a pointer to the value handle
++current_attribute;
@ -1317,6 +1469,8 @@ void GattServer::add_generic_attribute_service()
current_attribute->settings = 0;
current_attribute->permissions = 0;
tr_info("Add Service Changed characteristic: handle=%d", currentHandle);
// CCCD
++current_attribute;
current_attribute->pUuid = attCliChCfgUuid;
@ -1528,6 +1682,9 @@ void GattServer::onConfirmationReceived(EventCallback_t callback)
void GattServer::setEventHandler(EventHandler *handler)
{
if (handler == nullptr) {
tr_warning("Setting Gatt Server event handler to a null pointer");
}
eventHandler = handler;
}
@ -1564,7 +1721,7 @@ void GattServer::handleEvent(
{
switch (type) {
case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
tr_info("Updates enabled for attribute %d on connection %d", attributeHandle, connHandle);
if(eventHandler) {
GattUpdatesEnabledCallbackParams params({
.connHandle = connHandle,
@ -1579,7 +1736,7 @@ void GattServer::handleEvent(
}
break;
case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
tr_info("Updates disabled for attribute %d on connection %d", attributeHandle, connHandle);
if(eventHandler) {
GattUpdatesDisabledCallbackParams params({
.connHandle = connHandle,
@ -1594,7 +1751,7 @@ void GattServer::handleEvent(
}
break;
case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
tr_info("Confirmation received for attribute %d on connection %d", attributeHandle, connHandle);
if(eventHandler) {
GattConfirmationReceivedCallbackParams params({
.connHandle = connHandle,
@ -1610,7 +1767,7 @@ void GattServer::handleEvent(
break;
case GattServerEvents::GATT_EVENT_DATA_SENT:
tr_info("Data sent for attribute %d on connection %d", attributeHandle, connHandle);
if(eventHandler) {
GattDataSentCallbackParams params({
.connHandle = connHandle,