Hi engineer,
I have developed a dongle that uses 52840 and is used as the master device. Now the data sent by the dongle to the slave device needs to use prepare write request.
//code segment
static uint8_t m_lts_buf[MEM_LENGTH];
static ble_user_mem_block_t m_lts_mem = {
.p_mem = m_lts_buf,
.len = MEM_LENGTH
};
static uint16_t prepare_handle;
static uint8_t prepare_buf[MEM_LENGTH];
static uint16_t prepare_offset;
static uint16_t prepare_length;
#define PREPARE_LEN (BLE_NUS_MAX_DATA_LEN - 2)
uint32_t prepare_write(uint8_t* mac, uint8_t* pBuf, uint16_t len)
{
memset(prepare_buf, 0, MEM_LENGTH);
prepare_offset = 0;
if(find_handle_by_mac(mac, &prepare_handle) == NRF_ERROR_NOT_FOUND){
return NRF_ERROR_NOT_FOUND;
}
prepare_length = len > MEM_LENGTH ? MEM_LENGTH : len;
memcpy(prepare_buf, pBuf, prepare_length);
uint32_t retval = client_prepare_write_request(prepare_handle, prepare_buf, PREPARE_LEN, prepare_offset);
prepare_offset += PREPARE_LEN;
return retval;
}
void on_ble_evt(const ble_evt_t * const p_ble_evt)
{
case BLE_EVT_USER_MEM_REQUEST:
NRF_LOG_DEBUG("BLE_EVT_USER_MEM_REQUEST");
err_code = sd_ble_user_mem_reply(p_gap_evt->conn_handle, &m_lts_mem);
//simple_uart_putstring("User mem request \r\n");
break;
case BLE_EVT_USER_MEM_RELEASE:
if ((p_ble_evt->evt.common_evt.params.user_mem_release.mem_block.p_mem == m_lts_mem.p_mem)
&&(p_ble_evt->evt.common_evt.params.user_mem_release.mem_block.len == m_lts_mem.len)){
NRF_LOG_DEBUG("mem release nothing");
}
NRF_LOG_DEBUG("BLE_EVT_USER_MEM_RELEASE");
break;
case BLE_GATTC_EVT_WRITE_RSP:{
NRF_LOG_DEBUG("BLE_GATTC_EVT_WRITE_RSP");
uint8_t temp_data[PREPARE_LEN];
if(p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL)
{
client_prepare_write_exec(p_gap_evt->conn_handle);
}
else
{
if(p_ble_evt->evt.gattc_evt.params.write_rsp.write_op == BLE_GATT_OP_PREP_WRITE_REQ)
{
if(prepare_offset == prepare_length){
//prepare write Execute
client_prepare_write_exec(p_gap_evt->conn_handle);
break;
}
if(prepare_offset + PREPARE_LEN > prepare_length){
//prepare write request. Last packet of data
client_prepare_write_request(p_gap_evt->conn_handle,
prepare_buf + prepare_offset, prepare_length - prepare_offset, prepare_offset);
prepare_offset = prepare_length;
}else{
//prepare write request
client_prepare_write_request(p_gap_evt->conn_handle,
prepare_buf + prepare_offset, PREPARE_LEN, prepare_offset);
prepare_offset += PREPARE_LEN;
}
}else if(p_ble_evt->evt.gattc_evt.params.write_rsp.write_op ==
BLE_GATT_OP_EXEC_WRITE_REQ){
NRF_LOG_DEBUG("BLE_GATT_OP_EXEC_WRITE_REQ");
}
}
}break;
}
uint32_t client_prepare_write_exec(uint16_t handle)
{
uint32_t index;
client_t * p_client;
uint32_t retval = NRF_ERROR_NO_MEM;
index = client_find(handle);
if(index == MAX_CLIENTS) return NRF_ERROR_NOT_FOUND;
p_client = &m_client[index];
ble_gattc_write_params_t write_params = {
.write_op = BLE_GATT_OP_EXEC_WRITE_REQ,
.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
.handle = 0,
.offset = 0,
.len = 0,
.p_value = NULL,
};
retval = NRF_ERROR_NO_MEM;
write_params.handle = p_client->srv_db.services[p_client->srv_db.curr_srv_ind].charateristics[p_client->char_index].characteristic.handle_value;
retval = sd_ble_gattc_write(p_client->srv_db.conn_handle, &write_params);
NRF_LOG_DEBUG("gattc write retval %d", retval);
return retval;
}
uint32_t client_prepare_write_request(uint16_t handle, uint8_t * p_string, uint16_t length, uint16_t offset)
{
uint32_t index;
client_t * p_client;
uint32_t retval = NRF_ERROR_NO_MEM;
index = client_find(handle);
if(index == MAX_CLIENTS) return NRF_ERROR_NOT_FOUND;
p_client = &m_client[index];
ble_gattc_write_params_t write_params = {
.write_op = last ? BLE_GATT_OP_EXEC_WRITE_REQ : BLE_GATT_OP_PREP_WRITE_REQ,
.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
.handle = 0,
.offset = offset,
.len = length,
.p_value = p_string,
};
NRF_LOG_DEBUG("p_string %s, length %d, offset %d", p_string, length, offset);
retval = NRF_ERROR_NO_MEM;
write_params.handle = p_client->srv_db.services[p_client->srv_db.curr_srv_ind].charateristics[p_client->char_index].characteristic.handle_value;
retval = sd_ble_gattc_write(p_client->srv_db.conn_handle, &write_params);
NRF_LOG_DEBUG("gattc write retval %d", retval);
return retval;
}
This is my code, I call prepare_write() first, then send(use prepare write requese) the remaining data in the BLE_GATTC_EVT_WRITE_RSP event .
When the data is sent, start to execute prepare write Execute.
Can successfully send data to the slave device.
However, when I send the next command using BLE_GATT_OP_WRITE_CMD, it will prompt an error: SD Read/Write API returns error
The error code is 7, error code 7 meansInvalid Parameter
please help me.