<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>NUS central device return bt_hci_core: opcode 0x1405 status 0x02</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/118597/nus-central-device-return-bt_hci_core-opcode-0x1405-status-0x02</link><description>Hi 
 I have two nRF52833 development boards: one is using BLE peripheral_uart, and the other is used as RX (BLE central_uart). My issue is that, with the TX setup being completely identical, when I use ble_app_uart_c from the nRF5 SDK, it correctly receives</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 10 Feb 2025 14:05:44 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/118597/nus-central-device-return-bt_hci_core-opcode-0x1405-status-0x02" /><item><title>RE: NUS central device return bt_hci_core: opcode 0x1405 status 0x02</title><link>https://devzone.nordicsemi.com/thread/522222?ContentTypeID=1</link><pubDate>Mon, 10 Feb 2025 14:05:44 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e70d2ba8-7296-47ae-9459-6da6d2d37200</guid><dc:creator>Ziyao Zhou</dc:creator><description>&lt;p&gt;Thank you so much! I have sloved this issue!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NUS central device return bt_hci_core: opcode 0x1405 status 0x02</title><link>https://devzone.nordicsemi.com/thread/522133?ContentTypeID=1</link><pubDate>Mon, 10 Feb 2025 08:22:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:56e9171c-e2f1-415a-abd4-4773120279fd</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;This code does not even regularily check the RSSI (though you have code in place for it), so I suggest you back-track a bit. For reference, this is the full main.c file I tested which is your previous uploaded main.c with minor modifications. You should be able to run that and see that it works:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

/** @file
 *  @brief Nordic UART Service Client sample
 */

#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;zephyr/kernel.h&amp;gt;
#include &amp;lt;zephyr/device.h&amp;gt;
#include &amp;lt;zephyr/devicetree.h&amp;gt;
#include &amp;lt;zephyr/sys/byteorder.h&amp;gt;
#include &amp;lt;zephyr/sys/printk.h&amp;gt;

#include &amp;lt;zephyr/bluetooth/bluetooth.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/hci.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/conn.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/uuid.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/gatt.h&amp;gt;

#include &amp;lt;bluetooth/services/nus.h&amp;gt;
#include &amp;lt;bluetooth/services/nus_client.h&amp;gt;
#include &amp;lt;bluetooth/gatt_dm.h&amp;gt;
#include &amp;lt;bluetooth/scan.h&amp;gt;

#include &amp;lt;zephyr/settings/settings.h&amp;gt;

#include &amp;lt;zephyr/drivers/uart.h&amp;gt;

#include &amp;lt;zephyr/logging/log.h&amp;gt;

#include &amp;lt;zephyr/bluetooth/hci.h&amp;gt;


#define LOG_MODULE_NAME central_uart
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

/* UART payload buffer element size. */
#define UART_BUF_SIZE 45

#define KEY_PASSKEY_ACCEPT DK_BTN1_MSK
#define KEY_PASSKEY_REJECT DK_BTN2_MSK

#define NUS_WRITE_TIMEOUT K_MSEC(150)
#define UART_WAIT_FOR_BUF_DELAY K_MSEC(50)
#define UART_RX_TIMEOUT 50000 /* Wait for RX complete event time in microseconds. */

static const struct device *uart = DEVICE_DT_GET(DT_CHOSEN(nordic_nus_uart));
static struct k_work_delayable uart_work;

K_SEM_DEFINE(nus_write_sem, 0, 1);

struct uart_data_t {
	void *fifo_reserved;
	uint8_t  data[UART_BUF_SIZE];
	uint16_t len;
};

static K_FIFO_DEFINE(fifo_uart_tx_data);
static K_FIFO_DEFINE(fifo_uart_rx_data);

static struct bt_conn *default_conn;
static struct bt_nus_client nus_client;







static char last_received_data[UART_BUF_SIZE] = {0};
static uint16_t last_received_data_len = 0;
static struct k_work_delayable rssi_work;

// static void rssi_work_handler(struct k_work *work)
// {
//     struct bt_conn_info info;
//     struct net_buf *buf = NULL, *rsp = NULL;
//     struct bt_hci_cp_read_rssi *cp;
//     struct bt_hci_rp_read_rssi *rp;
//     int err;
	
// 	if (default_conn) {
//         struct bt_conn_info info;
//         int err;

//         // 获取当前连接信息
//         err = bt_conn_get_info(default_conn, &amp;amp;info);
//         if (err) {
//             LOG_ERR(&amp;quot;Failed to get connection info (err %d)&amp;quot;, err);
//             return;
//         }

//         // 创建HCI命令缓冲区以读取RSSI
//         struct net_buf *buf = bt_hci_cmd_create(BT_HCI_OP_READ_RSSI, sizeof(uint16_t));
//         if (!buf) {
//             LOG_ERR(&amp;quot;Failed to create HCI command buffer&amp;quot;);
//             return;
//         }

//         // 填充HCI命令
//         struct bt_hci_cp_read_rssi *cp = net_buf_add(buf, sizeof(*cp));
//         cp-&amp;gt;handle = sys_cpu_to_le16(info.id);

//         // 发送命令并解析响应
//         struct net_buf *rsp;
//         err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_RSSI, buf, &amp;amp;rsp);
//         if (err) {
//             LOG_ERR(&amp;quot;Failed to read RSSI (err %d)&amp;quot;, err);
//             return;
//         }

//         struct bt_hci_rp_read_rssi *rp = (void *)rsp-&amp;gt;data;
//         LOG_INF(&amp;quot;RSSI: %d dBm&amp;quot;, rp-&amp;gt;rssi);
// 		LOG_INF(&amp;quot;Data received: %.*s&amp;quot;, last_received_data_len, last_received_data);

//         net_buf_unref(rsp);
//     }

//     // 调度下一次任务
//     k_work_reschedule(&amp;amp;rssi_work, K_SECONDS(1));  // 每秒读取一次RSSI
// }
static void rssi_work_handler(struct k_work *work)
{
    uint16_t conn_handle;
    struct net_buf *buf = NULL, *rsp = NULL;
    struct bt_hci_cp_read_rssi *cp;
    struct bt_hci_rp_read_rssi *rp;
    int err;

    if (!default_conn) {
        LOG_ERR(&amp;quot;No default connection available&amp;quot;);
        goto schedule;
    }

    err = bt_hci_get_conn_handle(default_conn, &amp;amp;conn_handle);
    if (err) {
        printk(&amp;quot;Failed obtaining conn_handle (err %d)\n&amp;quot;, err);
    }

    /* 创建 HCI 命令缓冲区以读取 RSSI */
    buf = bt_hci_cmd_create(BT_HCI_OP_READ_RSSI, sizeof(*cp));
    if (!buf) {
        LOG_ERR(&amp;quot;Unable to allocate HCI command buffer&amp;quot;);
        goto schedule;
    }

    /* 填充 HCI 命令数据（使用连接标识 info.id 作为句柄） */
    cp = net_buf_add(buf, sizeof(*cp));
    cp-&amp;gt;handle = sys_cpu_to_le16(conn_handle);

    /* 发送 HCI 命令并等待同步响应 */
    err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_RSSI, buf, &amp;amp;rsp);
    if (err) {
        LOG_ERR(&amp;quot;Read RSSI error: %d&amp;quot;, err);
        goto schedule;
    }

    /* 解析并打印 RSSI 数据 */
    rp = (void *)rsp-&amp;gt;data;
    LOG_INF(&amp;quot;RSSI: %d dBm&amp;quot;, rp-&amp;gt;rssi);
	LOG_INF(&amp;quot;Data received: %.*s&amp;quot;, last_received_data_len, last_received_data);

    net_buf_unref(rsp);

