NUS bt_nus_send() returns -ENOTCONN (-128) after pairing with nRF Toolbox — client never subscribes to TX notifications (NCS v3.2.4)

Hi,

I am using the Nordic UART Service (NUS) on an nRF52840 with NCS. Without pairing enabled, NUS works perfectly with the nRF Toolbox UART service — both sending and receiving data works as expected. After adding pairing/bonding (Just Works) (CONFIG_BT_NUS_SECURITY_ENABLED), NUS stops working completely:

bt_nus_send() consistently returns -128 (-ENOTCONN) even after 5+ minutes of retries — the peripheral never sees the client subscribe to NUS TX characteristic notifications.
Messages sent from nRF Toolbox to the peripheral are also not being received.
My log shows:

[00:03:41.354,492] <inf> bluetooth: Connected
[00:03:44.490,722] <inf> bluetooth: Security changed: 60:B4:A2:2C:19:ED (public) level 2
[00:03:44.552,490] <inf> bluetooth: Pairing completed: 60:B4:A2:2C:19:ED (public), bonded: 1
[00:04:06.952,972] <dbg> nus: nus_send: No connected client, skipping NUS send
[00:04:06.953,033] <err> telemetry: Failed to send telemetry over NUS: -128
Pairing and bonding complete successfully, but NUS is completely non-functional in both directions after pairing.

My question:

Does nRF Toolbox subscribe to NUS TX notifications and perform GATT service discovery correctly after pairing/bonding completes, or is this a known limitation of the app? Is there something on the peripheral side that needs to be done differently when security is enabled?

Environment:

Hardware: nRF52840
NCS version: 3.2.4
nRF Toolbox version: 4.2.0
CONFIG_BT_SMP=y
CONFIG_BT_ID_UNPAIR_MATCHING_BONDS=y
CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=y
CONFIG_BT_SMP_SC_PAIR_ONLY=n
Any guidance would be appreciated. Thank you.

Parents
  • Update

    Further investigation confirms that the issue originates from the nRF Toolbox app, not the peripheral firmware.

    Diagnostic step

    A send_enabled callback was added to the peripheral’s NUS service to detect when a client writes to the NUS TX CCCD:

    static void on_send_enabled(enum bt_nus_send_status status)
    {
    if (status == BT_NUS_SEND_STATUS_ENABLED) {
    LOG_INF("NUS TX notifications ENABLED by client");
    } else {
    LOG_INF("NUS TX notifications DISABLED by client");
    }
    }

    Result

    After a successful connection, pairing, and bonding sequence, the send_enabled callback is never triggered—even after waiting more than 5 minutes. This indicates that nRF Toolbox (v4.2.0) does not subscribe to NUS TX notifications after pairing.

    Root cause (nRF Toolbox source: UARTManager.kt)

    The app calls .subscribe() on the NUS TX characteristic immediately after service discovery:

    remoteService.characteristics
    .firstOrNull { it.uuid == UART_TX_CHARACTERISTIC_UUID.toKotlinUuid() }
    ?.subscribe()

    With CONFIG_BT_NUS_SECURITY_ENABLED=y, CCCD writes require an encrypted link. If .subscribe() is executed before the security procedure completes, the CCCD write fails silently and is not retried.

    Action taken

    A GitHub issue has been opened in the nordicsemi/Android-nRF-Toolbox repository, including details and a proposed fix:

    Defer subscription until security is established, or
    Retry on CCCD write failure

    GitHub ticket: NUS TX notifications not subscribed after pairing when CONFIG_BT_NUS_SECURITY_ENABLED=y on peripheral · Issue #184 · nordicsemi/Android-nRF-Toolbox

    I’d appreciate any clarification, and hope this can be resolved in a future update.

Reply
  • Update

    Further investigation confirms that the issue originates from the nRF Toolbox app, not the peripheral firmware.

    Diagnostic step

    A send_enabled callback was added to the peripheral’s NUS service to detect when a client writes to the NUS TX CCCD:

    static void on_send_enabled(enum bt_nus_send_status status)
    {
    if (status == BT_NUS_SEND_STATUS_ENABLED) {
    LOG_INF("NUS TX notifications ENABLED by client");
    } else {
    LOG_INF("NUS TX notifications DISABLED by client");
    }
    }

    Result

    After a successful connection, pairing, and bonding sequence, the send_enabled callback is never triggered—even after waiting more than 5 minutes. This indicates that nRF Toolbox (v4.2.0) does not subscribe to NUS TX notifications after pairing.

    Root cause (nRF Toolbox source: UARTManager.kt)

    The app calls .subscribe() on the NUS TX characteristic immediately after service discovery:

    remoteService.characteristics
    .firstOrNull { it.uuid == UART_TX_CHARACTERISTIC_UUID.toKotlinUuid() }
    ?.subscribe()

    With CONFIG_BT_NUS_SECURITY_ENABLED=y, CCCD writes require an encrypted link. If .subscribe() is executed before the security procedure completes, the CCCD write fails silently and is not retried.

    Action taken

    A GitHub issue has been opened in the nordicsemi/Android-nRF-Toolbox repository, including details and a proposed fix:

    Defer subscription until security is established, or
    Retry on CCCD write failure

    GitHub ticket: NUS TX notifications not subscribed after pairing when CONFIG_BT_NUS_SECURITY_ENABLED=y on peripheral · Issue #184 · nordicsemi/Android-nRF-Toolbox

    I’d appreciate any clarification, and hope this can be resolved in a future update.

Children
No Data
Related