当前设备二维码中存储的是设备 MAC 地址(格式:98:A3:16:35:D2:52)。
在 Android 平台,系统 BLE API 的 deviceId 直接就是 MAC 地址,可以通过扫码结果直接发起连接。
在 iOS 平台,系统出于隐私保护,不暴露设备的真实 MAC 地址,deviceId 是系统随机分配的 UUID,且每次重置蓝牙后会变化。因此 iOS 无法通过 MAC 地址直接连接设备,必须先扫描周边设备,再通过某种标识从广播包中识别出目标设备。
当前设备广播包内容(十六进制):
06000109210AD04EB83117A450432D323032333032313531333539
其中不包含设备 MAC 地址,导致 iOS 端扫码后无法定位到目标设备。
请在 BLE 广播包的 Manufacturer Specific Data(厂商自定义数据,AD Type = 0xFF) 字段中,加入设备的 MAC 地址(6字节,大端序)。
[Length] [Type=0xFF] [Company ID Low] [Company ID High] [MAC 6字节, 大端序] [其他自定义数据...]
设备 MAC 为 98:A3:16:35:D2:52,对应字节为:
98 A3 16 35 D2 52
厂商数据段示例(Company ID 使用 0x0000 占位,可替换为实际注册 ID):
[Length] FF 00 00 98 A3 16 35 D2 52 [其他数据...]
完整广播包示例(在现有数据基础上增加该字段):
原有数据段保持不变
新增字段: 0A FF 00 00 98 A3 16 35 D2 52
0A= 后续字节长度(10字节:Type 1字节 + Company ID 2字节 + MAC 6字节 + 预留1字节)
MAC 地址按大端序写入,即 98:A3:16:35:D2:52 写为:
98 A3 16 35 D2 52
不要使用小端序(52 D2 35 16 A3 98),以便 App 端直接比对。
App 收到广播包后,会遍历所有 AD Structure,找到 Type = 0xFF 的字段,从第 3 字节(跳过 Company ID)开始读取 6 字节作为 MAC,与扫码结果比对:
// 解析 Manufacturer Specific Data 中的 MAC
function extractMacFromAdvertData(advertisData: ArrayBuffer): string {
const bytes = new Uint8Array(advertisData)
let i = 0
while (i < bytes.length) {
const len = bytes[i]
const type = bytes[i + 1]
if (type === 0xFF && len >= 8) {
// 跳过 length(1) + type(1) + companyId(2),取后6字节为MAC
const mac = Array.from(bytes.slice(i + 4, i + 10))
.map(b => b.toString(16).padStart(2, '0').toUpperCase())
.join('')
return mac // 返回格式如 "98A31635D252"
}
i += len + 1
}
return ''
}
比对时将扫码 MAC 98:A3:16:35:D2:52 去掉冒号转大写后与上述结果直接比较。
修改固件后,可使用以下工具验证广播包内容:
在 nRF Connect 中找到目标设备,展开 Raw Advertising Data,确认 Manufacturer Specific Data 字段中包含正确的 MAC 字节。
如有疑问请联系 App 开发团队。