schedule:
    /* 调度下一次任务：每秒读取一次 RSSI */
    k_work_reschedule(&amp;amp;rssi_work, K_SECONDS(1));
}









static void ble_data_sent(struct bt_nus_client *nus, uint8_t err,
					const uint8_t *const data, uint16_t len)
{
	ARG_UNUSED(nus);
	ARG_UNUSED(data);
	ARG_UNUSED(len);

	k_sem_give(&amp;amp;nus_write_sem);

	if (err) {
		LOG_WRN(&amp;quot;ATT error code: 0x%02X&amp;quot;, err);
	}
}

// static uint8_t ble_data_received(struct bt_nus_client *nus,
// 						const uint8_t *data, uint16_t len)
// {
// 	ARG_UNUSED(nus);

// 	int err;

// 	for (uint16_t pos = 0; pos != len;) {
// 		struct uart_data_t *tx = k_malloc(sizeof(*tx));

// 		if (!tx) {
// 			LOG_WRN(&amp;quot;Not able to allocate UART send data buffer&amp;quot;);
// 			return BT_GATT_ITER_CONTINUE;
// 		}

// 		/* Keep the last byte of TX buffer for potential LF char. */
// 		size_t tx_data_size = sizeof(tx-&amp;gt;data) - 1;

// 		if ((len - pos) &amp;gt; tx_data_size) {
// 			tx-&amp;gt;len = tx_data_size;
// 		} else {
// 			tx-&amp;gt;len = (len - pos);
// 		}

// 		memcpy(tx-&amp;gt;data, &amp;amp;data[pos], tx-&amp;gt;len);

// 		pos += tx-&amp;gt;len;

// 		/* Append the LF character when the CR character triggered
// 		 * transmission from the peer.
// 		 */
// 		if ((pos == len) &amp;amp;&amp;amp; (data[len - 1] == &amp;#39;\r&amp;#39;)) {
// 			tx-&amp;gt;data[tx-&amp;gt;len] = &amp;#39;\n&amp;#39;;
// 			tx-&amp;gt;len++;
// 		}

// 		err = uart_tx(uart, tx-&amp;gt;data, tx-&amp;gt;len, SYS_FOREVER_MS);
// 		if (err) {
// 			k_fifo_put(&amp;amp;fifo_uart_tx_data, tx);
// 		}
// 	}

// 	return BT_GATT_ITER_CONTINUE;
// }






static uint8_t ble_data_received(struct bt_nus_client *nus,
                                 const uint8_t *data, uint16_t len)
{
    ARG_UNUSED(nus);

    // 保存接收到的数据
    memset(last_received_data, 0, sizeof(last_received_data));
    last_received_data_len = len &amp;lt; UART_BUF_SIZE ? len : UART_BUF_SIZE - 1;
    memcpy(last_received_data, data, last_received_data_len);

    //LOG_INF(&amp;quot;Data received: %.*s&amp;quot;, last_received_data_len, last_received_data);

    return BT_GATT_ITER_CONTINUE;
}









static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
	ARG_UNUSED(dev);

	static size_t aborted_len;
	struct uart_data_t *buf;
	static uint8_t *aborted_buf;
	static bool disable_req;

	switch (evt-&amp;gt;type) {
	case UART_TX_DONE:
		LOG_DBG(&amp;quot;UART_TX_DONE&amp;quot;);
		if ((evt-&amp;gt;data.tx.len == 0) ||
		    (!evt-&amp;gt;data.tx.buf)) {
			return;
		}

		if (aborted_buf) {
			buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
					   data[0]);
			aborted_buf = NULL;
			aborted_len = 0;
		} else {
			buf = CONTAINER_OF(evt-&amp;gt;data.tx.buf,
					   struct uart_data_t,
					   data[0]);
		}

		k_free(buf);

		buf = k_fifo_get(&amp;amp;fifo_uart_tx_data, K_NO_WAIT);
		if (!buf) {
			return;
		}

		if (uart_tx(uart, buf-&amp;gt;data, buf-&amp;gt;len, SYS_FOREVER_MS)) {
			LOG_WRN(&amp;quot;Failed to send data over UART&amp;quot;);
		}

		break;

	case UART_RX_RDY:
		LOG_DBG(&amp;quot;UART_RX_RDY&amp;quot;);
		buf = CONTAINER_OF(evt-&amp;gt;data.rx.buf, struct uart_data_t, data[0]);
		buf-&amp;gt;len += evt-&amp;gt;data.rx.len;

		if (disable_req) {
			return;
		}

		if ((evt-&amp;gt;data.rx.buf[buf-&amp;gt;len - 1] == &amp;#39;\n&amp;#39;) ||
		    (evt-&amp;gt;data.rx.buf[buf-&amp;gt;len - 1] == &amp;#39;\r&amp;#39;)) {
			disable_req = true;
			uart_rx_disable(uart);
		}

		break;

	case UART_RX_DISABLED:
		LOG_DBG(&amp;quot;UART_RX_DISABLED&amp;quot;);
		disable_req = false;

		buf = k_malloc(sizeof(*buf));
		if (buf) {
			buf-&amp;gt;len = 0;
		} else {
			LOG_WRN(&amp;quot;Not able to allocate UART receive buffer&amp;quot;);
			k_work_reschedule(&amp;amp;uart_work, UART_WAIT_FOR_BUF_DELAY);
			return;
		}

		uart_rx_enable(uart, buf-&amp;gt;data, sizeof(buf-&amp;gt;data),
			       UART_RX_TIMEOUT);

		break;

	case UART_RX_BUF_REQUEST:
		LOG_DBG(&amp;quot;UART_RX_BUF_REQUEST&amp;quot;);
		buf = k_malloc(sizeof(*buf));
		if (buf) {
			buf-&amp;gt;len = 0;
			uart_rx_buf_rsp(uart, buf-&amp;gt;data, sizeof(buf-&amp;gt;data));
		} else {
			LOG_WRN(&amp;quot;Not able to allocate UART receive buffer&amp;quot;);
		}

		break;

	case UART_RX_BUF_RELEASED:
		LOG_DBG(&amp;quot;UART_RX_BUF_RELEASED&amp;quot;);
		buf = CONTAINER_OF(evt-&amp;gt;data.rx_buf.buf, struct uart_data_t,
				   data[0]);

		if (buf-&amp;gt;len &amp;gt; 0) {
			k_fifo_put(&amp;amp;fifo_uart_rx_data, buf);
		} else {
			k_free(buf);
		}

		break;

	case UART_TX_ABORTED:
		LOG_DBG(&amp;quot;UART_TX_ABORTED&amp;quot;);
		if (!aborted_buf) {
			aborted_buf = (uint8_t *)evt-&amp;gt;data.tx.buf;
		}

		aborted_len += evt-&amp;gt;data.tx.len;
		buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
				   data[0]);

		uart_tx(uart, &amp;amp;buf-&amp;gt;data[aborted_len],
			buf-&amp;gt;len - aborted_len, SYS_FOREVER_MS);

		break;

	default:
		break;
	}
}

