diff --git a/ble/att.c b/ble/att.c index f8ae32b32..0eed6ddd3 100644 --- a/ble/att.c +++ b/ble/att.c @@ -855,9 +855,9 @@ static uint16_t handle_prepare_write_request(att_connection_t * att_connection, return setup_error(response_buffer, ATT_PREPARE_WRITE_REQUEST, handle, error_code); } - ok = (*att_write_callback)(handle, ATT_TRANSACTION_MODE_ACTIVE, offset, request_buffer + 3, request_len - 3, NULL); - if (!ok){ - return setup_error(response_buffer, ATT_PREPARE_WRITE_REQUEST, handle, ATT_ERROR_PREPARE_QUEUE_FULL); + int result = (*att_write_callback)(handle, ATT_TRANSACTION_MODE_ACTIVE, offset, request_buffer + 3, request_len - 3, NULL); + if (result){ + return setup_error(response_buffer, ATT_PREPARE_WRITE_REQUEST, handle, result); } // response: echo request diff --git a/ble/att.h b/ble/att.h index cf1490874..361fea306 100644 --- a/ble/att.h +++ b/ble/att.h @@ -161,7 +161,7 @@ typedef uint16_t (*att_read_callback_t)(uint16_t handle, uint16_t offset, uint8_ // @param buffer // @param buffer_size // @param signature used for signed write commmands -// @returns 1 if request could be queue for ATT_TRANSACTION_MODE_ACTIVE +// @returns 0 if write was ok, ATT_ERROR_PREPARE_QUEUE_FULL if no space in queue, ATT_ERROR_INVALID_OFFSET if offset is larger than max buffer typedef int (*att_write_callback_t)(uint16_t handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size, signature_t * signature); // MARK: ATT Operations diff --git a/example/libusb/ble_peripheral.c b/example/libusb/ble_peripheral.c index 7287c476f..a6b7f79a2 100644 --- a/example/libusb/ble_peripheral.c +++ b/example/libusb/ble_peripheral.c @@ -299,7 +299,7 @@ static int att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16 client_configuration = buffer[0]; client_configuration_handle = handle; printf("Client Configuration set to %u for handle %04x\n", client_configuration, handle); - return 1; + return 0; // ok default: break; } @@ -312,7 +312,7 @@ static int att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16 attributes_index = att_attribute_for_handle(handle); if (attributes_index < 0){ attributes_index = att_attribute_for_handle(0); - if (attributes_index < 0) return 0; // fail + if (attributes_index < 0) return 0; // ok, but we couldn't store it (our fault) att_attributes[attributes_index].handle = handle; } att_attributes[attributes_index].len = buffer_size; @@ -320,30 +320,35 @@ static int att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16 break; case ATT_TRANSACTION_MODE_ACTIVE: writes_index = att_write_queue_for_handle(handle); - if (writes_index < 0) return 0; - if (buffer_size + offset > ATT_VALUE_MAX_LEN) return 0; + if (writes_index < 0) return ATT_ERROR_PREPARE_QUEUE_FULL; + if (offset > ATT_VALUE_MAX_LEN) return ATT_ERROR_INVALID_OFFSET; + if (buffer_size + offset > ATT_VALUE_MAX_LEN) { + // truncat value + buffer_size = ATT_VALUE_MAX_LEN - offset; + } att_write_queues[writes_index].len = buffer_size + offset; memcpy(&(att_write_queues[writes_index].value[offset]), buffer, buffer_size); break; case ATT_TRANSACTION_MODE_EXECUTE: - for (writes_index=0;writes_index