ionic-framework - 使用 protobufjs 和离子电容器 BLE 插件写入 ESP32 GATT 特性时出现写入特性失败错误
问题描述
从 Angular(使用 Ionic)构建 Android 应用程序以扫描 BLE 设备(ESP32 芯片)并写入其 GATT 特性。使用 Capacitor BLE 插件进行 BLE 通信和 protobufjs 创建消息(因为 ESP32 代码使用 Google 的 Protocol Buffer 机制来接受消息)。应用程序部署在三星 Galaxy Tab A7 上以部署应用程序。执行 BLEClient.write 时出现“写入特征失败”错误消息,并且无法理解失败的原因。这是我的代码(用户单击按钮时调用的 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 机制不太满意,因此需要一些指导。
解决方案
通过使用 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(谷歌协议缓冲区教程)
Ionic 中的协议缓冲区(堆栈问题)
如果您有任何问题,请 PM 我。
推荐阅读
- c# - 更新使用 Wix 工具集创建的 msi 中的属性
- aws-iot - AWS-IoT 主题与 $
- angular - Angular Material Table:基于两个数据库列但单个 UI 列搜索值
- laravel - laravel sanctum 上 SSR 模式 Nuxt 的认证问题
- python - 我怎么知道一个类有多少实例?
- javascript - Javascript中的数组排序
- python - 在 Python 中使用状态解析命令行
- c# - 如何让 AzureAppConfiguration 在 .NET Framework 4.7.2 MVC 应用程序上运行?
- elasticsearch - 弹性查找时间范围内记录组中的文本
- swift - 如何在 Swift 中从内存中播放 [Int16] 音频样本数组