static void uart_work_handler(struct k_work *item)
{
	struct uart_data_t *buf;

	buf = k_malloc(sizeof(*buf));
	if (buf) {
		buf-&amp;gt;len = 0;
	} else {
		LOG_WRN(&amp;quot;Not able to allocate UART receive buffer&amp;quot;);
		k_work_reschedule(&amp;amp;uart_work, UART_WAIT_FOR_BUF_DELAY);
		return;
	}

	uart_rx_enable(uart, buf-&amp;gt;data, sizeof(buf-&amp;gt;data), UART_RX_TIMEOUT);
}

static int uart_init(void)
{
	int err;
	struct uart_data_t *rx;

	if (!device_is_ready(uart)) {
		LOG_ERR(&amp;quot;UART device not ready&amp;quot;);
		return -ENODEV;
	}

	rx = k_malloc(sizeof(*rx));
	if (rx) {
		rx-&amp;gt;len = 0;
	} else {
		return -ENOMEM;
	}

	k_work_init_delayable(&amp;amp;uart_work, uart_work_handler);

	err = uart_callback_set(uart, uart_cb, NULL);
	if (err) {
		return err;
	}

	return uart_rx_enable(uart, rx-&amp;gt;data, sizeof(rx-&amp;gt;data),
			      UART_RX_TIMEOUT);
}

static void discovery_complete(struct bt_gatt_dm *dm,
			       void *context)
{
	struct bt_nus_client *nus = context;
	LOG_INF(&amp;quot;Service discovery completed&amp;quot;);

	bt_gatt_dm_data_print(dm);

	bt_nus_handles_assign(dm, nus);
	bt_nus_subscribe_receive(nus);

	bt_gatt_dm_data_release(dm);
}

static void discovery_service_not_found(struct bt_conn *conn,
					void *context)
{
	LOG_INF(&amp;quot;Service not found&amp;quot;);
}

static void discovery_error(struct bt_conn *conn,
			    int err,
			    void *context)
{
	LOG_WRN(&amp;quot;Error while discovering GATT database: (%d)&amp;quot;, err);
}

struct bt_gatt_dm_cb discovery_cb = {
	.completed         = discovery_complete,
	.service_not_found = discovery_service_not_found,
	.error_found       = discovery_error,
};

static void gatt_discover(struct bt_conn *conn)
{
	int err;

	if (conn != default_conn) {
		return;
	}

	err = bt_gatt_dm_start(conn,
			       BT_UUID_NUS_SERVICE,
			       &amp;amp;discovery_cb,
			       &amp;amp;nus_client);
	if (err) {
		LOG_ERR(&amp;quot;could not start the discovery procedure, error &amp;quot;
			&amp;quot;code: %d&amp;quot;, err);
	}
}

static void exchange_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_exchange_params *params)
{
	if (!err) {
		LOG_INF(&amp;quot;MTU exchange done&amp;quot;);
	} else {
		LOG_WRN(&amp;quot;MTU exchange failed (err %&amp;quot; PRIu8 &amp;quot;)&amp;quot;, err);
	}
}

static void connected(struct bt_conn *conn, uint8_t conn_err)
{
	char addr[BT_ADDR_LE_STR_LEN];
	int err;

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	if (conn_err) {
		LOG_INF(&amp;quot;Failed to connect to %s, 0x%02x %s&amp;quot;, addr, conn_err,
			bt_hci_err_to_str(conn_err));

		if (default_conn == conn) {
			bt_conn_unref(default_conn);
			default_conn = NULL;

			err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
			if (err) {
				LOG_ERR(&amp;quot;Scanning failed to start (err %d)&amp;quot;,
					err);
			}
		}

		return;
	}

	LOG_INF(&amp;quot;Connected: %s&amp;quot;, addr);

	static struct bt_gatt_exchange_params exchange_params;

	exchange_params.func = exchange_func;
	err = bt_gatt_exchange_mtu(conn, &amp;amp;exchange_params);
	if (err) {
		LOG_WRN(&amp;quot;MTU exchange failed (err %d)&amp;quot;, err);
	}

	err = bt_conn_set_security(conn, BT_SECURITY_L2);
	if (err) {
		LOG_WRN(&amp;quot;Failed to set security: %d&amp;quot;, err);

		gatt_discover(conn);
	}

	err = bt_scan_stop();
	if ((!err) &amp;amp;&amp;amp; (err != -EALREADY)) {
		LOG_ERR(&amp;quot;Stop LE scan failed (err %d)&amp;quot;, err);
	}

	// 启动任务
    k_work_schedule(&amp;amp;rssi_work, K_NO_WAIT);
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	k_work_cancel_delayable(&amp;amp;rssi_work);  // 取消RSSI任务

	char addr[BT_ADDR_LE_STR_LEN];
	int err;

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	LOG_INF(&amp;quot;Disconnected: %s, reason 0x%02x %s&amp;quot;, addr, reason, bt_hci_err_to_str(reason));
	


	if (default_conn != conn) {
		return;
	}

	bt_conn_unref(default_conn);
	default_conn = NULL;



	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
	if (err) {
		LOG_ERR(&amp;quot;Scanning failed to start (err %d)&amp;quot;,
			err);
	}

}

static void security_changed(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(&amp;quot;Security changed: %s level %u&amp;quot;, addr, level);
	} else {
		LOG_WRN(&amp;quot;Security failed: %s level %u err %d %s&amp;quot;, addr, level, err,
			bt_security_err_to_str(err));
			
	}

	gatt_discover(conn);
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = connected,
	.disconnected = disconnected,
	.security_changed = security_changed
};

static void scan_filter_match(struct bt_scan_device_info *device_info,
			      struct bt_scan_filter_match *filter_match,
			      bool connectable)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(device_info-&amp;gt;recv_info-&amp;gt;addr, addr, sizeof(addr));

	LOG_INF(&amp;quot;Filters matched. Address: %s connectable: %d&amp;quot;,
		addr, connectable);

		
}

static void scan_connecting_error(struct bt_scan_device_info *device_info)
{
	LOG_WRN(&amp;quot;Connecting failed&amp;quot;);
}

static void scan_connecting(struct bt_scan_device_info *device_info,
			    struct bt_conn *conn)
{
	default_conn = bt_conn_ref(conn);
}

static int nus_client_init(void)
{
	int err;
	struct bt_nus_client_init_param init = {
		.cb = {
			.received = ble_data_received,
			.sent = ble_data_sent,
		}
	};

	err = bt_nus_client_init(&amp;amp;nus_client, &amp;amp;init);
	if (err) {
		LOG_ERR(&amp;quot;NUS Client initialization failed (err %d)&amp;quot;, err);
		return err;
	}

	LOG_INF(&amp;quot;NUS Client module initialized&amp;quot;);
	return err;
}

BT_SCAN_CB_INIT(scan_cb, scan_filter_match, NULL,
		scan_connecting_error, scan_connecting);

static int scan_init(void)
{
	int err;
	struct bt_scan_init_param scan_init = {
		.connect_if_match = 1,
	};

	bt_scan_init(&amp;amp;scan_init);
	bt_scan_cb_register(&amp;amp;scan_cb);

	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, BT_UUID_NUS_SERVICE);
	if (err) {
		LOG_ERR(&amp;quot;Scanning filters cannot be set (err %d)&amp;quot;, err);
		return err;
	}

	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, &amp;quot;Dynamic test beacon&amp;quot;); // 替换为目标设备的名称
    if (err) {
        LOG_ERR(&amp;quot;Failed to set name filter (err %d)&amp;quot;, err);
        return err;
    }

	err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER|BT_SCAN_NAME_FILTER, false);
	if (err) {
		LOG_ERR(&amp;quot;Filters cannot be turned on (err %d)&amp;quot;, err);
		return err;
	}

	LOG_INF(&amp;quot;Scan module initialized&amp;quot;);
	return err;
}


