Hi
I have a beacon sending out some data, and I have already finish the TX side, I also want to have a RX side to receive the data, in addition, as there are many other deivices advertising, I want to only receive one device, the name is "TX beacon".
I have write my code like below:
/* * SPDX-License-Identifier: Apache-2.0 * * */ #include <zephyr/types.h> #include <stddef.h> #include <string.h> #include <zephyr/kernel.h> #include <zephyr/sys/printk.h> #include <zephyr/bluetooth/bluetooth.h> #include <zephyr/bluetooth/hci.h> static bool manuf_data_print(struct bt_data *data, void *user_data) { if (data->type == BT_DATA_MANUFACTURER_DATA) { printk("Manufacturer Data (len %u): ", data->data_len); for (uint8_t i = 0; i < data->data_len; i++) { printk("%02X ", data->data[i]); } printk("\n"); } return true; } static bool parse_name_cb(struct bt_data *data, void *user_data) { char *dev_name = user_data; if (data->type == BT_DATA_NAME_COMPLETE || data->type == BT_DATA_NAME_SHORTENED) { memcpy(dev_name, data->data, data->data_len); dev_name[data->data_len] = '\0'; return false; } return true; } static void scan_recv_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type, struct net_buf_simple *buf) { char addr_str[BT_ADDR_LE_STR_LEN]; char dev_name[31] = {0}; uint8_t backup_buf[buf->len]; memcpy(backup_buf, buf->data, buf->len); struct net_buf_simple backup; net_buf_simple_init_with_data(&backup, backup_buf, buf->len); bt_data_parse(buf, parse_name_cb, dev_name); if (strcmp(dev_name, "TX beacon") == 0) {printk("Target device found!\n"); // // bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); // // printk("Target device found: %s (RSSI %d)\n", addr_str, rssi); bt_data_parse(&backup, manuf_data_print, NULL);} } int main(void) { int err; printk("BLE Scanner started\n"); err = bt_enable(NULL); if (err) { printk("Bluetooth init failed (err %d)\n", err); return err; } printk("Bluetooth initialized\n"); struct bt_le_scan_param scan_param = { .type = BT_LE_SCAN_TYPE_ACTIVE, .options = BT_LE_SCAN_OPT_NONE, .interval = 0x0060, /* 扫描间隔:60 * 0.625 = 37.5ms */ .window = 0x0030, /* 扫描窗口:约18.75ms */ }; err = bt_le_scan_start(&scan_param, scan_recv_cb); if (err) { printk("Starting scanning failed (err %d)\n", err); return err; } printk("Scanning successfully started\n"); while (1) { k_sleep(K_SECONDS(1)); } return 0; }
My config is:
# 启用蓝牙子系统 CONFIG_BT=y # Enable the UART driver CONFIG_UART_ASYNC_API=y CONFIG_NRFX_UARTE0=y CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y # 启用观察者角色,允许扫描广告数据 CONFIG_BT_OBSERVER=y # 启用 BLE 扫描相关 API CONFIG_BT_SCAN=y # Config logger CONFIG_LOG=y CONFIG_USE_SEGGER_RTT=y CONFIG_LOG_BACKEND_RTT=y CONFIG_LOG_BACKEND_UART=n CONFIG_LOG_PRINTK=y CONFIG_ASSERT=y #scan CONFIG_BT_SCAN=y CONFIG_BT_SCAN_FILTER_ENABLE=y CONFIG_BT_SCAN_NAME_CNT=3
1.At this time, the filter is no functioning,
if (strcmp(dev_name, "TX beacon") == 0) {printk("Target device found!\n");}
bt_data_parse(&backup, manuf_data_print, NULL);
the result is :
Target device found! 00> Manufacturer Data (len 9): 4C 00 10 05 26 98 DA 17 15 00> Manufacturer Data (len 29): 06 00 01 0F 20 02 5E F5 2E 1A 02 45 7A EE 22 54 08 E9 52 50 --- 7 messages dropped --- 00> C1 7B 00> Manufacturer Data (len 26): 4C 00 0C 0E 00 C8 6C 8A 31 39 28 A6 49 47 16 B1 FB C8 10 06 45 1D A9 0A 48 58 00> Manufacturer Data (len 11): 4C 00 10 07 3A 1F 09 B8 D8 BB 58 00> Manufacturer Data (len 13): 4C 00 0F 05 90 00 D7 1E BC 10 02 25 04 00> Manufacturer Data (len 22): 4C 00 09 08 13 7D C0 A8 12 79 1B 58 13 08 4A DA C8 97 F4 E5 F6 00 00> Manufacturer Data (len 29): 06 00 01 0F 20 22 3F E9 2A AF BE 54 A4 C3 E6 A0 02 32 BF CA 13 2D --- 8 messages dropped --- 00> Manufacturer Data (len 29): 06 00 01 09 20 22 67 00 E8 CB 15 62 06 96 DD DD C4 0F 96 E7 1B EF 77 61 7D 49 93 43 13 00> Manufacturer Data (len 13): 4C 00 0F 05 90 00 5C 70 C6 10 02 20 04 00> Manufacturer Data (len 13): 4C 00 0F 05 90 00 5C 70 C6 10 02 20 04 00> Manufacturer Data (len 5): 65 00 01 C9 04 00> Manufacturer Data (len 20): 7D 02 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 FF 00 00 00> Target device found!
So I am sure when bt_data_parse(buf, parse_name_cb, dev_name) and bt_data_parse(&backup, manuf_data_print, NULL); functions well separetely.
2.However, when my code go to
if (strcmp(dev_name, "TX beacon") == 0) {printk("Target device found!\n");
bt_data_parse(&backup, manuf_data_print, NULL);}
Strange thing happen, bt_data_parse(&backup, manuf_data_print, NULL) can not work and the result is:
Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found! 00> Target device found!
I try to debug it and it will stop at __ASSERT(z_spin_lock_valid(l), "Invalid spinlock %p", l); which is really strange!
Could you help me figure out what is happening? Or is there some easier way to do the NAME filter like "bt_scan_filter_add" and "bt_scan_filter_enable", Thank you so much for your time!