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

sd_ble_gatts_rw_authorize_reply() return SUCCESS by long-length parameter

When create 128byte length's CHARACTERISTIC and read with NRFCONNECT on Android.
NRFCONNECT returns GATT_READ_NOT_PERMIT even though sd_ble_gatts_rw_authorize_reply() completes normally.

code is folowing,

Why sd_ble_gatts_rw_authorize_reply return SUCCESS?

#define	BUFFER_LENGTH				(128)

attr_md.vloc    = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth = 1;
attr_md.wr_auth = 1;
attr_md.vlen    = 0;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid    = uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_offs = 0;
attr_char_value.init_len  = BUFFER_LENGTH;
attr_char_value.max_len   = BUFFER_LENGTH;
attr_char_value.p_value   = nullptr;
APP_ERROR_CHECK(sd_ble_gatts_characteristic_add(service_handle,
                          &char_md,
                          &attr_char_value,
                          char_param->p_handle));
...........
...........
case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
if ( p_ble_evt->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_READ ) {
    reply.params.read.len = BUFFER_LENGTH;
    reply.params.read.offset = 0;
    reply.params.read.p_data = buffer;
	reply.params.read.update = 1;
	reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
    APP_ERROR_CHECK(sd_ble_gatts_rw_authorize_reply(m_conn_handle, &reply));
}

Parents Reply Children
  • My concern is that sd_ble_gatts_rw_authorize_reply returns success if you specify a read.len greater than ATT_MTU.
    Is this correct behavior?

  • Hi, 

    I discussed this with some colleagues. 
    When looking at the API documentation it is clear that the function should only return NRF_SUCCESS when everything is OK, otherwise e.g. INVALID_PARAMS should be returned. 

    Could you try with replies larger and smaller than the MTU size and log the return values?

    https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s140.api.v6.0.0%2Fgroup___b_l_e___g_a_t_t_s___f_u_n_c_t_i_o_n_s.html&anchor=ga6de7aea3a870669e1d869b047de95545

  • setup code

        ble_gatts_char_md_t char_md;
        ble_gatts_attr_t    attr_char_value;
        ble_gatts_attr_md_t attr_md;
    
        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.read			 = 1;
       	char_md.char_props.notify		 = 0;
    	char_md.p_cccd_md				= NULL;
        char_md.p_char_user_desc        = NULL;
        char_md.p_char_pf               = NULL;
        char_md.p_user_desc_md          = NULL;
        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 = 1;
        attr_md.wr_auth = 1;
        attr_md.vlen    = 0;
    
        memset(&attr_char_value, 0, sizeof(attr_char_value));
        
        attr_char_value.p_uuid    = uuid;
        attr_char_value.p_attr_md = &attr_md;
    	attr_char_value.init_offs = 0;
        
    	attr_char_value.init_len  = char_param->value_length;
    	attr_char_value.max_len   = char_param->value_length;
    	attr_char_value.p_value   = nullptr;
    	
    	APP_ERROR_CHECK(sd_ble_gatts_characteristic_add(service_handle,
    											&char_md,
    											&attr_char_value,
    											char_param->p_handle));
    

    read

    m_conn_handle = 1
    
    auth_reply
     .type = 1,
     .params.read.gatt_status = 0,
     .params.read.update = 1,
     .params.read.offset = 0,
     .params.read.len = 128,
     .params.read.p_data = buffer,
    sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply)
    return is 0
    

  • Hello,

    As Håkon said, if sd_ble_gatts_rw_authorize reply returns NRF_SUCCESS, the reply is queued:

    /**@brief Respond to a Read/Write authorization request.
     *
     * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application.
     *
     * @mscs
     * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
     * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
     * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
     * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC}
     * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC}
     * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
     * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC}
     * @endmscs
     *
     * @param[in] conn_handle                 Connection handle.
     * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application.
     *
     * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond
     *       to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update
     *       is set to 0.
     *
     * @retval ::NRF_SUCCESS               Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated.
     * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
     * @retval ::NRF_ERROR_BUSY            The stack is busy, process pending events and retry.
     * @retval ::NRF_ERROR_INVALID_ADDR    Invalid pointer supplied.
     * @retval ::NRF_ERROR_INVALID_STATE   Invalid Connection State or no authorization request pending.
     * @retval ::NRF_ERROR_INVALID_PARAM   Authorization op invalid,
     *                                         handle supplied does not match requested handle,
     *                                         or invalid data to be written provided by the application.
     * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
     */
    SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params));
    

    I am not sure what you are trying to show with the latest snippets. Can you please explain?

    Best regards,

    Edvin

  • Sorry,
    char_param->value_length -> replace 128

    >I am not sure what you are trying to show with the latest snippets
    this is setup for characteristic by 128-byte length, and this length is greater than MAX_ATT.

    Again say,
    I think that sd_ble_gatts_rw_authorize_reply() would return an error if called with a length greater than ATT_MTU. But it actually succeeds.
    I just want to know if this is the right move.


Related