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
  • 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
    

Children
  • 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.


  • Hello,

    Sorry for the late reply. We have been short staffed during the Christmas Holidays. 

    So where in the snippet do you set the ATT_MTU? If it returns NRF_SUCCESS (0), then the softdevice will split up the package. Are you missing data on the receiving side?

  • >where in the snippet do you set the ATT_MTU?
    No. I use default setting.

    >Are you missing data on the receiving side?
    I try to read nrfconnect for mobile.
    It's return 'Error2(0x2):GATT READ NOT PERMIT

  • Ok. I think we are looking in the wrong place now. If that is the return value, it has nothing to do with the length of the characteristic. It has to do with the permissions for the characteristic.

    From your snippets I can't see that you are missing any permission settings, but I see that you are missing some uuid settings 

    I suggest that you take a look at the ble_app_uart, in rx_char_add() in ble_nus.c:

    static uint32_t rx_char_add(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init)
    {
        ble_gatts_char_md_t char_md;
        ble_gatts_attr_t    attr_char_value;
        ble_uuid_t          ble_uuid;                       //This is missing
        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.p_char_user_desc         = NULL;
        char_md.p_char_pf                = NULL;
        char_md.p_user_desc_md           = NULL;
        char_md.p_cccd_md                = NULL;
        char_md.p_sccd_md                = NULL;
    
        ble_uuid.type = p_nus->uuid_type;                   //This is missing
        ble_uuid.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC;     //This is missing
                        
        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;
    
        memset(&attr_char_value, 0, sizeof(attr_char_value));
    
        attr_char_value.p_uuid    = &ble_uuid;                  //This is missing
        attr_char_value.p_attr_md = &attr_md;
        attr_char_value.init_len  = 1;
        attr_char_value.init_offs = 0;
        attr_char_value.max_len   = BLE_NUS_MAX_RX_CHAR_LEN;
    
        return sd_ble_gatts_characteristic_add(p_nus->service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               &p_nus->rx_handles);
    }

    But compare how you add the characteristic to this example, and see if you can find any other differences. 

    Best regards,

    Edvin

Related