diff --git a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h index cf310c3..32a21ea 100644 --- a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h +++ b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h @@ -1672,19 +1672,26 @@ * * @attention This function is not meant to be called by user code. * - * @param[in] params Context of the read-auth request; it contains an + * @param[in,out] params Context of the read-auth request; it contains an * out-parameter used as a reply and the handler can fill it with outgoing - * data. + * data. The params->data provides a pointer to the data and params->len + * provides the length of this data. params->len is also used to pass the + * maximum size of data that the params->data can contain. If you set the + * params->len to a value larger than the passed in value the read operation + * will fail. * * @return A GattAuthCallbackReply_t value indicating whether authorization * is granted. * + * @note If the read is approved, the event handler can specify an outgoing + * value directly with the help of the fields params->data and params->len. + * * @note If the read request is approved and params->data remains nullptr, then * the current characteristic value is used in the read response payload. * - * @note If the read is approved, the event handler can specify an outgoing - * value directly with the help of the fields - * GattReadAuthCallbackParams::data and GattReadAuthCallbackParams::len. + * @note The params->len parameter initially contains the maximum length of + * data that can be returned. Set it to the length of your data but it must + * not be larger than the original value. */ GattAuthCallbackReply_t authorizeRead(GattReadAuthCallbackParams *params) { diff --git a/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp b/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp index 78134bd..7be4e17 100644 --- a/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp +++ b/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp @@ -1130,7 +1130,7 @@ connId, handle, offset, - /* len */ 0, + /* len */ pAttr->maxLen, /* data */ nullptr, AUTH_CALLBACK_REPLY_SUCCESS }; @@ -1146,8 +1146,27 @@ return read_auth_params.authorizationReply & 0xFF; } - pAttr->pValue = read_auth_params.data; - *pAttr->pLen = read_auth_params.len; + /* if new data provided copy into the attribute value buffer */ + if (read_auth_params.data) { + if (read_auth_params.offset + read_auth_params.len > pAttr->maxLen) { + tr_error("Read authorisation callback set length larger than maximum attribute length. Cannot copy data"); + + GattReadCallbackParams read_params = { + connId, + handle, + offset, + read_auth_params.len, + read_auth_params.data, + BLE_ERROR_INVALID_PARAM, + }; + getInstance().handleDataReadEvent(&read_params); + + return ATT_ERR_UNLIKELY; + } + + memcpy(pAttr->pValue + read_auth_params.offset, read_auth_params.data, read_auth_params.len); + *pAttr->pLen = read_auth_params.len; + } } tr_debug("Read attribute %d on connection %d - value=%s",