static void auth_cancel(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(&amp;quot;Pairing cancelled: %s&amp;quot;, addr);
}


static void pairing_complete(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(&amp;quot;Pairing completed: %s, bonded: %d&amp;quot;, addr, bonded);
}


static void pairing_failed(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));

	LOG_WRN(&amp;quot;Pairing failed conn: %s, reason %d %s&amp;quot;, addr, reason,
		bt_security_err_to_str(reason));
}

static struct bt_conn_auth_cb conn_auth_callbacks = {
	.cancel = auth_cancel,
};

static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
	.pairing_complete = pairing_complete,
	.pairing_failed = pairing_failed
};

int main(void)
{
	int err;

	 k_work_init_delayable(&amp;amp;rssi_work, rssi_work_handler);

	err = bt_conn_auth_cb_register(&amp;amp;conn_auth_callbacks);
	if (err) {
		LOG_ERR(&amp;quot;Failed to register authorization callbacks.&amp;quot;);
		return 0;
	}

	err = bt_conn_auth_info_cb_register(&amp;amp;conn_auth_info_callbacks);
	if (err) {
		printk(&amp;quot;Failed to register authorization info callbacks.\n&amp;quot;);
		return 0;
	}

	err = bt_enable(NULL);
	if (err) {
		LOG_ERR(&amp;quot;Bluetooth init failed (err %d)&amp;quot;, err);
		return 0;
	}
	LOG_INF(&amp;quot;Bluetooth initialized&amp;quot;);



	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();
	}

	err = uart_init();
	if (err != 0) {
		LOG_ERR(&amp;quot;uart_init failed (err %d)&amp;quot;, err);
		return 0;
	}

	err = scan_init();
	if (err != 0) {
		LOG_ERR(&amp;quot;scan_init failed (err %d)&amp;quot;, err);
		return 0;
	}

	err = nus_client_init();
	if (err != 0) {
		LOG_ERR(&amp;quot;nus_client_init failed (err %d)&amp;quot;, err);
		return 0;
	}

	printk(&amp;quot;Starting Bluetooth Central UART example\n&amp;quot;);

	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
	if (err) {
		LOG_ERR(&amp;quot;Scanning failed to start (err %d)&amp;quot;, err);
		return 0;
	}

	LOG_INF(&amp;quot;Scanning successfully started&amp;quot;);

	struct uart_data_t nus_data = {
		.len = 0,
	};

	for (;;) {
		/* Wait indefinitely for data to be sent over Bluetooth */
		struct uart_data_t *buf = k_fifo_get(&amp;amp;fifo_uart_rx_data,
						     K_FOREVER);

		int plen = MIN(sizeof(nus_data.data) - nus_data.len, buf-&amp;gt;len);
		int loc = 0;

		while (plen &amp;gt; 0) {
			memcpy(&amp;amp;nus_data.data[nus_data.len], &amp;amp;buf-&amp;gt;data[loc], plen);
			nus_data.len += plen;
			loc += plen;
			if (nus_data.len &amp;gt;= sizeof(nus_data.data) ||
			   (nus_data.data[nus_data.len - 1] == &amp;#39;\n&amp;#39;) ||
			   (nus_data.data[nus_data.len - 1] == &amp;#39;\r&amp;#39;)) {
				err = bt_nus_client_send(&amp;amp;nus_client, nus_data.data, nus_data.len);
				if (err) {
					LOG_WRN(&amp;quot;Failed to send data over BLE connection&amp;quot;
						&amp;quot;(err %d)&amp;quot;, err);
				}

				err = k_sem_take(&amp;amp;nus_write_sem, NUS_WRITE_TIMEOUT);
				if (err) {
					LOG_WRN(&amp;quot;NUS send timeout&amp;quot;);
				}

				nus_data.len = 0;
			}

			plen = MIN(sizeof(nus_data.data), buf-&amp;gt;len - loc);
		}

		k_free(buf);
	}
}
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NUS central device return bt_hci_core: opcode 0x1405 status 0x02</title><link>https://devzone.nordicsemi.com/thread/522070?ContentTypeID=1</link><pubDate>Sat, 08 Feb 2025 01:51:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:79be7f22-bac5-4afd-a2db-2dac0da97170</guid><dc:creator>Ziyao Zhou</dc:creator><description>&lt;p&gt;Hi, thank you so much for your information. However, after I change me code into yours, the problem still happen. And I try to delete this&amp;nbsp;rssi_work_handler function and keep my code like this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

/** @file
 *  @brief Nordic UART Service Client sample
 */

#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;zephyr/kernel.h&amp;gt;
#include &amp;lt;zephyr/device.h&amp;gt;
#include &amp;lt;zephyr/devicetree.h&amp;gt;
#include &amp;lt;zephyr/sys/byteorder.h&amp;gt;
#include &amp;lt;zephyr/sys/printk.h&amp;gt;

#include &amp;lt;zephyr/bluetooth/bluetooth.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/hci.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/hci_vs.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/conn.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/uuid.h&amp;gt;
#include &amp;lt;zephyr/bluetooth/gatt.h&amp;gt;

#include &amp;lt;bluetooth/services/nus.h&amp;gt;
#include &amp;lt;bluetooth/services/nus_client.h&amp;gt;
#include &amp;lt;bluetooth/gatt_dm.h&amp;gt;
#include &amp;lt;bluetooth/scan.h&amp;gt;

#include &amp;lt;zephyr/settings/settings.h&amp;gt;

#include &amp;lt;zephyr/drivers/uart.h&amp;gt;

#include &amp;lt;zephyr/logging/log.h&amp;gt;

#include &amp;lt;zephyr/bluetooth/hci.h&amp;gt;

#include &amp;quot;pid.h&amp;quot; // 确保pid.h在项目中


#define LOG_MODULE_NAME central_uart
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

/* UART payload buffer element size. */
#define UART_BUF_SIZE 45

#define KEY_PASSKEY_ACCEPT DK_BTN1_MSK
#define KEY_PASSKEY_REJECT DK_BTN2_MSK

#define NUS_WRITE_TIMEOUT K_MSEC(150)
#define UART_WAIT_FOR_BUF_DELAY K_MSEC(50)
#define UART_RX_TIMEOUT 50000 /* Wait for RX complete event time in microseconds. */

static const struct device *uart = DEVICE_DT_GET(DT_CHOSEN(nordic_nus_uart));
static struct k_work_delayable uart_work;

K_SEM_DEFINE(nus_write_sem, 0, 1);

struct uart_data_t {
	void *fifo_reserved;
	uint8_t  data[UART_BUF_SIZE];
	uint16_t len;
};

static K_FIFO_DEFINE(fifo_uart_tx_data);
static K_FIFO_DEFINE(fifo_uart_rx_data);

static struct bt_conn *default_conn;
static struct bt_nus_client nus_client;
static uint16_t default_conn_handle;






static char last_received_data[UART_BUF_SIZE] = {0};
static uint16_t last_received_data_len = 0;
static struct k_work_delayable rssi_work;


// PID参数
static struct k_thread pwr_thread_data;
static K_THREAD_STACK_DEFINE(pwr_thread_stack, 512);
#define DEVICE_BEACON_TXPOWER_NUM 8
static const int8_t txpower[DEVICE_BEACON_TXPOWER_NUM] = {4, 0, -3, -8,
							  -15, -18, -23, -30};
#define TX_POWER_MAX   8   // 根据设备能力调整
#define TX_POWER_MIN -30
#define RSSI_TARGET  -40.0f // 目标RSSI值







static void read_conn_rssi(uint16_t handle, int8_t *rssi)
{
	struct net_buf *buf, *rsp = NULL;
	struct bt_hci_cp_read_rssi *cp;
	struct bt_hci_rp_read_rssi *rp;

	int err;

	buf = bt_hci_cmd_create(BT_HCI_OP_READ_RSSI, sizeof(*cp));
	if (!buf) {
		printk(&amp;quot;Unable to allocate command buffer\n&amp;quot;);
		return;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp-&amp;gt;handle = sys_cpu_to_le16(handle);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_RSSI, buf, &amp;amp;rsp);
	if (err) {
		printk(&amp;quot;Read RSSI err: %d\n&amp;quot;, err);
		return;
	}

	rp = (void *)rsp-&amp;gt;data;
	*rssi = rp-&amp;gt;rssi;

	net_buf_unref(rsp);
}


static void set_tx_power(uint8_t handle_type, uint16_t handle, int8_t tx_pwr_lvl)
{
	struct bt_hci_cp_vs_write_tx_power_level *cp;
	struct bt_hci_rp_vs_write_tx_power_level *rp;
	struct net_buf *buf, *rsp = NULL;
	int err;

	buf = bt_hci_cmd_create(BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL,
				sizeof(*cp));
	if (!buf) {
		printk(&amp;quot;Unable to allocate command buffer\n&amp;quot;);
		return;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp-&amp;gt;handle = sys_cpu_to_le16(handle);
	cp-&amp;gt;handle_type = handle_type;
	cp-&amp;gt;tx_power_level = tx_pwr_lvl;

	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL,
				   buf, &amp;amp;rsp);
	if (err) {
		printk(&amp;quot;Set Tx power err: %d\n&amp;quot;, err);
		return;
	}

	rp = (void *)rsp-&amp;gt;data;
	printk(&amp;quot;Actual Tx Power: %d\n&amp;quot;, rp-&amp;gt;selected_tx_power);

	net_buf_unref(rsp);
}

static void get_tx_power(uint8_t handle_type, uint16_t handle, int8_t *tx_pwr_lvl)
{
	struct bt_hci_cp_vs_read_tx_power_level *cp;
	struct bt_hci_rp_vs_read_tx_power_level *rp;
	struct net_buf *buf, *rsp = NULL;
	int err;

	*tx_pwr_lvl = 0xFF;
	buf = bt_hci_cmd_create(BT_HCI_OP_VS_READ_TX_POWER_LEVEL,
				sizeof(*cp));
	if (!buf) {
		printk(&amp;quot;Unable to allocate command buffer\n&amp;quot;);
		return;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp-&amp;gt;handle = sys_cpu_to_le16(handle);
	cp-&amp;gt;handle_type = handle_type;

	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_TX_POWER_LEVEL,
				   buf, &amp;amp;rsp);
	if (err) {
		printk(&amp;quot;Read Tx power err: %d\n&amp;quot;, err);
		return;
	}

	rp = (void *)rsp-&amp;gt;data;
	*tx_pwr_lvl = rp-&amp;gt;tx_power_level;

	net_buf_unref(rsp);
}







void modulate_tx_power(void *p1, void *p2, void *p3)
{


	while (1) {

	int err;
	int8_t rssi = 0xFF;
	read_conn_rssi(default_conn_handle, &amp;amp;rssi);
	printk(&amp;quot;RSSI: %d dBm\n&amp;quot;, rssi);
	 err = bt_nus_client_send(&amp;amp;nus_client, (uint8_t *)&amp;amp;rssi, sizeof(rssi));
        if (err) {
      LOG_WRN(&amp;quot;bt_nus_client_send failed (err %d)&amp;quot;, err);}

	k_sleep(K_MSEC(100));}
}


















// static void rssi_work_handler(struct k_work *work)
// {
//     uint16_t conn_handle;
//     struct net_buf *buf = NULL, *rsp = NULL;
//     struct bt_hci_cp_read_rssi *cp;
//     struct bt_hci_rp_read_rssi *rp;
//     int err;

//     if (!default_conn) {
//         LOG_ERR(&amp;quot;No default connection available&amp;quot;);
//         goto schedule;
//     }

//     err = bt_hci_get_conn_handle(default_conn, &amp;amp;conn_handle);
//     if (err) {
//         printk(&amp;quot;Failed obtaining conn_handle (err %d)\n&amp;quot;, err);
//     }

//     /* 创建 HCI 命令缓冲区以读取 RSSI */
//     buf = bt_hci_cmd_create(BT_HCI_OP_READ_RSSI, sizeof(*cp));
//     if (!buf) {
//         LOG_ERR(&amp;quot;Unable to allocate HCI command buffer&amp;quot;);
//         goto schedule;
//     }

//     /* 填充 HCI 命令数据（使用连接标识 info.id 作为句柄） */
//     cp = net_buf_add(buf, sizeof(*cp));
//     cp-&amp;gt;handle = sys_cpu_to_le16(conn_handle);

//     /* 发送 HCI 命令并等待同步响应 */
//     err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_RSSI, buf, &amp;amp;rsp);
//     if (err) {
//         LOG_ERR(&amp;quot;Read RSSI error: %d&amp;quot;, err);
//         goto schedule;
//     }

//     /* 解析并打印 RSSI 数据 */
//     rp = (void *)rsp-&amp;gt;data;
//     LOG_INF(&amp;quot;RSSI: %d dBm&amp;quot;, rp-&amp;gt;rssi);
// 	LOG_INF(&amp;quot;Data received: %.*s&amp;quot;, last_received_data_len, last_received_data);

//     net_buf_unref(rsp);

// schedule:
//     /* 调度下一次任务：每秒读取一次 RSSI */
//     k_work_reschedule(&amp;amp;rssi_work, K_SECONDS(1));
// }










static void ble_data_sent(struct bt_nus_client *nus, uint8_t err,
					const uint8_t *const data, uint16_t len)
{
	ARG_UNUSED(nus);
	ARG_UNUSED(data);
	ARG_UNUSED(len);

	k_sem_give(&amp;amp;nus_write_sem);

	if (err) {
		LOG_WRN(&amp;quot;ATT error code: 0x%02X&amp;quot;, err);
	}
}




static uint8_t ble_data_received(struct bt_nus_client *nus,
                                 const uint8_t *data, uint16_t len)
{
    ARG_UNUSED(nus);

    // 保存接收到的数据
    memset(last_received_data, 0, sizeof(last_received_data));
    last_received_data_len = len &amp;lt; UART_BUF_SIZE ? len : UART_BUF_SIZE - 1;
    memcpy(last_received_data, data, last_received_data_len);

    LOG_INF(&amp;quot;Data received: %.*s&amp;quot;, last_received_data_len, last_received_data);

    return BT_GATT_ITER_CONTINUE;
}









static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
	ARG_UNUSED(dev);

	static size_t aborted_len;
	struct uart_data_t *buf;
	static uint8_t *aborted_buf;
	static bool disable_req;

	switch (evt-&amp;gt;type) {
	case UART_TX_DONE:
		LOG_DBG(&amp;quot;UART_TX_DONE&amp;quot;);
		if ((evt-&amp;gt;data.tx.len == 0) ||
		    (!evt-&amp;gt;data.tx.buf)) {
			return;
		}

		if (aborted_buf) {
			buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
					   data[0]);
			aborted_buf = NULL;
			aborted_len = 0;
		} else {
			buf = CONTAINER_OF(evt-&amp;gt;data.tx.buf,
					   struct uart_data_t,
					   data[0]);
		}

		k_free(buf);

		buf = k_fifo_get(&amp;amp;fifo_uart_tx_data, K_NO_WAIT);
		if (!buf) {
			return;
		}

		if (uart_tx(uart, buf-&amp;gt;data, buf-&amp;gt;len, SYS_FOREVER_MS)) {
			LOG_WRN(&amp;quot;Failed to send data over UART&amp;quot;);
		}

		break;

	case UART_RX_RDY:
		LOG_DBG(&amp;quot;UART_RX_RDY&amp;quot;);
		buf = CONTAINER_OF(evt-&amp;gt;data.rx.buf, struct uart_data_t, data[0]);
		buf-&amp;gt;len += evt-&amp;gt;data.rx.len;

		if (disable_req) {
			return;
		}

		if ((evt-&amp;gt;data.rx.buf[buf-&amp;gt;len - 1] == &amp;#39;\n&amp;#39;) ||
		    (evt-&amp;gt;data.rx.buf[buf-&amp;gt;len - 1] == &amp;#39;\r&amp;#39;)) {
			disable_req = true;
			uart_rx_disable(uart);
		}

		break;

	case UART_RX_DISABLED:
		LOG_DBG(&amp;quot;UART_RX_DISABLED&amp;quot;);
		disable_req = false;

		buf = k_malloc(sizeof(*buf));
		if (buf) {
			buf-&amp;gt;len = 0;
		} else {
			LOG_WRN(&amp;quot;Not able to allocate UART receive buffer&amp;quot;);
			k_work_reschedule(&amp;amp;uart_work, UART_WAIT_FOR_BUF_DELAY);
			return;
		}

		uart_rx_enable(uart, buf-&amp;gt;data, sizeof(buf-&amp;gt;data),
			       UART_RX_TIMEOUT);

		break;

	case UART_RX_BUF_REQUEST:
		LOG_DBG(&amp;quot;UART_RX_BUF_REQUEST&amp;quot;);
		buf = k_malloc(sizeof(*buf));
		if (buf) {
			buf-&amp;gt;len = 0;
			uart_rx_buf_rsp(uart, buf-&amp;gt;data, sizeof(buf-&amp;gt;data));
		} else {
			LOG_WRN(&amp;quot;Not able to allocate UART receive buffer&amp;quot;);
		}

		break;

	case UART_RX_BUF_RELEASED:
		LOG_DBG(&amp;quot;UART_RX_BUF_RELEASED&amp;quot;);
		buf = CONTAINER_OF(evt-&amp;gt;data.rx_buf.buf, struct uart_data_t,
				   data[0]);

		if (buf-&amp;gt;len &amp;gt; 0) {
			k_fifo_put(&amp;amp;fifo_uart_rx_data, buf);
		} else {
			k_free(buf);
		}

		break;

	case UART_TX_ABORTED:
		LOG_DBG(&amp;quot;UART_TX_ABORTED&amp;quot;);
		if (!aborted_buf) {
			aborted_buf = (uint8_t *)evt-&amp;gt;data.tx.buf;
		}

		aborted_len += evt-&amp;gt;data.tx.len;
		buf = CONTAINER_OF(aborted_buf, struct uart_data_t,
				   data[0]);

		uart_tx(uart, &amp;amp;buf-&amp;gt;data[aborted_len],
			buf-&amp;gt;len - aborted_len, SYS_FOREVER_MS);

		break;

	default:
		break;
	}
}

static void uart_work_handler(struct k_work *item)
{
	struct uart_data_t *buf;

	buf = k_malloc(sizeof(*buf));
	if (buf) {
		buf-&amp;gt;len = 0;
	} else {
		LOG_WRN(&amp;quot;Not able to allocate UART receive buffer&amp;quot;);
		k_work_reschedule(&amp;amp;uart_work, UART_WAIT_FOR_BUF_DELAY);
		return;
	}

	uart_rx_enable(uart, buf-&amp;gt;data, sizeof(buf-&amp;gt;data), UART_RX_TIMEOUT);
}

static int uart_init(void)
{
	int err;
	struct uart_data_t *rx;

	if (!device_is_ready(uart)) {
		LOG_ERR(&amp;quot;UART device not ready&amp;quot;);
		return -ENODEV;
	}

	rx = k_malloc(sizeof(*rx));
	if (rx) {
		rx-&amp;gt;len = 0;
	} else {
		return -ENOMEM;
	}

	k_work_init_delayable(&amp;amp;uart_work, uart_work_handler);

	err = uart_callback_set(uart, uart_cb, NULL);
	if (err) {
		return err;
	}

	return uart_rx_enable(uart, rx-&amp;gt;data, sizeof(rx-&amp;gt;data),
			      UART_RX_TIMEOUT);
}

static void discovery_complete(struct bt_gatt_dm *dm,
			       void *context)
{
	struct bt_nus_client *nus = context;
	LOG_INF(&amp;quot;Service discovery completed&amp;quot;);

	bt_gatt_dm_data_print(dm);

	bt_nus_handles_assign(dm, nus);
	bt_nus_subscribe_receive(nus);

	bt_gatt_dm_data_release(dm);
}

static void discovery_service_not_found(struct bt_conn *conn,
					void *context)
{
	LOG_INF(&amp;quot;Service not found&amp;quot;);
}

static void discovery_error(struct bt_conn *conn,
			    int err,
			    void *context)
{
	LOG_WRN(&amp;quot;Error while discovering GATT database: (%d)&amp;quot;, err);
}

struct bt_gatt_dm_cb discovery_cb = {
	.completed         = discovery_complete,
	.service_not_found = discovery_service_not_found,
	.error_found       = discovery_error,
};

static void gatt_discover(struct bt_conn *conn)
{
	int err;

	if (conn != default_conn) {
		return;
	}

	err = bt_gatt_dm_start(conn,
			       BT_UUID_NUS_SERVICE,
			       &amp;amp;discovery_cb,
			       &amp;amp;nus_client);
	if (err) {
		LOG_ERR(&amp;quot;could not start the discovery procedure, error &amp;quot;
			&amp;quot;code: %d&amp;quot;, err);
	}
}

static void exchange_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_exchange_params *params)
{
	if (!err) {
		LOG_INF(&amp;quot;MTU exchange done&amp;quot;);
	} else {
		LOG_WRN(&amp;quot;MTU exchange failed (err %&amp;quot; PRIu8 &amp;quot;)&amp;quot;, err);
	}
}

