如何配置nRF52840仅接受授权蓝牙连接?
nRF52840蓝牙设备限制可见性与连接权限解决方案
问题描述
现有基于Seeed Studio XIAO nRF52840的蓝牙代码功能正常,通过BLE UART接收PC客户端指令控制LED,但存在以下问题:
- 设备对所有蓝牙设备可见,手机蓝牙设置等非授权设备可扫描到并占用连接
- 无法限制仅授权桌面应用接入
需求:
- 禁止手机等普通蓝牙设备扫描发现该设备
- 仅允许指定桌面应用检测并连接
解决方案
通过修改广播模式、添加配对验证、调整广播内容三个维度实现限制:
1. 修改广播为定向不可发现模式
将通用可发现广播改为仅广播特定服务UUID,且不发送设备名称,普通蓝牙扫描工具(如手机蓝牙设置)会忽略此类广播,只有知道目标服务UUID的应用才能扫描到。
2. 添加配对验证机制
设置蓝牙配对要求,使用预共享密钥(PSK),只有知道密钥的桌面应用才能完成配对并连接,避免非授权设备占用连接。
修改后的完整代码
#include <bluefruit.h> const int LED_PIN = D7; BLEDis bledis; BLEUart bleuart; // 预共享配对密钥(桌面应用需使用相同密钥) const char* PAIRING_KEY = "YourSecureKey123"; void setup() { pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); Serial.begin(115200); Bluefruit.begin(); Bluefruit.setTxPower(4); Bluefruit.Periph.setDisconnectCallback(onDisconnect); Bluefruit.Periph.setConnectCallback(onConnect); // 配置配对参数:使用预共享密钥,要求MITM保护 Bluefruit.Security.setPairingMode(BLE_SEC_PAIRING_MODE_LEGACY); Bluefruit.Security.setIoCaps(BLE_SEC_IO_CAPS_NONE); Bluefruit.Security.setPasskey(atoi(PAIRING_KEY)); // 若使用数字密钥,直接转换 // 若使用字符串密钥,可替换为静态密码设置(需匹配nRF52支持格式) // Bluefruit.Security.setStaticPasskey(PAIRING_KEY); bledis.setManufacturer("Seeed Studio"); bledis.setModel("XIAO nRF52840"); bledis.begin(); bleuart.begin(); startAdv(); } void loop() { if (bleuart.available()) { delay(2); uint8_t buffer[3]; int bytesRead = bleuart.read(buffer, 3); if (bytesRead == 3 && buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0) { digitalWrite(LED_PIN, LOW); } if (bytesRead == 3 && buffer[0] == 1 && buffer[1] == 0 && buffer[2] == 1){ digitalWrite(LED_PIN, HIGH); } } } void startAdv(void) { // 使用有限可发现模式,普通设备不会主动扫描此类设备 Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE); Bluefruit.Advertising.addTxPower(); // 仅广播BLE UART服务UUID,不广播设备名称 Bluefruit.Advertising.addService(bleuart); // 注释掉广播名称的代码,避免被普通设备识别 // Bluefruit.Advertising.addName(); Bluefruit.Advertising.restartOnDisconnect(true); Bluefruit.Advertising.setInterval(32, 244); Bluefruit.Advertising.setFastTimeout(0); Bluefruit.Advertising.start(0); } void onDisconnect(uint16_t conn_handle, uint8_t reason) { digitalWrite(LED_PIN, LOW); } void onConnect(uint16_t conn_handle){ // 可选增强:验证连接设备的MAC地址,仅允许指定桌面设备连接 // ble_gap_addr_t peer_addr; // Bluefruit.Gap.getPeerAddr(conn_handle, &peer_addr); // 对比peer_addr与授权设备MAC,不匹配则主动断开连接 }
关键修改说明
- 广播配置:
- 将广播标志改为
BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE,普通蓝牙设备不会主动扫描该模式的设备 - 移除
Bluefruit.Advertising.addName(),避免设备名称被识别
- 将广播标志改为
- 配对验证:
- 设置预共享密钥,桌面应用需使用相同密钥才能完成配对
- 启用MITM保护,确保配对过程安全
- 可选增强:在
onConnect中验证设备MAC地址,进一步限制仅指定桌面设备连接
桌面应用配置要求
- 应用需主动扫描指定服务UUID:
6E400001-B5A3-F393-E0A9-E50E24DCCA9E - 应用需配置与设备相同的配对密钥,完成配对后才能建立连接
内容的提问来源于stack exchange,提问作者Aveyron2033
相关产品推荐
相关产品推荐

