bt_gatt: Unable to register handle 0x0016 on ncs v2.4.2

I use nRF5340 to test Nordic UART Service. But RTT Viewer the following error messages. What is meaning and how to fix it?

<err> bt_gatt: Unable to register handle 0x0016

Parents Reply Children
  • /*
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #if CONFIG_BT
    
    #include <bluetooth/services/nus.h>
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/direction.h>
    #include <zephyr/bluetooth/conn.h>
    #include <zephyr/bluetooth/gap.h>
    #include <zephyr/bluetooth/gatt.h>
    #include <zephyr/bluetooth/hci.h>
    #include <zephyr/bluetooth/uuid.h>
    #include <zephyr/drivers/uart.h>
    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/mgmt/mcumgr/transport/smp_bt.h>
    #include <zephyr/sys/printk.h>
    #include "battery_timer.h"
    #include "bt_ad.h"
    #include "bt_nus.h"
    #include "bt_thread.h"
    #include "error.h"
    #include "time_cal.h"
    
    #define BT_DEBUG_ENABLED 0
    #define BLE_RX_BLOCK_SIZE              (CONFIG_BT_L2CAP_TX_MTU - 3)
    #define BLE_RX_BUF_COUNT               4
    #define BLE_SLAB_ALIGNMENT             4
    
    LOG_MODULE_REGISTER(bt);
    K_MEM_SLAB_DEFINE(ble_rx_slab, BLE_RX_BLOCK_SIZE, BLE_RX_BUF_COUNT, BLE_SLAB_ALIGNMENT);
    
    static struct bt_conn* _gCurrentConn;
    static struct bt_conn* auth_conn;
    
    #ifdef CONFIG_BT_USER_PHY_UPDATE
    void _btUpdateDataLength(struct bt_conn *conn) {
        int err;
        struct bt_conn_le_data_len_param dataLen = {
            .tx_max_len  = BT_GAP_DATA_LEN_MAX,
            .tx_max_time = BT_GAP_DATA_TIME_MAX,
        };
        err = bt_conn_le_data_len_update(conn, &dataLen);
        if (err) {
            LOG_ERR("bt_conn_le_data_len_update() failed (err %d)", err);
        }
    }
    #endif
    
    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);
        struct bt_conn_info btInfo;
        int ret = bt_conn_get_info(conn, &btInfo);
        if (ret != 0) {
            LOG_ERR("Cannot get conn info %d", ret);
            return;
        }
    
    #if BT_DEBUG_ENABLED
        printk("btInfo.le.interval=%u\n", btInfo.le.interval);
        printk("btInfo.le.latency=%u\n",  btInfo.le.latency);
        printk("btInfo.le.timeout=%u\n",  btInfo.le.timeout);
    #endif
    
        _gCurrentConn = bt_conn_ref(conn);
    
    #if CONFIG_BT_NUS_SECURITY_ENABLED
        ret = bt_conn_set_security(conn, BT_SECURITY_L2);
        if (ret != 0) {
            LOG_ERR("Failed to set security (err %d)\n", ret);
        }
    #endif
    
    #ifdef CONFIG_BT_USER_PHY_UPDATE
        _btUpdateDataLength(conn);
    #endif
    
        const uint32_t mtu = bt_nus_get_mtu(_gCurrentConn);
        btNusSetMtu(mtu);
        LOG_INF("MTU=%u", mtu);
    
        btNusSetState(BT_NUS_STATE_CONNECT);
    
        // creating threads
        btNusThreadCreate();
    
    #if CONFIG_BOARD_AM_NRF52832
        // starting timers
        basTimerStart();
    #endif
    
        LOG_INF("connected");
    }
    
    static void disconnected(struct bt_conn *conn, uint8_t reason) {
        char addr[BT_ADDR_LE_STR_LEN];
        bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
        LOG_INF("disconnected: %s (reason %u)", addr, reason);
        const bt_nus_state_t state = btNusGetState();
        if (state != BT_NUS_STATE_MEASURE) {
            btNusSetState(BT_NUS_STATE_DISCONNECT);
        }
    
        //  aborting threads
        btNusThreadAbort();
    
    #if CONFIG_BOARD_AM_NRF52832
       // stopping timers
        basTimerStop();
    #endif
    
        if (auth_conn) {
            bt_conn_unref(auth_conn);
            auth_conn = NULL;
        }
    
        if (_gCurrentConn) {
            bt_conn_unref(_gCurrentConn);
            _gCurrentConn = NULL;
        }
    
        /* Start advertising */
        btAdvStart();
    }
    
    #if CONFIG_BT_NUS_SECURITY_ENABLED
    static void securityChanged(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) {
        char addr[BT_ADDR_LE_STR_LEN];
    
        bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
        if (!err) {
            LOG_INF("Security changed: %s level %u", addr, level);
        } else {
            LOG_ERR("Security failed: %s level %u err %d", addr, level, err);
        }
    }
    
    static void authCancel(struct bt_conn *conn) {
        char addr[BT_ADDR_LE_STR_LEN];
    
        bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
        LOG_INF("Pairing cancelled: %s", addr);
    }
    
    
    static void pairingComplete(struct bt_conn *conn, bool bonded) {
        char addr[BT_ADDR_LE_STR_LEN];
    
        bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
        LOG_INF("Pairing completed: %s, bonded: %d", addr, bonded);
    }
    
    
    static void pairingFailed(struct bt_conn *conn, enum bt_security_err reason) {
        char addr[BT_ADDR_LE_STR_LEN];
    
        bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
        bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
        LOG_ERR("Pairing failed conn: %s, reason %d", addr, reason);
    }
    
    
    #endif
    
    #ifdef CONFIG_BT_USER_DATA_LEN_UPDATE
    void _leDataLenUpdated(struct bt_conn *conn, struct bt_conn_le_data_len_info *info) {
    #if BT_DEBUG_ENABLED
        uint16_t tx_len     = info->tx_max_len; 
        uint16_t tx_time    = info->tx_max_time;
        uint16_t rx_len     = info->rx_max_len;
        uint16_t rx_time    = info->rx_max_time;
    
        LOG_INF("Data length updated. Length %d/%d bytes, time %d/%d us", tx_len, rx_len, tx_time, rx_time);
    #endif
    }
    #endif
    
    #ifdef CONFIG_BT_USER_PHY_UPDATE
    void _lePhyUpdated(struct bt_conn *conn, struct bt_conn_le_phy_info *param) {
        if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_1M) {
            LOG_INF("PHY updated. New PHY: 1M");
        } else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_2M) {
            LOG_INF("PHY updated. New PHY: 2M");
        } else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_CODED_S8) {
            LOG_INF("PHY updated. New PHY: Long Range");
        }
    }
    #endif
    
    BT_CONN_CB_DEFINE(conn_callbacks) = {
        .connected    = connected,
        .disconnected = disconnected,
    #if CONFIG_BT_NUS_SECURITY_ENABLED
        .security_changed = securityChanged,
    #endif
    #ifdef CONFIG_BT_USER_DATA_LEN_UPDATE
        .le_data_len_updated    = _leDataLenUpdated,
    #endif
    #ifdef CONFIG_BT_USER_PHY_UPDATE
        .le_phy_updated = _lePhyUpdated
    #endif
    
    };
    
    #if CONFIG_BT_NUS_SECURITY_ENABLED
    static struct bt_conn_auth_cb _connAuthCallbacks = {
        .passkey_display = NULL,
        .passkey_confirm = NULL,
        .cancel          = authCancel,
    };
    
    static struct bt_conn_auth_info_cb _connAuthInfoCallbacks = {
        .pairing_complete = pairingComplete,
        .pairing_failed   = pairingFailed
    };
    #endif
    
    
    static void _btReady(const int err) {
        if (err) {
            LOG_ERR("Bluetooth init failed (err %d)", err);
            return;
        }
    
        LOG_INF("Bluetooth initialized");
    
        const int ret = btNusInit();
        if (ret < 0) {
            LOG_ERR("btNusInit() failed, err=0x%x\n", ret);
            return;
        }
        
        /* Start advertising */
        btAdvStart();
    }
    
    int btInit(void) {
        int ret;
    
    #if CONFIG_BOOTLOADER_MCUBOOT
        printk("before calling smp_bt_register\n");
        smp_bt_register();
        printk("after calling smp_bt_register\n");
    #endif
    
    #if CONFIG_BT_NUS_SECURITY_ENABLED
        {
            ret = bt_conn_auth_cb_register(&_connAuthCallbacks);
            if (ret != 0) {
                LOG_ERR("Failed to register authorization callbacks.\n");
                return ERROR_BT_INITIALIZE_FAIL;
            }
    
            ret = bt_conn_auth_info_cb_register(&_connAuthInfoCallbacks);
            if (ret != 0) {
                LOG_ERR("Failed to register authorization info callbacks.\n");
                return ERROR_BT_INITIALIZE_FAIL;
            }
        }
    #endif
    
        ret = bt_enable(_btReady);
        if (ret != 0) {
            LOG_ERR("Bluetooth init failed (err 0x%x)\n", ret);
            return ERROR_BT_INITIALIZE_FAIL;
        }
    
        return 0;
    }
    
    struct bt_conn* btGetConnectHandle(void) {
        return _gCurrentConn;
    }
    
    #endif

  • The function smp_bt_register() runs automatically on startup when CONFIG_MCUMGR_TRANSPORT_BT is enabled. Therefore, you should remove your call to this function in main().

  • Thanks for your great support! This issue has been fixed after removing calling smp_bt_register().

Related