static void connected(struct bt_conn *conn, uint8_t conn_err)
{
	char addr[BT_ADDR_LE_STR_LEN];
	int err;

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));


	if (conn_err) {
		LOG_INF(&amp;quot;Failed to connect to %s, 0x%02x %s&amp;quot;, addr, conn_err,
			bt_hci_err_to_str(conn_err));

		if (default_conn == conn) {
			bt_conn_unref(default_conn);

			default_conn = NULL;

			err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
			if (err) {
				LOG_ERR(&amp;quot;Scanning failed to start (err %d)&amp;quot;,
					err);
			}
		}

		return;
	}

	default_conn = bt_conn_ref(conn);
	bt_hci_get_conn_handle(default_conn, &amp;amp;default_conn_handle);

	LOG_INF(&amp;quot;Connected: %s&amp;quot;, addr);

	static struct bt_gatt_exchange_params exchange_params;

	exchange_params.func = exchange_func;
	err = bt_gatt_exchange_mtu(conn, &amp;amp;exchange_params);
	if (err) {
		LOG_WRN(&amp;quot;MTU exchange failed (err %d)&amp;quot;, err);
	}

	err = bt_conn_set_security(conn, BT_SECURITY_L2);
	if (err) {
		LOG_WRN(&amp;quot;Failed to set security: %d&amp;quot;, err);

		gatt_discover(conn);
	}

	err = bt_scan_stop();
	if ((!err) &amp;amp;&amp;amp; (err != -EALREADY)) {
		LOG_ERR(&amp;quot;Stop LE scan failed (err %d)&amp;quot;, err);
	}
	//k_work_init_delayable(&amp;amp;rssi_work, rssi_work_handler);
	// 启动任务
    //k_work_schedule(&amp;amp;rssi_work, K_NO_WAIT);
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	//k_work_cancel_delayable(&amp;amp;rssi_work);  // 取消RSSI任务

	char addr[BT_ADDR_LE_STR_LEN];
	int err;

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	LOG_INF(&amp;quot;Disconnected: %s, reason 0x%02x %s&amp;quot;, addr, reason, bt_hci_err_to_str(reason));
	


	if (default_conn != conn) {
		return;
	}

	bt_conn_unref(default_conn);
	default_conn = NULL;



	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
	if (err) {
		LOG_ERR(&amp;quot;Scanning failed to start (err %d)&amp;quot;,
			err);
	}

}

