Hi!
Using SDK 14, nRF52382, used ble_template to develop a custom app.
I have problems with BLE_GATTS_EVT_WRITE not being called. I do not use auth. My custom ble sevice has 3 chars and all are setup like this:
memset(&cccd_md, 0, sizeof(cccd_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.write = 1;
char_md.char_props.write_wo_resp = 1;
char_md.char_props.notify = 1;
char_md.p_char_user_desc = NULL;
char_md.p_char_pf = NULL;
char_md.p_user_desc_md = NULL;
char_md.p_cccd_md = &cccd_md;
char_md.p_sccd_md = NULL;
...
memset(&attr_md, 0, sizeof(attr_md));
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 = 1;
...
When I connect with mobile device to this module and write a single byte to one of the chars I get 2 calls with BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event. Both are write requests, first is BLE_GATTS_OP_PREP_WRITE_REQ and second is BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL.
If I leave the code as it is in ble_template for auth event:
case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
{
ble_gatts_evt_rw_authorize_request_t req;
ble_gatts_rw_authorize_reply_params_t auth_reply;
req = p_ble_evt->evt.gatts_evt.params.authorize_request;
if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
{
if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) ||
(req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
(req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
{
if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
{
auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
}
else
{
auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
}
auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
&auth_reply);
APP_ERROR_CHECK(err_code);
}
}
I get a fatal error with code 7, NRF_ERROR_INVALID_PARAM.
Browsing for answers I found out that this is a bug and that you have to write something like this:
if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
{
if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) ||
(req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
(req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
{
if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
{
auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
}
else
{
auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
}
auth_reply.params.write.gatt_status = (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) ? BLE_GATT_STATUS_SUCCESS : APP_FEATURE_NOT_SUPPORTED;
err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &auth_reply);
APP_ERROR_CHECK(err_code);
}
}
Meaning that BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL should set gatt_status as success.
After that I get no errors, but BLE_GATTS_EVT_WRITE is never called!
After a lot of time reading questions and answers I found out that BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST should be only called when auth is used, and BLE_GATTS_EVT_WRITE when auth is not used, but is does not behave like this.
Anything I missed?
Thanks!