使用protobufjs和离子电容BLE插件写入ESP32 GATT特性时,写入特性失败错误



从Angular(使用Ionic)构建Android应用程序来扫描BLE设备(ESP32芯片)并写入其GATT特性。使用电容BLE插件进行BLE通信,protobufjs创建消息(因为ESP32代码使用Google的Protocol Buffer机制来接受消息)。在三星Galaxy Tab A7上部署应用程序,Get"写入特性失败";执行BLEClient时的错误信息。写,却不明白为什么会失败。下面是我的代码(当用户单击按钮时调用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。原文件看起来像:

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应用开发,因为我没有这方面的经验,而且时间紧迫。另外,我对协议缓冲机制也不是很熟悉,所以我希望得到一些指导。

使用Google的javascript协议缓冲代码解决了这个问题。不知道如何使用protobufjs创建正确的消息格式。创建,特别是因为消息需要模拟嵌套对象。下面是为我工作的代码:

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。而对应的pb.js文件(通过运行protoc创建)名为wifi_config_pb.js。

用于创建要传输的数据的函数在pb.js文件中定义,并对应于proto文件中定义的对象。如果你对这个机制的工作原理没有很好的理解,下面的参考文献会有很大的帮助:

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

Protocol Buffers in Ionic (stack question)

如果你有任何问题,请留言给我。

最新更新