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

NUS central example can't send more than 4 packets of 244 Bytes

Hi everybody,

I have some trouble fixing the ERROR 19 [NRF_ERROR_RESOURCES]. I think it's something about the buffer queue size that is too busy. But I don't know how to fix it because most of the resolution on that matter was on the peripheral side with BLE_GATTS_EVT_HVN_TX_COMPLETE but it's a server whereas on the central side it's a client. 

So I think I can't solve my problem with BLE_GATTS_EVT_HVN_TX_COMPLETE or I misunderstood something.

If you could enlighten me on that matter or give me some solutions. It would be great.

Some informations that might be useful : 

NRF_SDH_BLE_GAP_EVENT_LENGTH is 320

NRF_SDH_BLE_GAP_DATA_LENGTH is 251

NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 1408

// Where I send my 244 Bytes data

void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    
    static uint16_t index = 0;
	static uint32_t ret_val;
    static uint16_t length = 244;
	static uint8_t j;
	static uint8_t send_data[BLE_NUS_MAX_DATA_LEN];
  
    
	for (uint8_t i=0; i<length; i++)
	{
		send_data[i]=i;
	}
    switch (p_event->evt_type)
    {
        /**@snippet [Handling data from UART] */
        case APP_UART_DATA_READY:
            UNUSED_VARIABLE(app_uart_get(&data_array[index]));
            index++;

            if (//(data_array[index - 1] == '\n') ||
                (data_array[index - 1] == '\r') ||
                (index >= (m_ble_nus_max_data_len)))
            {
                NRF_LOG_INFO("Ready to send data over BLE NUS");
                NRF_LOG_HEXDUMP_INFO(data_array, index);

                do
                {
					if (index % 4 != 0 || index > 4)
                    {
						for (int i=0;i<10;i++)
						{
								ret_val = ble_nus_c_string_send(&m_ble_nus_c, send_data, length);
						}
					}

                    if ( (ret_val != NRF_ERROR_INVALID_STATE) && (ret_val != NRF_ERROR_RESOURCES) &&
						(ret_val != NRF_ERROR_NOT_FOUND))
                    {
                        APP_ERROR_CHECK(ret_val);
                    }
                } while (ret_val == NRF_ERROR_RESOURCES);

                index = 0;
            }
            break;

        /**@snippet [Handling data from UART] */
        case APP_UART_COMMUNICATION_ERROR:
            NRF_LOG_ERROR("Communication error occurred while handling UART.");
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;

        case APP_UART_FIFO_ERROR:
            NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;

        default:
            break;
    }
}

Best Regards,

Parents
  • Hello,

    The ble_nus_c_string_send() will result in a sd_ble_gattc_write() call in the end. Depending on what SDK version you are using, it is either called directly. Alternativley it is called via the GQ module. 

    Check out the declaration of this function in ble_gattc.h (may differ between different SDK versions).

    /**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure.
     *
     * @details This function can perform all write procedures described in GATT.
     *
     * @note    Only one write with response procedure can be ongoing per connection at a time.
     *          If the application tries to write with response while another write with response procedure is ongoing,
     *          the function call will return @ref NRF_ERROR_BUSY.
     *          A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer.
     *
     * @note    The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size
     *          When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
     *          A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete.
     *
     * @note    The application can keep track of the available queue element count for writes without responses 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_GATTC_EVT_WRITE_CMD_TX_COMPLETE event.
     *
     * @events
     * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.}
     * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.}
     * @endevents
     *
     * @mscs
     * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC}
     * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC}
     * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC}
     * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC}
     * @endmscs
     *
     * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
     * @param[in] p_write_params A pointer to a write parameters structure.
     *
     * @retval ::NRF_SUCCESS Successfully started the Write procedure.
     * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
     * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
     * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
     * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
     * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
     * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry.
     * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued.
     *                               Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_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_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params));

    Particularly these lines:

    * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued.
    * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry.

    So that is the solution in your case. If that doesn't work, let me know what SDK version you are using.

    Best regards,

    Edvin

  • Hi, 

    I was testing your solution but i encountered another problem...
    When I send 4 packets now on the peripheral I have :

    <error> app: Failed receiving NUS message. Error 0x4.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] 
    PC at: 0x00045DDD

    On err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);

    but i didn't have that issue before i don't know why suddenly i have this problem

    Best regards,

  • Hi Edwin,

    I was wondering if you has an update on my problem ? 

    Br,

  • Sorry for late response TermiteUser, Edvin went on parental leave and I just took over this case. I see that you found the answer for your problem. Once again sorry for the delays and the inconvenience caused by it.

  • Oh, I understand there is no problem, thank you for letting me know.

Reply Children
No Data
Related