Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SDK14 NUS_C Question

HW: nRF52, PCA10056

SW: SDK15

I'm using the nus_c service with multiple central connections.

After change the GATT Write operations from BLE_GATT_OP_WRITE_CMD to BLE_GATT_OP_WRITE_REQ,  then call "ble_nus_c_string_send()" function, it always return "NRF_ERROR_BUSY".(success to discovery service and enable notification)

Using the same peripheral and controlling it by the nRFConnect, everything works well.

Here are some codes for your reference, and please help me to solve the problem.  

main.c

#define TOTAL_LINK_COUNT        NRF_SDH_BLE_CENTRAL_LINK_COUNT

BLE_DB_DISCOVERY_DEF(m_db_disc);
BLE_NUS_C_ARRAY_DEF(m_ble_nus_c, NRF_SDH_BLE_CENTRAL_LINK_COUNT);           /**< LED Button client instances. */

static uint8_t           		 m_ble_nus_c_count; 

static void nus_c_init(void)
{
    uint32_t         err_code;
    ble_nus_c_init_t nus_c_init_t;

    nus_c_init_t.evt_handler = ble_nus_c_evt_handler;
	
		for (m_ble_nus_c_count = 0; m_ble_nus_c_count < TOTAL_LINK_COUNT; m_ble_nus_c_count++)
    {
        err_code = ble_nus_c_init(&m_ble_nus_c[m_ble_nus_c_count], &nus_c_init_t);
        APP_ERROR_CHECK(err_code);
    }
    m_ble_nus_c_count = 0;
}

static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, const ble_nus_c_evt_t * p_ble_nus_evt)
{
    uint32_t err_code;

    switch (p_ble_nus_evt->evt_type)
		{
			case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
				NRF_LOG_INFO("BLE_NUS_C_EVT_DISCOVERY_COMPLETE \r\n");
			
				err_code = ble_nus_c_handles_assign(&m_ble_nus_c[m_ble_nus_c->conn_handle], p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
        APP_ERROR_CHECK(err_code);
			
				err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
        APP_ERROR_CHECK(err_code);
				NRF_LOG_INFO("ble_nus_c_tx_notif_enable \r\n");
			
				//ble_nus_c_led_control_command_send(p_ble_nus_c);
				while(ble_nus_c_string_send(p_ble_nus_c, (uint8_t *)TEST_CMD, sizeof(TEST_CMD)) != NRF_SUCCESS)
				{
					;
				}
				NRF_LOG_INFO("ble_nus_c_string_send \r\n");
				break;
			
			case BLE_NUS_C_EVT_NUS_TX_EVT:
			
				NRF_LOG_INFO("RX: %02x %02x %02x %02x \r\n",p_ble_nus_evt->p_data[0],p_ble_nus_evt->p_data[1],p_ble_nus_evt->p_data[2],p_ble_nus_evt->p_data[3]);
			
				break;
			
			case BLE_NUS_C_EVT_DISCONNECTED:
            break;
			
		}
}

ble_nus_c.c

uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length)
{
    VERIFY_PARAM_NOT_NULL(p_ble_nus_c);

    if (length > BLE_NUS_MAX_DATA_LEN)
    {
        NRF_LOG_WARNING("Content too long.");
        return NRF_ERROR_INVALID_PARAM;
    }
    if (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID)
    {
        NRF_LOG_WARNING("Connection handle invalid.");
        return NRF_ERROR_INVALID_STATE;
    }

    ble_gattc_write_params_t const write_params =
    {
				.write_op = BLE_GATT_OP_WRITE_REQ, // write with response
        .flags    = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
        .handle   = p_ble_nus_c->handles.nus_rx_handle,
        .offset   = 0,
        .len      = length,
        .p_value  = p_string
    };

    return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);
}

Parents
  • Hello,

    Please see this response from an old thread.

    I do not know how you check this, but let me see if I understand you correctly:

     

    According to the documentation of sd_ble_gattc_write, it says that a return value NRF_ERROR_BUSY means: "For write with response, procedure is already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry."

    Did you already send a write with response prior to the one returning NRF_ERROR_BUSY?

     

    Best regards,

    Edvin

  • Hello Edvin,

    Thanks for your reply. 

    We check the " BLE_GATTC_EVT_WRITE_RSP" first after we send "ble_nus_c_tx_notif_enable(p_ble_nus_c)".

    The BLE command can be sent after receive " " BLE_GATTC_EVT_WRITE_RSP"".

    The problem is solved if add the following codes.

    static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, const ble_nus_c_evt_t * p_ble_nus_evt)
    {
        uint32_t err_code;
    	static bool is_ready_send_command = false; 
    
        switch (p_ble_nus_evt->evt_type)
    		{
    			case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
    				NRF_LOG_INFO("BLE_NUS_C_EVT_DISCOVERY_COMPLETE \r\n");
    			
    				err_code = ble_nus_c_handles_assign(&m_ble_nus_c[p_ble_nus_evt->conn_handle], p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
                     APP_ERROR_CHECK(err_code);
    				
    				err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
                    APP_ERROR_CHECK(err_code);
    
    			    is_ready_send_command = false; // Added
    			    
    				break;
    			
    			case BLE_NUS_C_EVT_WRITE_RSP:
    				
    				// Added
    				if(is_ready_send_command == false)
    				{
    				    is_ready_send_command = true;
    				    // Send BLE Command here
    				}
    
    				break;

  • Does this mean that the issue is solved, or are you still stuck?

     

    Best regards,

    Edvin

Reply Children
Related