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

Long Read with authorize: how to reply with ATTERR_INVALID_OFFSET

What is the exact sequence when reading a characteristic with variable length and authorize required.

When I have a actual data length of 14 I can read with offset = 0 and a normal "Read Request" is transmitted.

How do I know that I have read all data? Do I have to do send a second Read with offset to know that there are no more data left?

When I do a second read with offset = 14, a "Read Blob Request is sent from the client to the server, and I want to answer with BLE_GATT_STATUS_ATTERR_INVALID_OFFSET. Calling "sd_ble_gatts_rw_authorize_reply" with status =  BLE_GATT_STATUS_ATTERR_INVALID_OFFSET results in the erro_code INVALID_PARAM.

Parents
  • Hi.

     

    When I do a second read with offset = 14, a "Read Blob Request is sent from the client to the server, and I want to answer with BLE_GATT_STATUS_ATTERR_INVALID_OFFSET. Calling "sd_ble_gatts_rw_authorize_reply" with status =  BLE_GATT_STATUS_ATTERR_INVALID_OFFSET results in the erro_code INVALID_PARAM.

     I'm a bit unsure what you mean here actually, have you looked at the API documentation for sd_ble_gatts_rw_authorize_reply()?

    /**@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));
    

    If you get the error code NRF_ERROR_INVALID_PARAM when calling this function, you have either given a wrong connection handle or invalid data to be written by the application.

    Best regards,

    Andreas

  • I am implementing long read with authorization in the server (peripheral). I have a characteristic with vlen = 1 and maxlen = 300. ATT_MTU = 23.

    To transfer a value with len = 30, the client reads first with offset=0 and gets back 22 data bytes. Because len in response == ATT_MTU-1 the client has to read again with offset = 22 and gets back the response with len=8 and the remaining 8 bytes. Client knows now that the transfer is over because len < ATT_MTU-1.

    When the length of the data is len = 44, the client reads with offset = 22 and gets back len=22 and the remaining 22 bytes. Now the client has to read a third time with offset= 44 to be sure to have read all bytes.

    My question is now: What is the correct answer from server to this third request to inform the client that there are no more data to read?

    When trying to answer with INVALID_OFFSET, I get the INVALID_PARAMETER error, when I answer with len=0, I get a "[Malformed packet]" on the wire (nrfSniffer).

Reply
  • I am implementing long read with authorization in the server (peripheral). I have a characteristic with vlen = 1 and maxlen = 300. ATT_MTU = 23.

    To transfer a value with len = 30, the client reads first with offset=0 and gets back 22 data bytes. Because len in response == ATT_MTU-1 the client has to read again with offset = 22 and gets back the response with len=8 and the remaining 8 bytes. Client knows now that the transfer is over because len < ATT_MTU-1.

    When the length of the data is len = 44, the client reads with offset = 22 and gets back len=22 and the remaining 22 bytes. Now the client has to read a third time with offset= 44 to be sure to have read all bytes.

    My question is now: What is the correct answer from server to this third request to inform the client that there are no more data to read?

    When trying to answer with INVALID_OFFSET, I get the INVALID_PARAMETER error, when I answer with len=0, I get a "[Malformed packet]" on the wire (nrfSniffer).

Children
Related