相关链接:
AI语音智能体开发日记(一)如何为"小智"服务器启用并调试 License 功能-CSDN博客
AI语音智能体开发日记(二)解决 Wi-Fi 配网小程序的兼容性问题-CSDN博客
AI语音智能体开发日记(三)解决小程序配网中的蓝牙命名与MAC地址获取问题-CSDN博客
AI语音智能体开发日记(四)在FreeRTOS中构建线程安全的UART2通信模块-CSDN博客
AI语音智能体开发日记(五)为智能设备注入"灵魂"------详解MCP工具的注册与使用-CSDN博客
推荐链接:
AI语音智能体架构解析(二)大模型(AI 的大脑)-CSDN博客
AI语音智能体架构解析(三)智控台(指挥中心)-CSDN博客
AI语音智能体架构解析(四)AI 语音终端(执行器官)-CSDN博客
AI语音智能体架构解析(五)小程序/APP(遥控器)-CSDN博客
推荐链接:
AI 应用 图文 解说 (一) -- 百度智能云 实现 语音 聊天-CSDN博客
AI 应用 图文 解说 (二) -- 百度智能云 ASR LIM TTS 语音AI助手程序 -CSDN博客
开发手记:解决小程序配网中的蓝牙命名与MAC地址获取问题
继上次解决了配网方案的兼容性问题后,这次我们遇到了一个更隐蔽的坑:在小程序配网过程中,设备蓝牙名称不规范导致无法正确获取MAC地址。这个问题在iOS上尤为突出,直接导致了配网流程的失败。
问题背景
在实现"小智云"和七牛小程序的Wi-Fi配网功能时,我们遇到了一个棘手的问题:小程序无法正确识别并连接到我们的设备。经过排查,问题根源指向了设备的蓝牙广播名称(Local Name)以及MAC地址的获取方式。
问题定位
根据灵矽平台的官方文档《设备识别》章节,我们找到了问题的关键所在。

- 设备名称规范 :文档明确规定,为了让客户端(如小程序)正确识别设备,蓝牙广播的设备名称(
name)必须符合特定的格式,例如DTXZ*、BLUFI_DEVICE*或ESP_*。 - MAC地址获取 :文档指出,由于iOS系统的安全机制,无法像Android那样直接从广播包中获取设备的MAC地址。因此,解决方案是将设备的MAC地址嵌入到蓝牙广播名称(
localName)中。 - MAC地址格式 :文档推荐了三种MAC地址格式,其中
AABBCCDDEEFF这种无分隔符的连续格式是首选,并且与智能体绑定所使用的格式一致。
结合代码分析,我们发现项目中的 blufi.c 文件存在两个问题:
- 蓝牙服务启动时,广播名称被硬编码为
"DTXZ",虽然符合命名规则,但没有包含MAC地址。 - 在生成广播名称的函数
update_adv_data_if_need中,MAC地址的拼接逻辑被注释掉了,取而代之的是一个固定的示例MAC地址。
解决方案
解决这个问题的核心是修改 project/ln_model_public/app/blufi.c 文件,确保蓝牙广播名称既符合命名规范,又包含了设备真实的MAC地址。
第一步:启用正确的蓝牙服务
首先,我们需要确保启动的是BLUFI服务,并且广播名称前缀正确。

1// 文件: project/ln_model_public/app/blufi.c
2
3void netcfg_task_entry(void *params) {
4 // ... 其他代码 ...
5 sys_ble_init(2);
6 // 启动BLUFI服务
7 sys_ble_service_start(SERVICE_TYPE_BLUFI);
8 // 设置广播名称前缀为 "DTXZ",符合灵矽规范
9 sys_ble_adv_start("DTXZ");
10 // ... 其他代码 ...
11}
这里的关键是调用 sys_ble_adv_start("DTXZ"),将广播名称的前缀设置为 DTXZ。
第二步:将真实MAC地址嵌入广播名称
这是最关键的一步。我们需要修改 update_adv_data_if_need 函数,取消注释并修正MAC地址的拼接逻辑。

1// 文件: project/ln_model_public/app/blufi.c
2
3static void update_adv_data_if_need(const char *name_format) {
4 // ... 其他代码 ...
5 uint8_t *adv_data = g_ble_cfg.adv_data;
6 char *dev_name = g_ble_cfg.dev_name;
7 int index = 0;
8
9 // ... 其他代码 ...
10
11 // 获取设备真实的Wi-Fi MAC地址
12 uint8_t *wifi_mac = get_mac_addr(); // 返回 uint8_t[6]
13
14 // 将MAC地址格式化为 "AABBCCDDEEFF" 的形式,并拼接到设备名称中
15 // 最终的设备名将会是类似 "DTXZ-A0B1C2D3E4F5" 的格式
16 snprintf(dev_name, sizeof(g_ble_cfg.dev_name), "%s-%02X%02X%02X%02X%02X%02X",
17 name_format ? name_format : "LN_DEV", // name_format 对应上一步的 "DTXZ"
18 wifi_mac[0], wifi_mac[1], wifi_mac[2],
19 wifi_mac[3], wifi_mac[4], wifi_mac[5]);
20
21 // ... 后续处理 adv_data 的代码 ...
22}
原理分析
这个解决方案完美地遵循了灵矽平台的设计规范:
- 满足命名规则 :通过
sys_ble_adv_start("DTXZ"),我们确保了广播名称以DTXZ开头,满足了小程序识别设备的第一个条件。 - 解决iOS限制 :通过
snprintf将get_mac_addr()获取到的真实MAC地址,以AABBCCDDEEFF的格式拼接到广播名称中。这样,iOS小程序在扫描到设备后,就可以通过解析localName字段,用正则表达式轻松提取出设备的MAC地址,从而解决了无法直接获取MAC的问题。
最终,设备广播的名称会变成一个类似 DTXZ-A0B1C2D3E4F5 的字符串。这个字符串既告诉了小程序"我是谁"(DTXZ设备),也告诉了小程序"我的唯一标识是什么"(MAC地址),从而打通了整个配网流程。