This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE_GATTS_EVT_WRITE not called, not using auth

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!

Related