You need to enable JavaScript to run this app. 基于Bleno的BLE外设如何在写入请求处理时向发送方回传响应
优惠活动
大模型
产品
解决方案
定价
更多

基于Bleno的BLE外设如何在写入请求处理时向发送方回传响应

Bleno 外设端回传逻辑失效的原因与修复方案

现有代码的核心问题

  • 对onWriteRequest回调的作用认知错误:该回调仅用于向BLE协议栈告知写入请求的处理状态,传入的Buffer不会被发送到手机端,将业务回传数据塞在这里完全无法触达发送方。
  • 回调调用时机错误:代码在wifi.scan异步流程外、所有业务逻辑执行前就触发了callback(this.RESULT_SUCCESS),此时协议栈已经关闭了本次写入的会话通道,后续异步流程里的操作都无法完成数据回传。
  • 业务判断逻辑错误:通过forEach遍历网络列表时,只要碰到一个不匹配目标SSID的网络就触发错误回传,实际需要遍历完全部列表,确认所有扫描到的网络都不存在目标SSID时,才能判定为匹配失败。
  • 遗漏了Bleno外设主动发数据的正确通道:Bleno里外设给手机端回传业务数据,不能依赖写入请求的回调,必须通过特征自带的通知/指示能力,调用updateValue方法主动推送。

正确实现步骤

  1. 校验特征定义:确保当前使用的读写特征,在初始化配置时就开启了notify(通知)或indicate(指示)属性,没有这个属性就算推送数据,手机端也无法接收。
  2. 调整回调位置:将onWriteRequest的协议层回调移动到所有异步业务逻辑执行完成的节点再触发,避免提前关闭写入会话。
  3. 替换回传通道:所有需要发送给手机的业务状态、错误信息,统一通过特征实例的updateValue(数据Buffer, false)方法推送。
  4. 修正SSID匹配逻辑:先遍历完所有扫描到的网络列表,通过布尔标记记录是否存在匹配的目标SSID,遍历完成后再生成对应回传数据。

修正后的参考代码

// 特征初始化时需包含notify属性,示例配置参考:
// this.properties = ['read', 'write', 'notify']
WriteReadCharacteristic.prototype.onWriteRequest = function(data, offset, withoutResponse, callback) {
    const output = Buffer.from(data, 'hex');
    let payload = {};
    if (hasJsonStructure(String(output))) {
        payload = JSON.parse(String(output));
    }

    wifi.scan((error, networks) => {
        if (error) {
            console.log('WiFi扫描异常', error);
            // 扫描异常时生成错误包,通过通知推给手机
            const errBuffer = Buffer.alloc(4);
            errBuffer.writeUInt32LE(this.RESULT_SCAN_FAIL);
            this.updateValue(errBuffer, false);
            // 给协议栈返回写入处理完成的状态
            callback(this.RESULT_SUCCESS);
            return;
        }

        // 遍历所有网络,判断目标SSID是否存在
        let ssidMatched = false;
        networks.forEach(network => {
            if (payload.ssid === network.ssid) {
                ssidMatched = true;
            }
        });

        if (ssidMatched) {
            console.log("Success, wifi found");
            // 匹配成功时推送成功状态给手机
            const successBuffer = Buffer.alloc(4);
            successBuffer.writeUInt32LE(this.RESULT_SUCCESS);
            this.updateValue(successBuffer, false);
        } else {
            console.log("Failed, not found");
            // 匹配失败时推送错误状态给手机
            const failBuffer = Buffer.alloc(4);
            failBuffer.writeUInt32LE(this.RESULT_UNLIKELY_ERROR);
            this.updateValue(failBuffer, false);
        }

        // 所有业务逻辑走完,最后触发协议层回调
        callback(this.RESULT_SUCCESS);
    });
};

注意事项:手机端需在nRF Connect中先点击对应特征的订阅按钮,开启通知接收权限,才能收到外设推送的回传数据;代码中原先使用的new Buffer(31)是Node.js已废弃的API,替换为Buffer.alloc()可避免潜在的内存安全问题。

内容的提问来源于stack exchange,提问作者Dizio Adil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.10 01:15:10