Merge pull request #13449 from paul-szczepanek-arm/fix-prep-write

BLE: Fix writing attributes larger than MTU size
pull/13468/head
Martin Kojtal 2020-08-21 13:52:07 +01:00 committed by GitHub
commit 31701fa518
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 1087 additions and 1068 deletions

View File

@ -381,13 +381,11 @@ private:
struct PrepareWriteResponseConverter : ResponseConverter<ATTC_PREPARE_WRITE_RSP> {
static AttPrepareWriteResponse convert(const attEvt_t* event)
{
// WARNING: Not sure if correct, the stack erase the length parameter
return AttPrepareWriteResponse(
event->handle,
to_uint16_t(event->pValue + 2),
// FIXME: the stack set the lenght to 0, the data won't be seen ...
0, /* offset is lost */
make_const_Span(
event->pValue + 4,
event->pValue,
event->valueLen
)
);

View File

@ -260,7 +260,7 @@ void attsProcPrepWriteReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket)
}
/* verify write length, fixed length */
else if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) == 0) &&
(writeLen != pAttr->maxLen))
(writeLen > pAttr->maxLen))
{
err = ATT_ERR_LENGTH;
}

View File

@ -329,6 +329,7 @@ ble_error_t GattServer::insert_characteristic_value_attribute(
}
if (properties & WRITABLE_PROPERTIES) {
attribute_it->settings |= ATTS_SET_WRITE_CBACK;
attribute_it->settings |= ATTS_SET_ALLOW_OFFSET;
}
if (value_attribute.getUUID().shortOrLong() == UUID::UUID_TYPE_LONG) {
attribute_it->settings |= ATTS_SET_UUID_128;
@ -990,9 +991,39 @@ uint8_t GattServer::atts_write_cb(
{
uint8_t err;
/* TODO: offset is not handled properly */
if ((err = AttsSetAttr(handle, len, pValue)) != ATT_SUCCESS) {
return err;
GattCharacteristic* auth_char = getInstance().get_auth_char(handle);
if (auth_char && auth_char->isWriteAuthorizationEnabled()) {
GattWriteAuthCallbackParams write_auth_params = {
connId,
handle,
offset,
len,
pValue,
AUTH_CALLBACK_REPLY_SUCCESS
};
GattAuthCallbackReply_t ret = auth_char->authorizeWrite(&write_auth_params);
if (ret!= AUTH_CALLBACK_REPLY_SUCCESS) {
return ret & 0xFF;
}
}
/* we don't write anything during the prepare phase */
bool write_happened = (operation != ATT_PDU_PREP_WRITE_REQ);
MBED_ASSERT(len + offset <= pAttr->maxLen);
if (write_happened) {
WsfTaskLock();
memcpy((pAttr->pValue + offset), pValue, len);
/* write the length if variable length attribute */
if ((pAttr->settings & ATTS_SET_VARIABLE_LEN) != 0) {
*(pAttr->pLen) = offset + len;
}
WsfTaskUnlock();
}
GattWriteCallbackParams::WriteOp_t writeOp;
@ -1025,33 +1056,19 @@ uint8_t GattServer::atts_write_cb(
break;
}
GattCharacteristic* auth_char = getInstance().get_auth_char(handle);
if (auth_char && auth_char->isWriteAuthorizationEnabled()) {
GattWriteAuthCallbackParams write_auth_params = {
if (write_happened) {
GattWriteCallbackParams write_params = {
connId,
handle,
writeOp,
offset,
len,
pValue,
AUTH_CALLBACK_REPLY_SUCCESS
pValue
};
GattAuthCallbackReply_t ret = auth_char->authorizeWrite(&write_auth_params);
if (ret!= AUTH_CALLBACK_REPLY_SUCCESS) {
return ret & 0xFF;
}
getInstance().handleDataWrittenEvent(&write_params);
}
GattWriteCallbackParams write_params = {
connId,
handle,
writeOp,
offset,
len,
pValue
};
getInstance().handleDataWrittenEvent(&write_params);
return ATT_SUCCESS;
}