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.

  • 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

  • Here are the relevant message sequence charts: Long Read on Client Side and (Long) Read with Authorize Servcer Side

    I wan't to handle the case when the client requests more data than available. This is the last reply in the "Long Read on Client Side" message sequence chart.

    When setting the Status to BLE_GATT_STATUS_ATTERR_INVALID_OFFSET in the reply, I get the INVALID_PARAMETER result when calling the sd_ble_gatts_rw_authorize_reply.

     

  • Hi.

    As I said in my previous reply, you get this error because 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).

  • Hi Christian,

    What you do is correct by trying to send an INVALID_OFFSET. The question is why does it give an invalid param. Since we do not have any examples to start with for that, it would help me if you could give me a code snippet to reproduce that error and I will see if i can get it work on my side.

Related