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
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
Hello,
How are you testing the UART service? Are you using the original 'peripheral_uart' sample, or are you trying to integrate the service into another project?
Best regards,
Vidar
I have created a new project for testing the NUS service. I found the error is caused by calling smp_bt_register(). Should I add more configuration in prj.conf file?
00> before calling smp_bt_register 00> [00:00:00.000,915] <err> bt_gatt: Unable to register handle 0x0016 00> after calling smp_bt_register
I have created a new project for testing the NUS service. I found the error is caused by calling smp_bt_register(). Should I add more configuration in prj.conf file?
00> before calling smp_bt_register 00> [00:00:00.000,915] <err> bt_gatt: Unable to register handle 0x0016 00> after calling smp_bt_register
/* * * 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().