In previous SDK (or softdevice?) version, the maximum data length for a notification was 20 bytes.
With SDK V10 and softdevice 8, the following code returns error NRF_ERROR_DATA_SIZE
if the length is greather than 10 bytes.
err_code = sd_ble_gatts_value_set(p_watch->conn_handle,
p_watch->command_handles.value_handle,
&gatts_value);
Is there a new limitation on the maximum data length for notification or am I missing something?
EDIT
This is how I am defining the characteristic. When BLE_RESPONSE_MAX_LENGTH is set to 10
everything is fine, but when it is set to 20
, the NRF_ERROR_DATA_SIZE
is throw when I try to send a notification.
/**@brief Add Response characteristic.
*
* @param[in] p_watch Watch Service structure.
* @param[in] p_watch_init Information needed to initialize the service.
*
* @return NRF_SUCCESS on success, otherwise an error code.
*/
static uint32_t response_char_add(ble_watch_t * p_watch, const ble_watch_init_t * p_watch_init)
{
uint32_t err_code;
ble_gatts_char_md_t char_md;
ble_gatts_attr_md_t cccd_md;
ble_gatts_attr_t attr_char_value;
ble_uuid_t ble_uuid;
ble_gatts_attr_md_t attr_md;
uint32_t initial_value = 0;
uint8_t encoded_buffer[BLE_RESPONSE_MAX_LENGTH] = {0};
// Add notification support
if (p_watch->is_notification_supported_response_char)
{
memset(&cccd_md, 0, sizeof(cccd_md));
// According to BAS_SPEC_V10, the read operation on cccd should be possible without
// authentication.
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);//TODO : confirm write access
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
}
memset(&char_md, 0, sizeof(char_md));
char_md.p_char_user_desc = NULL;
char_md.char_props.read = 1;
char_md.char_props.notify = (p_watch->is_notification_supported_response_char) ? 1 : 0;
char_md.p_char_pf = NULL;
char_md.p_user_desc_md = NULL;
char_md.p_cccd_md = (p_watch->is_notification_supported_response_char) ? &cccd_md : NULL;
char_md.p_sccd_md = NULL;
ble_uuid.type = p_watch->uuid_type;
ble_uuid.uuid = BLE_UUID_WATCH_RESPONSE_CHAR;
memset(&attr_md, 0, sizeof(attr_md));
//BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
//BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth = 0;
attr_md.wr_auth = 0;
attr_md.vlen = 0;
unix_time_encode(initial_value,encoded_buffer);
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &ble_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = BLE_RESPONSE_MAX_LENGTH;
attr_char_value.init_offs = 0;
attr_char_value.max_len = BLE_RESPONSE_MAX_LENGTH;
attr_char_value.p_value = encoded_buffer;
err_code = sd_ble_gatts_characteristic_add(p_watch->service_handle,
&char_md,
&attr_char_value,
&p_watch->response_handles);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
return NRF_SUCCESS;
}
And this is how I send the notification
/**@brief Response characteristic update
*
* @param[in] p_watch watch Service structure.
* @param[in] value New value to update.
*/
uint32_t ble_response_update(ble_watch_t * p_watch, uint8_t * p_data_buffer)
{
ble_gatts_value_t gatts_value;
uint32_t err_code = NRF_SUCCESS;
uint8_t encoded_buffer[BLE_RESPONSE_MAX_LENGTH] = {0x00};
memcpy(encoded_buffer,p_data_buffer, BLE_RESPONSE_MAX_LENGTH);
uint16_t len = BLE_RESPONSE_MAX_LENGTH;
// Initialize value struct.
memset(&gatts_value, 0, sizeof(gatts_value));
gatts_value.len = len;
gatts_value.offset = 0;
gatts_value.p_value = encoded_buffer;
// Update database
err_code = sd_ble_gatts_value_set(p_watch->conn_handle,
p_watch->command_handles.value_handle,
&gatts_value);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// Send value if connected and notifying
if ((p_watch->conn_handle != BLE_CONN_HANDLE_INVALID) && p_watch->is_notification_supported_response_char)
{
ble_gatts_hvx_params_t hvx_params;
memset(&hvx_params, 0, sizeof(hvx_params));
hvx_params.handle = p_watch->response_handles.value_handle;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
hvx_params.offset = 0;
hvx_params.p_len = &len;
hvx_params.p_data = encoded_buffer;
err_code = sd_ble_gatts_hvx(p_watch->conn_handle, &hvx_params);
}
else
{
err_code = NRF_ERROR_INVALID_STATE;
}
return err_code;
}
EDIT 2
Capture from Keil to depict the problem when sending notification with BLE_RESPONSE_MAX_LENGTH
set to 20
Best regards