When is NUS ready?

Hi!

We have two similar nRF52840 boards and want them to talk via nus_client and nus_server.

At the moment, we consider connection established after client receives the generic bluetooth connected callback and setups nus (below code).

static void connected(struct bt_conn *conn, uint8_t err) {
    // setup NUS
    static struct bt_gatt_exchange_params exchange_params;
    exchange_params.func = exchange_func;
    bt_gatt_exchange_mtu(conn, &exchange_params);
    bt_conn_set_security(conn, BT_SECURITY_L2);
    gatt_discover(conn);
    bt_scan_stop();


    <send first NUS data>
}

Of course, NUS is not ready at that moment, so the message is lost (without any error being reported), just as any messages sent within the next ~1 second.

Is there a way to register a callback that will notify us when NUS is actually ready?

We are using NCS_VERSION=v2.6.1

(I should note that I came across https://devzone.nordicsemi.com/f/nordic-q-a/28208/when-is-nus-ready, but it seems no longer relevant. If I am mistaken, then how can the mentioned handler registered?)

Parents
  • Hi!

    You can add a callback like this. This will be called when the client have enabled notifications, and you can then start sending notifications.

    static void send_enabled(enum bt_nus_send_status status)
    {
    
    	LOG_INF("Notifications %sabled", (status == BT_NUS_SEND_STATUS_ENABLED) ? "en" : "dis");
    }
    
    static struct bt_nus_cb nus_cb = {
    	.received = bt_receive_cb,
    	.send_enabled = send_enabled,
    };

  • Actually, we are still having problems when sending messages from nus server to nus client.

    static void send_enabled(enum bt_nus_send_status status)
    {
        if (status == BT_NUS_SEND_STATUS_ENABLED) {
            NusServerInitialized = true;
        }
    }
    
    static struct bt_nus_cb nus_cb = {
        .received = received,
        .sent = sent,
        .send_enabled = send_enabled,
    };
    

        while (NusServerInitialized == false) {
            k_sleep(K_MSEC(1));
        }
        for (int i = 0; i < 30; i++) {
            LogBt("=== Ping %i\n", i);
            k_sleep(K_MSEC(50));
        }

    From the very first message, `bt_nus_send(NULL, data, len);` succeeds, we receive the `static void sent(struct bt_conn *conn)` callback with correct address, yet first 8 messages don't arrive on the client.

  • Hi!

    Do you see any difference with`bt_nus_send(current_conn , data, len);` instead?

  • The same.

    (LogBt originally evaluated to `        err = bt_nus_send(NULL, data, len);`, but supplementing it with a connection pointer doesn't make a difference.)

    (Similarly, throwing out the LogBt machinery and sending raw data with `bt_nus_send(conn, data, sizeof(data));` right in the main loop doesn't make a difference.)

    In case you spot something in our logs, here they are:

    server:

    sync:
    I: Initialized
    I: 2 Sectors of 4096 bytes
    I: alloc wra: 0, f38
    I: data wra: 0, 160
    I: SoftDevice Controller build revision:
    I: 36 f0 e5 0e 87 68 48 fb |6....hH.
    I: 02 fd 9f 82 cc 32 e5 7b |.....2.{
    I: 91 b1 5c ed             |..\.
    I: HW Platform: Nordic Semiconductor (0x0002)
    I: HW Variant: nRF52x (0x0002)
    I: Firmware: Standard Bluetooth controller (0x00) Version 54.58864 Build 1214809870
    I: No ID address. App must call settings_load()
    Settings: Found peer 'client' with address 92a4ce1198f0
    I: Identity: E7:60:F0:D9:98:51 (random)
    I: HCI: version 5.4 (0x0d) revision 0x118f, manufacturer 0x0059
    I: LMP: version 5.4 (0x0d) subver 0x118f
    NUS advertising continued
    W: opcode 0x200a status 0x0d
    Connected to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    

    client:

    client$ ATT error code: 0x0E
    Disconnected from server (e7:60:f0:d9:98:51), reason 8
    Start scan
    Client failed to send data over BLE connection (err -128)
    Filters matched: server (e7:60:f0:d9:98:51), connectable:1
    Scan connecting: server (e7:60:f0:d9:98:51)
    Filters matched: server (e7:60:f0:d9:98:51), connectable:0
    Connecting failed: server (e7:60:f0:d9:98:51)
    Connected to server (e7:60:f0:d9:98:51)
    Failed to set security for server (e7:60:f0:d9:98:51): -12
    MTU exchange done with server (e7:60:f0:d9:98:51)
    Service discovery completed
    server: === Ping 11
    server: ---;
    server: === Ping 12
    server: ---<
    server: === Ping 13
    server: ---=
    server: === Ping 14
    server: --->
    server: === Ping 15
    server: ---?
    ...
    
    

    Scenario: server restarts and once nus connection is established, it tries to ping the client. (`---` lines are from a direct raw call to `bt_nus_send(conn, data, sizeof(data))`)

    Current relevant code from server main loop is:

        while (NusServerInitialized == false || RightConn == NULL) {
            k_sleep(K_MSEC(1));
        }
        for (int i = 0; i < 30; i++) {
            LogBt("=== Ping %i\n", i);
            uint8_t data[20] = {
                MessageId_Log,
                '-',
                '-',
                '-',
                '0'+i,
                '\n',
                0
            };
            int err = bt_nus_send(RightConn, data, sizeof(data));
            if (err) {
                printk("Failed to send message (err: %d)\n", err);
            }
            k_sleep(K_MSEC(50));

Reply
  • The same.

    (LogBt originally evaluated to `        err = bt_nus_send(NULL, data, len);`, but supplementing it with a connection pointer doesn't make a difference.)

    (Similarly, throwing out the LogBt machinery and sending raw data with `bt_nus_send(conn, data, sizeof(data));` right in the main loop doesn't make a difference.)

    In case you spot something in our logs, here they are:

    server:

    sync:
    I: Initialized
    I: 2 Sectors of 4096 bytes
    I: alloc wra: 0, f38
    I: data wra: 0, 160
    I: SoftDevice Controller build revision:
    I: 36 f0 e5 0e 87 68 48 fb |6....hH.
    I: 02 fd 9f 82 cc 32 e5 7b |.....2.{
    I: 91 b1 5c ed             |..\.
    I: HW Platform: Nordic Semiconductor (0x0002)
    I: HW Variant: nRF52x (0x0002)
    I: Firmware: Standard Bluetooth controller (0x00) Version 54.58864 Build 1214809870
    I: No ID address. App must call settings_load()
    Settings: Found peer 'client' with address 92a4ce1198f0
    I: Identity: E7:60:F0:D9:98:51 (random)
    I: HCI: version 5.4 (0x0d) revision 0x118f, manufacturer 0x0059
    I: LMP: version 5.4 (0x0d) subver 0x118f
    NUS advertising continued
    W: opcode 0x200a status 0x0d
    Connected to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    NUS data sent to client (f0:98:11:ce:a4:92)
    

    client:

    client$ ATT error code: 0x0E
    Disconnected from server (e7:60:f0:d9:98:51), reason 8
    Start scan
    Client failed to send data over BLE connection (err -128)
    Filters matched: server (e7:60:f0:d9:98:51), connectable:1
    Scan connecting: server (e7:60:f0:d9:98:51)
    Filters matched: server (e7:60:f0:d9:98:51), connectable:0
    Connecting failed: server (e7:60:f0:d9:98:51)
    Connected to server (e7:60:f0:d9:98:51)
    Failed to set security for server (e7:60:f0:d9:98:51): -12
    MTU exchange done with server (e7:60:f0:d9:98:51)
    Service discovery completed
    server: === Ping 11
    server: ---;
    server: === Ping 12
    server: ---<
    server: === Ping 13
    server: ---=
    server: === Ping 14
    server: --->
    server: === Ping 15
    server: ---?
    ...
    
    

    Scenario: server restarts and once nus connection is established, it tries to ping the client. (`---` lines are from a direct raw call to `bt_nus_send(conn, data, sizeof(data))`)

    Current relevant code from server main loop is:

        while (NusServerInitialized == false || RightConn == NULL) {
            k_sleep(K_MSEC(1));
        }
        for (int i = 0; i < 30; i++) {
            LogBt("=== Ping %i\n", i);
            uint8_t data[20] = {
                MessageId_Log,
                '-',
                '-',
                '-',
                '0'+i,
                '\n',
                0
            };
            int err = bt_nus_send(RightConn, data, sizeof(data));
            if (err) {
                printk("Failed to send message (err: %d)\n", err);
            }
            k_sleep(K_MSEC(50));

Children
No Data
Related