static void security_changed(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(&amp;quot;Security changed: %s level %u&amp;quot;, addr, level);
	} else {
		LOG_WRN(&amp;quot;Security failed: %s level %u err %d %s&amp;quot;, addr, level, err,
			bt_security_err_to_str(err));
			
	}

	gatt_discover(conn);
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = connected,
	.disconnected = disconnected,
	.security_changed = security_changed
};

static void scan_filter_match(struct bt_scan_device_info *device_info,
			      struct bt_scan_filter_match *filter_match,
			      bool connectable)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(device_info-&amp;gt;recv_info-&amp;gt;addr, addr, sizeof(addr));

	LOG_INF(&amp;quot;Filters matched. Address: %s connectable: %d&amp;quot;,
		addr, connectable);

		
}

static void scan_connecting_error(struct bt_scan_device_info *device_info)
{
	LOG_WRN(&amp;quot;Connecting failed&amp;quot;);
}

static void scan_connecting(struct bt_scan_device_info *device_info,
			    struct bt_conn *conn)
{
	default_conn = bt_conn_ref(conn);
}

static int nus_client_init(void)
{
	int err;
	struct bt_nus_client_init_param init = {
		.cb = {
			.received = ble_data_received,
			.sent = ble_data_sent,
		}
	};

	err = bt_nus_client_init(&amp;amp;nus_client, &amp;amp;init);
	if (err) {
		LOG_ERR(&amp;quot;NUS Client initialization failed (err %d)&amp;quot;, err);
		return err;
	}

	LOG_INF(&amp;quot;NUS Client module initialized&amp;quot;);
	return err;
}

