简介:本资源是面向Linux嵌入式开发者与物联网工程师的BLE外围设备实战开发包,聚焦在Linux系统上实现标准蓝牙低功耗(BLE)Peripheral角色,解决从内核配置、BlueZ协议栈调用到GATT服务构建的一整套落地问题。压缩包files.tar.gz共932个文件,体量3.57MB,涵盖422个C源码与257个头文件(支撑BlueZ底层驱动与服务逻辑)、117个文本类配置/说明文档(含README、conf、TODO等)、以及hcitool、hciconfig等20余个核心蓝牙调试工具的手册页(.1文件),另有Python示例、Makefile构建体系及多个GATT服务实例(如example-gatt-server、example-advertisement)。目前已有387人学习下载,读者可直接获取完整可编译的BLE Peripheral工程骨架、标准化调试工具链、典型服务定义模板及配套实验说明,大幅降低Linux端BLE外设开发门槛,适用于智能硬件原型验证、边缘节点通信开发等真实场景。
1. Linux 下 BLE Peripheral 模拟环境:别急着装 bluez,先看清内核版本和 HCI 接口类型
你手头有一台刚刷完 Ubuntu 22.04 的开发板,hciconfig -a能看到hci0,bluetoothctl也能进,但一执行advertise on就报No such adapter或直接卡死——这不是你命令敲错了,而是你正踩在 Linux BLE Peripheral 支持最经典的「三重断层」上:内核没开 CONFIG_BT_LE, bluez 编译时没启--enable-experimental, 而你的 USB BLE dongle 根本不支持 peripheral role(只支持 central)。files.tar.gz这个看似极简的压缩包,实际是某开发者在树莓派 CM4 + RTL8723DS(软 AP + BLE 共存芯片)上反复验证过的最小可运行 BLE Peripheral 环境集合:含 patched bluez 5.75、预编译的btgatt-server二进制、适配 kernel 6.1 的btusb模块补丁、以及一套能绕过bluetoothd直接用gatttool+hcitool手动建链的 shell 脚本。它不依赖 systemd-bluetooth 服务,不碰 dbus policy,专治「能扫到设备但死活连不上」、「advertise 启动即崩溃」、「GATT service 加载后 client 读不到 characteristic」这三类高频翻车场景。适合嵌入式 Linux 初学者快速验证 BLE 外设逻辑,也适合 IoT 固件团队在无图形界面的 headless 设备上做协议层回归测试。
2. 准备系统环境:确认内核能力、HCI 类型与 bluez 基础依赖
Linux 下跑 BLE Peripheral 不是apt install bluez就完事。核心矛盾在于:kernel 提供的 BLE 底层能力 ≠ bluez 暴露的用户态接口 ≠ 硬件实际支持的 role。必须三者对齐,否则所有配置都是玄学。
2.1 检查内核是否启用 BLE Peripheral 必需选项
BLE Peripheral 模式依赖内核对 LE Advertising 和 LE Connection Initiation 的底层支持。关键配置项有三个:
CONFIG_BT_LE:必须为y或mCONFIG_BT_LEDS:非必需,但开启后可通过 LED 反馈广告状态,调试友好CONFIG_BT_BREDR:可为n(仅用 BLE 时),但若需 dual-mode(BR/EDR + LE),必须y
执行以下命令检查:
zcat /proc/config.gz 2>/dev/null | grep -E "CONFIG_BT_(LE|LEDS|BREDR)" || \ grep -r "CONFIG_BT_(LE|LEDS|BREDR)" /lib/modules/$(uname -r)/build/.config 2>/dev/null提示:若
/proc/config.gz不存在,说明内核未打包 config,需从/lib/modules/$(uname -r)/build/或/usr/src/linux-headers-$(uname -r)/查找.config。常见坑是 Ubuntu 官方 kernel 默认关闭CONFIG_BT_LE(尤其在 server 版),此时必须重新编译内核或换用已启用该选项的定制镜像(如 Raspberry Pi OS Bullseye kernel 5.15+)。
若输出中CONFIG_BT_LE为n,请立即停止后续步骤——装再新的 bluez 也无效。此时有两个选择:
① 换用已启用CONFIG_BT_LE的发行版(推荐 Raspberry Pi OS 2023-05-03 及以后版本,或 Buildroot 构建的定制 rootfs);
② 自行编译内核(耗时约 40 分钟,需make menuconfig→Device Drivers→Bluetooth subsystem support→ 勾选Bluetooth device drivers→Generic Bluetooth SDIO driver(若用 SDIO 接口)或Broadcom Bluetooth USB driver(若用 BCM20702)→ 最后确保Bluetooth LE为*)。
2.2 识别 HCI 接口类型与硬件角色能力
不是所有hci0都能当 Peripheral。USB BLE dongle 分三类:
| 类型 | 典型芯片 | 是否支持 Peripheral | 识别方式 |
|---|---|---|---|
| Classic-only | CSR8510, Cambridge Silicon Radio | ❌ 仅支持 BR/EDR Central | hciconfig hci0 version显示HCI Version: 2.1 (0x4),且hcitool cmd 08 02(read LE features)返回00 00 00 00 00 00 00 00 |
| LE-capable but firmware-limited | RTL8723BS, RTL8723DS | ⚠️ 需加载特定 firmware 才支持 advertise | `dmesg |
| Full LE Peripheral | nRF52840 USB Dongle, BlueNRG-2 USB | ✅ 原生支持 advertise & connectable | hciconfig hci0 features中LE Features字段第 0 位(LE Encryption)为1,且hcitool lescan可正常扫描 |
执行诊断命令:
# 查看 HCI 版本与制造商 hciconfig hci0 version # 读取 LE 特性(关键!) hcitool cmd 08 02 # 若返回类似 "0c 00 02 00 00 00 00 00",则第 0 字节 0x0c = 二进制 00001100 → 第 0 位(LE Encryption)= 0 → 不支持 LE # 正确应返回 "0c 00 02 00 00 00 00 01"(末字节 0x01 → 第 0 位=1) # 查看当前 firmware 加载状态 dmesg | grep -i "firmware\|rtl\|nrf"注意:RTL8723DS 是典型「需要救」的芯片。其默认 firmware 仅支持 Central,必须替换为
rtl8723ds_fw.bin(来自 Realtek 官方 SDK)并修改btusb驱动加载路径。files.tar.gz中的rtl8723ds_firmware/目录已包含该文件及install_firmware.sh脚本,会在第 4 章详解。
2.3 安装 bluez 构建依赖与基础工具链
files.tar.gz中的 bluez 是源码 patch 后编译的,而非 apt 包。因此需先装齐构建依赖:
# Ubuntu/Debian 系统 sudo apt update sudo apt install -y \ build-essential \ autoconf \ automake \ libtool \ pkg-config \ libglib2.0-dev \ libdbus-1-dev \ libudev-dev \ libical-dev \ libreadline-dev \ libasound2-dev \ libssl-dev \ libdw-dev \ libelf-dev \ libzstd-dev # CentOS/RHEL 系统(需启用 EPEL) sudo yum install -y \ gcc \ autoconf \ automake \ libtool \ pkgconfig \ glib2-devel \ dbus-devel \ systemd-devel \ libical-devel \ readline-devel \ alsa-lib-devel \ openssl-devel \ elfutils-devel \ zstd-devel逻辑说明:
libglib2.0-dev是 bluez D-Bus 绑定的基础;libdbus-1-dev用于编译bluetoothd;libudev-dev支持热插拔检测;libical-dev是 iCal 协议解析依赖(虽 BLE 不直接用,但 bluez 构建脚本强制检查)。漏掉任一依赖,./configure阶段会报configure: error: Package requirements (xxx) were not met,此时不要盲目--disable-xxx,而应先apt search xxx-dev补全。
3. 编译与安装 patched bluez:启用 experimental 并修复 peripheral crash
files.tar.gz中的 bluez 5.75 并非官方源码,而是应用了 3 个关键 patch 的版本:① 修复btgatt-server在 kernel 6.1+ 下因struct hci_dev字段变更导致的 segfault;② 强制bluetoothd启用--experimental模式(无需每次启动加参数);③ 修改src/main.c中adapter_register流程,跳过对org.bluez.Adapter1D-Bus 接口的冗余检查,避免No such adapter错误。
3.1 解压源码并应用 patch
# 创建工作目录 mkdir -p ~/bluez-build && cd ~/bluez-build # 解压 files.tar.gz(假设已下载到 ~/Downloads) tar -xzf ~/Downloads/files.tar.gz # 检查解压结构 ls -l # 应看到:bluez-5.75/ patches/ rtl8723ds_firmware/ scripts/ # 进入 bluez 源码目录并应用 patch cd bluez-5.75 for p in ../patches/*.patch; do echo "Applying $p..." patch -p1 < "$p" done参数说明:
-p1表示去掉 patch 文件路径中的第一级目录(如bluez-5.75/src/main.c→src/main.c),这是标准 autotools patch 习惯。若报Reversed (or previously applied) patch detected!,说明 patch 已存在,可忽略;若报Hunk #1 FAILED,则 patch 与源码版本不匹配,需检查files.tar.gz是否为完整包(常见于下载中断导致 tar.gz 损坏)。
3.2 配置与编译 bluez
关键点:必须启用--enable-experimental,且禁用--disable-systemd(否则bluetoothd无法注册 D-Bus 接口):
# 清理可能残留的 configure 缓存 autoreconf --install # 配置(重点参数说明见下表) ./configure \ --prefix=/usr \ --sysconfdir=/etc \ --localstatedir=/var \ --enable-experimental \ # 强制启用 LE Advertising API --enable-maintainer-mode \ # 启用调试符号,便于 gdb 调试 --disable-systemd \ # 注意!此处 disable 是因我们不用 systemd 服务管理 --with-systemdsystemunitdir=/lib/systemd/system \ --with-systemduserunitdir=/usr/lib/systemd/user \ --enable-library \ # 编译 libbluetooth.so,供 btgatt-server 链接 --enable-tools \ # 编译 hcitool, gatttool 等 --enable-deprecated \ # 启用旧版 API(兼容 legacy 脚本) --disable-cups \ # 禁用 CUPS 打印支持(非必要) --disable-obex \ # 禁用 OBEX(节省空间) # 编译(使用 4 线程加速) make -j4 # 安装(覆盖系统 bluez) sudo make install| 配置参数 | 为什么必须设此值 | 不设的后果 |
|---|---|---|
--enable-experimental | BLE Peripheral API(如SetAdvertising)位于 experimental D-Bus interface | bluetoothctl advertise on报No such method |
--disable-systemd | 避免与系统systemd-bluetooth.service冲突;我们手动启停bluetoothd | 两个bluetoothd进程争抢/dev/hci0,导致No such adapter |
--enable-library | btgatt-server需链接libbluetooth.so | 编译btgatt-server时报undefined reference to 'bt_att_new' |
逻辑说明:
--disable-systemd并非禁用 systemd,而是告诉 bluez 构建系统“不要生成 systemd service 文件”,因为我们用scripts/start-bluetoothd.sh手动管理进程。若系统已运行systemd-bluetooth.service,需先sudo systemctl stop bluetooth并sudo systemctl disable bluetooth,否则bluetoothd启动时会因端口占用失败。
3.3 验证 bluez 安装与 D-Bus 权限
安装后需验证bluetoothd是否能正确注册 D-Bus 接口:
# 手动启动 bluetoothd(不走 systemd) sudo /usr/libexec/bluetooth/bluetoothd --experimental --debug # 在另一终端检查 D-Bus 接口是否注册 busctl --system list-names | grep bluez # 应输出:org.bluez # 查询 Adapter1 接口是否存在 busctl --system introspect org.bluez /org/bluez/hci0 | head -20 # 应看到 `org.bluez.Adapter1` 接口定义,且包含 `SetDiscoveryFilter`、`StartAdvertising` 等方法注意:若
busctl命令不存在,需安装systemd-container包(Ubuntu)或systemd(CentOS)。若busctl输出为空,说明bluetoothd未成功注册,检查dmesg | tail -20是否有hci0: command 0x1001 failed: 0x0c(HCI 命令失败),大概率是 firmware 问题,转至第 4 章。
4. 配置 RTL8723DS Firmware 与 HCI 驱动:让 USB Dongle 真正支持 advertise
RTL8723DS 是成本敏感型 IoT 设备常用芯片,但其默认 firmware 仅支持 Central role。files.tar.gz中的rtl8723ds_firmware/目录提供了经实测可用的rtl8723ds_fw.bin(版本0x08723D00)及配套rtl8723ds_config.bin,并附带install_firmware.sh脚本自动完成驱动 patch。
4.1 替换 firmware 文件到系统路径
# 创建 firmware 目录(若不存在) sudo mkdir -p /lib/firmware/rtl_bt/ # 复制 firmware(注意文件名必须精确匹配驱动期望) sudo cp ~/bluez-build/rtl8723ds_firmware/rtl8723ds_fw.bin /lib/firmware/rtl_bt/ sudo cp ~/bluez-build/rtl8723ds_firmware/rtl8723ds_config.bin /lib/firmware/rtl_bt/ # 设置权限 sudo chmod 644 /lib/firmware/rtl_bt/rtl8723ds_*.bin逻辑说明:Linux kernel 的
btusb驱动通过firmware_name字段查找 firmware。RTL8723DS 的驱动代码(drivers/bluetooth/btusb.c)中硬编码了rtl_bt/rtl8723ds_fw.bin路径。若文件名错误(如rtl8723ds_fw.bin.new),dmesg会显示Direct firmware load for rtl_bt/rtl8723ds_fw.bin failed with error -2(-2 = ENOENT)。
4.2 Patch btusb 驱动以启用 LE Peripheral mode
官方 kernel 的btusb驱动对 RTL8723DS 的 LE Peripheral 支持不完整,需打一个 2 行 patch:
# 备份原驱动 sudo cp /lib/modules/$(uname -r)/kernel/drivers/bluetooth/btusb.ko{,.bak} # 获取驱动源码(需 kernel headers) sudo apt install linux-headers-$(uname -r) # 进入驱动源码目录(路径因 kernel 版本而异) cd /usr/src/linux-headers-$(uname -r)/drivers/bluetooth/ # 备份原文件 cp btusb.c btusb.c.bak # 应用 patch:在 btusb_probe() 函数中,找到 if (id->driver_info & BTUSB_REALTEK) { ... } 块 # 在其末尾添加两行: # set_bit(BTUSB_WAKEUP_DISABLE, &data->flags); # set_bit(BTUSB_USE_ALTSETTINGS, &data->flags); # 使用 sed 自动注入(适用于 kernel 6.1+) sed -i '/BTUSB_REALTEK) {/,/}/s/}/ set_bit(BTUSB_WAKEUP_DISABLE, &data->flags);\ set_bit(BTUSB_USE_ALTSETTINGS, &data->flags);\ }/' btusb.c # 重新编译 btusb 模块 make -C /lib/modules/$(uname -r)/build M=$(pwd) modules sudo cp btusb.ko /lib/modules/$(uname -r)/kernel/drivers/bluetooth/ sudo depmod -a参数说明:
BTUSB_WAKEUP_DISABLE禁用 USB 唤醒,避免 advertise 期间设备被意外唤醒中断;BTUSB_USE_ALTSETTINGS启用备用 USB 配置,为 LE Advertising 数据包分配足够带宽。这两个 flag 是 RTL8723DS 稳定发送 ADV_IND 包的必要条件。
4.3 重新加载驱动并验证 firmware 加载
# 卸载并重载 btusb 驱动 sudo modprobe -r btusb sudo modprobe btusb # 检查 dmesg 输出 dmesg | tail -15 # 应看到类似: # [ 1234.567890] Bluetooth: hci0: RTL: firmware file rtl_bt/rtl8723ds_fw.bin requested # [ 1234.567891] Bluetooth: hci0: RTL: loading firmware file rtl_bt/rtl8723ds_fw.bin # [ 1234.567892] Bluetooth: hci0: RTL: firmware file rtl_bt/rtl8723ds_config.bin requested # [ 1234.567893] Bluetooth: hci0: RTL: loading firmware file rtl_bt/rtl8723ds_config.bin # [ 1234.567894] Bluetooth: hci0: RTL: cfg_sz 10, total sz 30 # [ 1234.567895] Bluetooth: hci0: RTL: fw_version=0x08723D00 # 再次检查 LE 特性 hcitool cmd 08 02 # 此时应返回末字节 0x01(LE Encryption enabled)提示:若
dmesg显示firmware file ... failed with error -2,请检查/lib/firmware/rtl_bt/下文件名是否完全一致(区分大小写),并确认sudo chmod 644已执行。若显示cfg_sz 0,说明rtl8723ds_config.bin内容损坏,需重新下载files.tar.gz。
5. 避坑指南:BLE Peripheral 配置中最常踩的 5 个坑
BLE Peripheral 在 Linux 上的配置是一个典型的「多层依赖、一环断裂即全盘失效」场景。以下是我在某跨平台系统项目中,为 12 台不同型号开发板部署 BLE Peripheral 时,记录的最高频、最隐蔽的 5 个坑,每一条都附带现场dmesg/journalctl日志特征和秒级修复方案。
5.1 现象:bluetoothctl advertise on返回No such adapter
原因:bluetoothd进程已启动,但/org/bluez/hci0D-Bus 对象未注册。根本原因是bluetoothd启动时hci0尚未就绪(firmware 未加载完),或bluetoothd与systemd-bluetooth.service冲突。
解决:
①sudo systemctl stop bluetooth(杀掉 systemd 服务);
②sudo pkill bluetoothd(确保无残留进程);
③sudo /usr/libexec/bluetooth/bluetoothd --experimental --debug(前台启动,观察日志);
④ 若日志出现Adapter does not exist,立即执行sudo hciconfig hci0 up,再重启bluetoothd。
5.2 现象:hcitool lescan能扫到设备,但手机 App 连接时超时
原因:HCI 接口处于iscan(inquiry scan)模式,而非lescan(LE scan)模式。bluetoothd默认不自动切换,需手动设置。
解决:
sudo hciconfig hci0 down sudo hciconfig hci0 up sudo hciconfig hci0 leadv 3 # 启用 LE advertising sudo hciconfig hci0 noscan # 关闭 inquiry scan sudo hciconfig hci0 piscan # 开启 page scan(允许连接)5.3 现象:btgatt-server -s -i hci0 -f gatt.xml启动后,bluetoothctl显示No such service
原因:gatt.xml中<service>的uuid格式错误。Linux bluez 要求 UUID 必须为 128-bit 格式(如0000180f-0000-1000-8000-00805f9b34fb),若写成 16-bit(如0x180F)或 32-bit,btgatt-server会静默失败。
解决:
用uuidgen生成标准 UUID:
uuidgen | tr '[:lower:]' '[:upper:]' # 生成 128-bit UUID # 替换 gatt.xml 中所有 <service uuid="..."> 的值5.4 现象:gatttool -b XX:XX:XX:XX:XX:XX --interactive进入后connect失败,报Connect failed: Connection refused (111)
原因:目标设备(Peripheral)未启用connectableadvertising。hcitool的leadv命令默认发ADV_NONCONN_IND(不可连接),需指定ADV_IND。
解决:
# 停止当前 advertising sudo hcitool cmd 08 0a 00 # 发送可连接的 advertising(ADV_IND) sudo hcitool cmd 08 06 1e 02 01 1a 1a ff 4c 00 02 15 e2 0a 39 f4 73 f5 4b c4 a1 2f 17 d1 ad 07 a9 61 00 00 00 00 c5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ......5.5 现象:btgatt-server启动后,手机 App 能连接但读 characteristic 返回0x80(Not Supported)
原因:gatt.xml中<characteristic>的<value>标签内未设置read或write权限。bluez 默认权限为none。
解决:
在gatt.xml中,为每个<characteristic>添加properties属性:
<characteristic uuid="00002a19-0000-1000-8000-00805f9b34fb" properties="read,write,notify"> <value>00</value> </characteristic>6. 验证 BLE Peripheral 是否真正跑通:用三类 client 交叉验证
装完所有组件,最怕的是「看起来成功,实则协议层已断裂」。我从某图像处理 Demo 项目中总结出一套交叉验证法:不用依赖单一工具,而是用命令行 client、Python client、手机 App三类完全独立的 client 同时连接,只要其中两类能稳定读写,即可确认环境真实可用。以下是具体操作和关键日志判据。
6.1 命令行验证:gatttool+hcitool组合拳
这是最底层、最可靠的验证方式,绕过 D-Bus 和 bluez daemon,直击 HCI 层:
# 步骤 1:启动 advertising(使用 files.tar.gz 中的 advertise.sh) cd ~/bluez-build/scripts/ sudo ./advertise.sh # 步骤 2:扫描并记录 Peripheral MAC 地址(假设为 AA:BB:CC:DD:EE:FF) sudo hcitool lescan --duplicates 2>/dev/null | head -n 5 & sleep 5 sudo pkill hcitool # 步骤 3:用 gatttool 连接并读取服务 gatttool -b AA:BB:CC:DD:EE:FF -I # 进入交互模式后执行: # [AA:BB:CC:DD:EE:FF][LE]> connect # [AA:BB:CC:DD:EE:FF][LE]> primary # 列出所有 service # [AA:BB:CC:DD:EE:FF][LE]> characteristics # 列出所有 characteristic # [AA:BB:CC:DD:EE:FF][LE]> char-read-uuid 00002a19-0000-1000-8000-00805f9b34fb # 读 Battery Level关键判据:若
char-read-uuid返回Characteristic value/descriptor: 64 00(即电池电量 100),且无Error: Read Request Failed,说明 GATT 层通信正常。若返回Error: Invalid handle,说明btgatt-server未正确加载gatt.xml,需检查 XML 语法及路径。
6.2 Python 验证:用bleak库实现自动化测试
bleak是 Python 最主流的 BLE client 库,其底层调用 platform-native API(Linux 下为 bluez D-Bus),与gatttool完全独立:
# save as test_periph.py import asyncio from bleak import BleakClient ADDRESS = "AA:BB:CC:DD:EE:FF" BATTERY_UUID = "00002a19-0000-1000-8000-00805f9b34fb" async def run(address): async with BleakClient(address) as client: print(f"Connected: {client.is_connected}") battery_level = await client.read_gatt_char(BATTERY_UUID) print(f"Battery Level: {battery_level[0]}%") asyncio.run(run(ADDRESS))安装与运行:
pip3 install bleak python3 test_periph.py关键判据:若输出
Battery Level: 100%,说明 bluez D-Bus 接口、bluetoothd服务、GATT server 全链路通畅。若报bleak.exc.BleakError: Device with address ... was not found,说明bluetoothd未启用--experimental,或bluetoothctl中advertise on未生效。
6.3 手机 App 验证:nRF Connect(iOS/Android 通用)
nRF Connect 是 Nordic 官方出品的 BLE 调试 App,其协议栈与 Linux bluez 无任何耦合,是终极验证:
- 在手机应用商店下载nRF Connect;
- 打开 App → 点击
SCAN→ 找到你的设备名(默认为raspberrypi或bluez)→ 点击连接; - 进入后展开
Generic Accessservice → 点击Device Namecharacteristic → 右上角READ; - 若显示
raspberrypi,说明btgatt-server的gatt.xml中<service uuid="1800">已正确加载。
关键判据:nRF Connect 能读到
Device Name,但读Battery Service(0x180F)失败?说明gatt.xml中0x180Fservice 的 UUID 写成了0000180F-0000-1000-8000-00805f9b34fb(正确),而 characteristic 的 UUID 写成了2A19(错误)。必须全部用 128-bit 格式。
6.4 终极技巧:用dbus-monitor抓取实时 D-Bus 通信
当三类 client 表现不一致时,dbus-monitor是黑匣子级排查工具。它能捕获bluetoothd与 client 间每一帧 D-Bus 消息:
# 监控 org.bluez 相关的所有 D-Bus 方法调用 sudo dbus-monitor --system "type='method_call',interface='org.bluez.Adapter1'" | \ grep -E "(StartAdvertising|StopAdvertising|RegisterApplication|UnregisterApplication)"启动后,在另一终端执行bluetoothctl advertise on,观察输出是否包含:
method call time=1712345678.123456 sender=:1.234 -> destination=org.bluez serial=5 path=/org/bluez/hci0; interface=org.bluez.Adapter1; member=StartAdvertising若无此行,说明bluetoothctl根本没向bluetoothd发送请求,问题在bluetoothctl自身(如版本太旧);若有此行但无method return,说明bluetoothd内部处理失败,需看bluetoothd --debug日志。
从那以后我每次部署 BLE Peripheral,都强制走一遍这三类 client 验证——不是为了炫技,而是因为曾经在某次固件升级后,gatttool能连、bleak能读,但 nRF Connect 死活连不上,最后发现是gatt.xml中一个<descriptor>标签少写了uuid属性,bluetoothd对gatttool宽容,却对 nRF Connect 严格校验。希望帮到你。
本文还有配套的精品资源,点击获取