【问题标题】:Writing characteristic failed error when writing to ESP32 GATT characteristic using protobufjs and ionic capacitor BLE plugin使用 protobufjs 和离子电容器 BLE 插件写入 ESP32 GATT 特性时出现写入特性失败错误
【发布时间】:2021-10-27 13:37:29
【问题描述】:

从 Angular(使用 Ionic)构建 Android 应用以扫描 BLE 设备(ESP32 芯片)并写入其 GATT 特性。使用 Capacitor BLE 插件进行 BLE 通信和 protobufjs 创建消息(因为 ESP32 代码使用 Google 的协议缓冲区机制来接受消息)。应用程序部署在三星 Galaxy Tab A7 上以部署应用程序。执行 BLEClient.write 时收到“Writing characteristic failed”错误消息,无法理解失败的原因。这是我的代码(用户单击按钮时调用 getBLE()):

import { load } from '../../../node_modules/protobufjs';
import { BleClient } from '@capacitor-community/bluetooth-le';

export class SetupPage implements OnInit {

  async getBLE(){
    try {
      let wifiid = 'wifiSSID';
      let password = 'somePassword';
      await load ('../../assets/wifi_config.proto')
      .then((root) => {
        var wifi_config_message = root.lookupType("wifi_config_package.CmdSetConfig");
        let message = wifi_config_message.create({
          ssid: wifiid,
          passphrase: password
        });
        let buffer1 = wifi_config_message.encode(message).finish();
        return buffer1;
      })
      .then(async buffer1 => {
        await BleClient.initialize();
        let connectedDevice = await BleClient.requestDevice();
        await BleClient.connect(connectedDevice.deviceId);
        let bufferView = await new DataView(buffer1.buffer);
        const result = await BleClient.write(connectedDevice.deviceId, '021a9004-0382-4aea-bff4-6b3f1c5adfb4', '021aff52-0382-4aea-bff4-6b3f1c5adfb4',bufferView);
      });
    }
    catch(error) {
      console.log('bluetooth error is: ', error);
    }
  }
}

这是 wifi_config.proto 文件的样子:

package wifi_config_package;
syntax = "proto3";

import "constants.proto";
import "wifi_constants.proto";

message CmdGetStatus {}

message RespGetStatus {
    Status status = 1;
    WifiStationState sta_state = 2;
    oneof state {
        WifiConnectFailedReason fail_reason = 10;
        WifiConnectedState connected = 11;
    }
}

message CmdSetConfig {
    string ssid = 1;
    string passphrase = 2;
    bytes bssid = 3;
    int32 channel = 4;
}

message RespSetConfig {
    Status status = 1;
}

message CmdApplyConfig {}

message RespApplyConfig {
    Status status = 1;
}

enum WiFiConfigMsgType {
    TypeCmdGetStatus = 0;
    TypeRespGetStatus = 1;
    TypeCmdSetConfig = 2;
    TypeRespSetConfig = 3;
    TypeCmdApplyConfig = 4;
    TypeRespApplyConfig = 5;
}

message WiFiConfigPayload {
    WiFiConfigMsgType msg = 1;
    oneof payload {
        CmdGetStatus cmd_get_status = 10;
        RespGetStatus resp_get_status = 11;
        CmdSetConfig cmd_set_config = 12;
        RespSetConfig resp_set_config = 13;
        CmdApplyConfig cmd_apply_config = 14;
        RespApplyConfig resp_apply_config = 15;
    }
}

我做错了什么?实现相同目标的任何替代方法(通过写入 GATT 特性通过 BLE 将数据发送到 ESP32)?我不想求助于原生 Android 应用程序开发,因为我没有这方面的经验,而且截止日期很短。此外,对 Protocol Buffer 机制不是很满意,因此请提供一些指导。

【问题讨论】:

    标签: ionic-framework bluetooth-lowenergy protocol-buffers capacitor protobuf.js


    【解决方案1】:

    通过使用 Google 的 javascript 协议缓冲区代码解决了这个问题。无法弄清楚如何使用 protobufjs.create 创建正确的消息格式,尤其是因为消息需要模仿嵌套对象。这是对我有用的代码:

    import * as goog from 'google-protobuf';
    export class SetupPage implements OnInit {
    
      messages = require('../../assets/proto-js/wifi_config_pb.js');
      connectedDevice: BleDevice;
      bleScan: any;
      wifiSSID: Promise<any>;
      scanResults: Promise<[]>;
      wifiCredentials: string;
      uint8String: Uint8Array;
      buffer: Uint8Array;
    
      ngOnInit() {
        async getBLE(){
          await BleClient.initialize();
          var cmdSetMessage = new this.messages.CmdSetConfig();
          var wifiConfigPayloadMessage = new this.messages.WiFiConfigPayload;
          message.setSsid('wifiid');
          message.setPassphrase('password');
          wifiConfigPayloadMessage.setCmdSetConfig(cmdSetMessage);
          wifiConfigPayloadMessage.setMsg(2);
          let bytesOfStuff = await wifiConfigPayloadMessage.serializeBinary();
          this.connectedDevice = await BleClient.requestDevice();
          await BleClient.connect(this.connectedDevice.deviceId);
          BleClient.writeWithoutResponse(this.connectedDevice.deviceId, '021a9004-0382- 
          4aea-bff4-6b3f1c5adfb4', '021aff52-0382-4aea-bff4-6b3f1c5adfb4', 
          bytesOfStuff)
      }
    }
    

    在此代码可以运行之前,您需要从 npm 或其他软件包安装程序和 protoc 或其他编译器安装 google-protobuf,以便为每个 proto 文件生成 pb.js 文件(因为我正在使用 javascript)原型文件。在本例中,proto 文件名为 wifi_config.proto,对应的 pb.js 文件(通过运行 protoc 创建)名为 wifi_config_pb.js。

    用于创建要传输的数据的函数在 pb.js 文件中定义,并对应于 proto 文件中定义的对象。如果您不了解此机制的工作原理,以下参考资料会很有帮助:

    https://developers.google.com/protocol-buffers/docs/proto3(谷歌协议缓冲区教程)

    Protocol Buffers in Ionic(堆栈问题)

    如果您有任何问题,请私信我。

    【讨论】:

      猜你喜欢
      • 2015-06-18
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多