BT_SCAN_CB_INIT(scan_cb, scan_filter_match, NULL,
		scan_connecting_error, scan_connecting);

static int scan_init(void)
{
	int err;
	struct bt_scan_init_param scan_init = {
		.connect_if_match = 1,
	};

	bt_scan_init(&amp;amp;scan_init);
	bt_scan_cb_register(&amp;amp;scan_cb);

	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, BT_UUID_NUS_SERVICE);
	if (err) {
		LOG_ERR(&amp;quot;Scanning filters cannot be set (err %d)&amp;quot;, err);
		return err;
	}

	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, &amp;quot;Dynamic test beacon&amp;quot;); // 替换为目标设备的名称
    if (err) {
        LOG_ERR(&amp;quot;Failed to set name filter (err %d)&amp;quot;, err);
        return err;
    }

	err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER|BT_SCAN_NAME_FILTER, false);
	if (err) {
		LOG_ERR(&amp;quot;Filters cannot be turned on (err %d)&amp;quot;, err);
		return err;
	}

	LOG_INF(&amp;quot;Scan module initialized&amp;quot;);
	return err;
}


static void auth_cancel(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(&amp;quot;Pairing cancelled: %s&amp;quot;, addr);
}


static void pairing_complete(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(&amp;quot;Pairing completed: %s, bonded: %d&amp;quot;, addr, bonded);
}


static void pairing_failed(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));

	LOG_WRN(&amp;quot;Pairing failed conn: %s, reason %d %s&amp;quot;, addr, reason,
		bt_security_err_to_str(reason));
}

static struct bt_conn_auth_cb conn_auth_callbacks = {
	.cancel = auth_cancel,
};

static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
	.pairing_complete = pairing_complete,
	.pairing_failed = pairing_failed
};

