mirror of https://github.com/ARMmbed/mbed-os.git
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 UUIDspull/14198/head
parent
f4febdcb9d
commit
db9428f18f
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue