bt_nus_send Failed

I tried to establish communication between the two development boards and the phone. The specific process is as follows: One development board works in slave mode and the other board works in master mode to receive data sent from the slave and forward the received data to the cell phone.

The code for forwarding is as follows:

static uint8_t ble_data_received(struct bt_nus_client *nus,struct bt_conn *conn,
						const uint8_t *data, uint16_t len)
{


	if (bt_nus_send(conn,  data, len)) {
		LOG_WRN("Failed to send data over BLE connection");
	}

	return BT_GATT_ITER_CONTINUE;
}

But the serial debugger will show "Failed to send data over BLE_connection".

Another problem: I'm not quite sure where the "conn" is being assigned. Since this board works as both a slave and a master, I need to know which device the "conn" represents.

Parents
  • Hello,

    So you have one DK acting as a peripheral, and you connect it to two mobile phones acting as centrals, is that the case?

    You figured out that bt_nus_send() returns something other than 0, since you are checking the value. But can you please check what it returns?

    int err;
    
    err = bt_nus_send(conn, data, len);
    
    if (err) {
        LOG_WRN("bt_nus_send() returned %d", err);
    }
    return err;

    Best regards,

    Edvin

  • So you have one DK acting as a peripheral, and you connect it to two mobile phones acting as centrals, is that the case?

    What I mean is that I have two DKs, one only as a slave to the other, and one both as a master to the previous DK and as a slave to the phone.

    But can you please check what it returns?

    I will try it later.

    But what I want to know most is where "conn" is assigned, or which device it represents when a DK is connected to two devices.

Reply
  • So you have one DK acting as a peripheral, and you connect it to two mobile phones acting as centrals, is that the case?

    What I mean is that I have two DKs, one only as a slave to the other, and one both as a master to the previous DK and as a slave to the phone.

    But can you please check what it returns?

    I will try it later.

    But what I want to know most is where "conn" is assigned, or which device it represents when a DK is connected to two devices.

Children
  • The "conn" parameter comes from the connected event. Let us call it a connection handle. You use the connection handles to determine to which connected device you want to send the messages. Since you have two connections, you would need to handle the two different connection handles. You can check in the connected event whether the connection is a central or a peripheral connection, to determine which connection handle that belongs to the phone and which connection handle that belongs to the other DK. 

    You can see in the peirpheral_uart sample in NCS that the bt_receive_cb also has a *conn parameter saying from what connection the callback is coming from. Out of the box this sample only supports one connection, but if you had two connections, this pointer would be the same as you saw in the connected event.

    static void connected(struct bt_conn *conn, uint8_t err)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	if (err) {
    		LOG_ERR("Connection failed (err %u)", err);
    		return;
    	}
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    	LOG_INF("Connected %s", addr);
    
    	current_conn = bt_conn_ref(conn);
    
    	dk_set_led_on(CON_STATUS_LED);
    }

    Best regards,

    Edvin

  • But can you please check what it returns?

    The value of err is -22.

  • Can you provide me with a routine to link two devices in one DK? Thanks a lot!

  • I was wondering if “data” is empty, does that cause “bt_nus_send()” to fail?

  • Hello,

    If bt_nus_send() returns -22, it means EINVAL.

    It probably means that your conn pointer is invalid. Please note how the peripheral_uart sample stores the current_conn pointer in the connected event (and that it invalidates it in the disconnected event). That current_conn parameter is one that you could enter into bt_nus_send().

    Since you want to have two connections, you can check your role in the connected event:

    static void connected(struct bt_conn *conn, uint8_t err)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	if (err) {
    		LOG_ERR("Connection failed (err %u)", err);
    		return;
    	}
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    	LOG_INF("Connected %s", addr);
    
    	current_conn = bt_conn_ref(conn);
    
    	dk_set_led_on(CON_STATUS_LED);
    	
    	if (conn->role == BT_CONN_ROLE_CENTRAL)
    	{
    	    LOG_INF("I am the central in this connection.");
    	}
    	else if (conn_role == BT_CONN_ROLE_PERIPHERAL)
    	{
    	    LOG_INF("I am the peripheral in this connection.");
    	}
    }

    Best regards,

    Edvin

Related