int main(void)
{
	int err;

	err = bt_conn_auth_cb_register(&amp;amp;conn_auth_callbacks);
	if (err) {
		LOG_ERR(&amp;quot;Failed to register authorization callbacks.&amp;quot;);
		return 0;
	}

	err = bt_conn_auth_info_cb_register(&amp;amp;conn_auth_info_callbacks);
	if (err) {
		printk(&amp;quot;Failed to register authorization info callbacks.\n&amp;quot;);
		return 0;
	}

	err = bt_enable(NULL);
	if (err) {
		LOG_ERR(&amp;quot;Bluetooth init failed (err %d)&amp;quot;, err);
		return 0;
	}
	LOG_INF(&amp;quot;Bluetooth initialized&amp;quot;);



	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();
	}

	err = uart_init();
	if (err != 0) {
		LOG_ERR(&amp;quot;uart_init failed (err %d)&amp;quot;, err);
		return 0;
	}

	err = scan_init();
	if (err != 0) {
		LOG_ERR(&amp;quot;scan_init failed (err %d)&amp;quot;, err);
		return 0;
	}

	err = nus_client_init();
	if (err != 0) {
		LOG_ERR(&amp;quot;nus_client_init failed (err %d)&amp;quot;, err);
		return 0;
	}

	printk(&amp;quot;Starting Bluetooth Central UART example\n&amp;quot;);

	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
	if (err) {
		LOG_ERR(&amp;quot;Scanning failed to start (err %d)&amp;quot;, err);
		return 0;
	}

	LOG_INF(&amp;quot;Scanning successfully started&amp;quot;);

	struct uart_data_t nus_data = {
		.len = 0,
	};

	k_thread_create(&amp;amp;pwr_thread_data, pwr_thread_stack,
			K_THREAD_STACK_SIZEOF(pwr_thread_stack),
			modulate_tx_power, NULL, NULL, NULL,
			K_PRIO_COOP(10),
			0, K_NO_WAIT);
	k_thread_name_set(&amp;amp;pwr_thread_data, &amp;quot;DYN TX&amp;quot;);

	for (;;) {
		/* Wait indefinitely for data to be sent over Bluetooth */
		struct uart_data_t *buf = k_fifo_get(&amp;amp;fifo_uart_rx_data,
						     K_FOREVER);

		int plen = MIN(sizeof(nus_data.data) - nus_data.len, buf-&amp;gt;len);
		int loc = 0;

		while (plen &amp;gt; 0) {
			memcpy(&amp;amp;nus_data.data[nus_data.len], &amp;amp;buf-&amp;gt;data[loc], plen);
			nus_data.len += plen;
			loc += plen;
			if (nus_data.len &amp;gt;= sizeof(nus_data.data) ||
			   (nus_data.data[nus_data.len - 1] == &amp;#39;\n&amp;#39;) ||
			   (nus_data.data[nus_data.len - 1] == &amp;#39;\r&amp;#39;)) {
				err = bt_nus_client_send(&amp;amp;nus_client, nus_data.data, nus_data.len);
				if (err) {
					LOG_WRN(&amp;quot;Failed to send data over BLE connection&amp;quot;
						&amp;quot;(err %d)&amp;quot;, err);
				}

				err = k_sem_take(&amp;amp;nus_write_sem, NUS_WRITE_TIMEOUT);
				if (err) {
					LOG_WRN(&amp;quot;NUS send timeout&amp;quot;);
				}

				nus_data.len = 0;
			}

			plen = MIN(sizeof(nus_data.data), buf-&amp;gt;len - loc);
		}

		k_free(buf);
	}
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I still get this opcode 0x1405&amp;nbsp;after the second connection.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;00&amp;gt; [00:01:02.611,816] &amp;lt;wrn&amp;gt; central_uart: bt_nus_client_send failed (err -128)
00&amp;gt; [00:01:02.712,188] &amp;lt;wrn&amp;gt; bt_hci_core: opcode 0x1405 status 0x02 
00&amp;gt; Read RSSI err: -5
00&amp;gt; RSSI: -1 dBm
00&amp;gt; [00:01:02.712,310] &amp;lt;wrn&amp;gt; central_uart: bt_nus_client_send failed (err -128)
00&amp;gt; [00:01:02.812,683] &amp;lt;wrn&amp;gt; bt_hci_core: opcode 0x1405 status 0x02 
00&amp;gt; Read RSSI err: -5
00&amp;gt; RSSI: -1 dBm
00&amp;gt; [00:01:02.812,774] &amp;lt;wrn&amp;gt; central_uart: bt_nus_client_send failed (err -128)
00&amp;gt; [00:01:02.913,146] &amp;lt;wrn&amp;gt; bt_hci_core: opcode 0x1405 status 0x02 
00&amp;gt; Read RSSI err: -5
00&amp;gt; RSSI: -1 dBm
00&amp;gt; [00:01:02.913,238] &amp;lt;wrn&amp;gt; central_uart: bt_nus_client_send failed (err -128)
00&amp;gt; [00:01:03.013,610] &amp;lt;wrn&amp;gt; bt_hci_core: opcode 0x1405 status 0x02 
00&amp;gt; Read RSSI err: -5
00&amp;gt; RSSI: -1 dBm
00&amp;gt; [00:01:03.013,732] &amp;lt;wrn&amp;gt; central_uart: bt_nus_client_send failed (err -128)
00&amp;gt; [00:01:03.114,105] &amp;lt;wrn&amp;gt; bt_hci_core: opcode 0x1405 status 0x02 
00&amp;gt; Read RSSI err: -5
00&amp;gt; RSSI: -1 dBm
00&amp;gt; [00:01:03.114,196] &amp;lt;wrn&amp;gt; central_uart: bt_nus_client_send failed (err -128)
00&amp;gt; [00:01:03.214,569] &amp;lt;wrn&amp;gt; bt_hci_core: opcode 0x1405 status 0x02 
00&amp;gt; Read RSSI err: -5
00&amp;gt; RSSI: -1 dBm
00&amp;gt; [00:01:03.214,660] &amp;lt;wrn&amp;gt; central_uart: bt_nus_client_send failed (err -128)
00&amp;gt; [00:01:03.315,032] &amp;lt;wrn&amp;gt; bt_hci_core: opcode 0x1405 status 0x02 
00&amp;gt; Read RSSI err: -5
00&amp;gt; RSSI: -1 dBm&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Could you help me to figure out?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NUS central device return bt_hci_core: opcode 0x1405 status 0x02</title><link>https://devzone.nordicsemi.com/thread/522012?ContentTypeID=1</link><pubDate>Fri, 07 Feb 2025 15:37:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f0a4ef6e-4962-45f8-abc9-0263a3f22dac</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;The issue here is that the conn handle provided is incorrect. It is accidentally correct the first time (when the value is zero). Specifically, the way you set&amp;nbsp;p-&amp;gt;handle was incorrect. If you modify your&amp;nbsp;rssi_work_handler() function so that it looks like this, it should work (and does so on my end):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void rssi_work_handler(struct k_work *work)
{
    uint16_t conn_handle;
    struct net_buf *buf = NULL, *rsp = NULL;
    struct bt_hci_cp_read_rssi *cp;
    struct bt_hci_rp_read_rssi *rp;
    int err;

    if (!default_conn) {
        LOG_ERR(&amp;quot;No default connection available&amp;quot;);
        goto schedule;
    }

    err = bt_hci_get_conn_handle(default_conn, &amp;amp;conn_handle);
    if (err) {
        printk(&amp;quot;Failed obtaining conn_handle (err %d)\n&amp;quot;, err);
    }

    /* 创建 HCI 命令缓冲区以读取 RSSI */
    buf = bt_hci_cmd_create(BT_HCI_OP_READ_RSSI, sizeof(*cp));
    if (!buf) {
        LOG_ERR(&amp;quot;Unable to allocate HCI command buffer&amp;quot;);
        goto schedule;
    }

    /* 填充 HCI 命令数据（使用连接标识 info.id 作为句柄） */
    cp = net_buf_add(buf, sizeof(*cp));
    cp-&amp;gt;handle = sys_cpu_to_le16(conn_handle);

    /* 发送 HCI 命令并等待同步响应 */
    err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_RSSI, buf, &amp;amp;rsp);
    if (err) {
        LOG_ERR(&amp;quot;Read RSSI error: %d&amp;quot;, err);
        goto schedule;
    }

    /* 解析并打印 RSSI 数据 */
    rp = (void *)rsp-&amp;gt;data;
    LOG_INF(&amp;quot;RSSI: %d dBm&amp;quot;, rp-&amp;gt;rssi);
	LOG_INF(&amp;quot;Data received: %.*s&amp;quot;, last_received_data_len, last_received_data);

    net_buf_unref(rsp);

schedule:
    /* 调度下一次任务：每秒读取一次 RSSI */
    k_work_reschedule(&amp;amp;rssi_work, K_SECONDS(1));
}
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NUS central device return bt_hci_core: opcode 0x1405 status 0x02</title><link>https://devzone.nordicsemi.com/thread/521353?ContentTypeID=1</link><pubDate>Tue, 04 Feb 2025 15:10:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cbea3f28-76a4-48a9-baa9-8dbba975ba45</guid><dc:creator>Ziyao Zhou</dc:creator><description>&lt;p&gt;Thank you so much for your help!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NUS central device return bt_hci_core: opcode 0x1405 status 0x02</title><link>https://devzone.nordicsemi.com/thread/521345?ContentTypeID=1</link><pubDate>Tue, 04 Feb 2025 15:00:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:905172cf-743c-41d0-83bf-f9d8b9ae5f8d</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I am sorry for the delay. I am reproducing the same as you and looking into it, but have not got to the bottom of it yet. I will continue to look into it and get back to you.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>