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

while loop other error,miss data

if i use this code to send data,i sometimes miss data..

do
{
err_code = ble_nus_string_send(&m_nus, (uint8_t*)data, &data_len);

if (( err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_BUSY))
{
  APP_ERROR_CHECK(err_code);
}
} while (err_code == NRF_ERROR_BUSY);

but if i use this way, data can be sent sucessfully .

loop:
err_code = ble_nus_string_send(&m_nus, (uint8_t*)data, &data_len);
nrf_delay_ms(1);
if(err_code!=0)
goto loop;

why ? maybe only error is busy, it will send again, if other error,it would not ? 

it would not, so if we face other error,it will lose data ...

  • Hi Lyman, 

    the ble_nus_data_send() function can return the following error codes:

    • NRF_ERROR_NOT_FOUND
    • NRF_ERROR_INVALID_STATE
    • NRF_ERROR_INVALID_PARAM
    • All error_code returned by sd_ble_gatts_hvx, see snippet below

    /**@brief Notify or Indicate an attribute value.
     *
     * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation
     *          (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that
     *          the application can atomically perform a value update and a server initiated transaction with a single API call.
     *
     * @note    The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution.
     *          The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY,
     *          @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES.
     *          The caller can check whether the value has been updated by looking at the contents of *(@ref ble_gatts_hvx_params_t::p_len).
     *
     * @note    Only one indication procedure can be ongoing per connection at a time.
     *          If the application tries to indicate an attribute value while another indication procedure is ongoing,
     *          the function call will return @ref NRF_ERROR_BUSY.
     *          A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer.
     *
     * @note    The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size
     *          When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
     *          A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete.
     *
     * @note    The application can keep track of the available queue element count for notifications by following the procedure below:
     *          - Store initial queue element count in a variable.
     *          - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
     *          - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event.
     *
     * @events
     * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.}
     * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.}
     * @endevents
     *
     * @mscs
     * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
     * @mmsc{@ref BLE_GATTS_HVN_MSC}
     * @mmsc{@ref BLE_GATTS_HVI_MSC}
     * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC}
     * @endmscs
     *
     * @param[in] conn_handle      Connection handle.
     * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data
     *                             contains a non-NULL pointer the attribute value will be updated with the contents
     *                             pointed by it before sending the notification or indication. If the attribute value
     *                             is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to
     *                             contain the number of actual bytes written, else it will be set to 0.
     *
     * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
     * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
     * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
     *                                   - Invalid Connection State
     *                                   - Notifications and/or indications not enabled in the CCCD
     *                                   - An ATT_MTU exchange is ongoing
     * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
     * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
     * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
     * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
     * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
     * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic.
     * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
     * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry.
     * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
     * @retval ::NRF_ERROR_RESOURCES Too many notifications queued.
     *                               Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.
     * @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_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));

    I am guessing that its the sd_ble_gatts_hvx() call in ble_nus_data_send() that returns  NRF_ERROR_RESOURCES due to too many notifications being queued. As stated in the function description you should wait for the BLE_GATTS_EVT_HVN_TX_COMPLETE event before queuing additional notifications. 

    Best regards

    Bjørn

Related