快速开始
本指南介绍如何定义协议、生成代码以及将 bleRPC 集成到您的项目中。
1. 定义协议
创建一个 .proto 文件来定义 RPC 消息。每个命令是一个请求/响应对:
syntax = "proto3";
package blerpc;
message EchoRequest {
string message = 1;
}
message EchoResponse {
string message = 1;
}
message FlashReadRequest {
uint32 address = 1;
uint32 length = 2;
}
message FlashReadResponse {
uint32 address = 1;
bytes data = 2;
}
命令从匹配的 *Request / *Response 对中自动发现。例如,EchoRequest + EchoResponse 会生成 echo 命令。
2. 代码生成
generate-handlers 工具为所有支持的语言生成处理器桩代码和客户端代码。
构建生成器
cd tools/generate-handlers
go build -o generate-handlers .
运行代码生成
./generate-handlers -root /path/to/blerpc
这将生成以下文件:
| 输出 | 描述 |
|---|---|
peripheral_fw/src/generated_handlers.h | C 处理器声明 + 查找表 |
peripheral_fw/src/generated_handlers.c | C 弱引用处理器桩 |
peripheral_py/generated_handlers.py | Python 处理器桩 |
central_py/blerpc/generated/generated_client.py | Python 客户端 mixin |
central_android/.../GeneratedClient.kt | Kotlin 抽象客户端 |
central_ios/.../GeneratedClient.swift | Swift 客户端协议扩展 |
central_flutter/.../generated_client.dart | Dart 客户端 mixin |
central_rn/.../GeneratedClient.ts | TypeScript 抽象客户端(React Native) |
central_fw/src/generated_client.h | C central 客户端声明 |
central_fw/src/generated_client.c | C central 客户端实现 |
3. 平台集成
iOS (Swift)
依赖
通过 Swift Package Manager 添加到您的 Xcode 项目:
// Package.swift or Xcode > File > Add Package Dependencies
https://github.com/tdaira/blerpc-protocol-swift (from: 0.5.0)
https://github.com/apple/swift-protobuf.git (from: 1.28.0)
生成 Protobuf 类型
brew install swift-protobuf
protoc --swift_out=YourApp/Proto/ \
--swift_opt=Visibility=Public \
-I proto/ proto/blerpc.proto
使用方法
let client = BlerpcClient()
// Scan for peripherals
let devices = try await client.scan()
try await client.connect(device: devices[0])
// Type-safe RPC call
let response = try await client.echo(message: "hello")
print(response.message) // "hello"
// Read flash data
let flash = try await client.flashRead(address: 0, length: 8192)
print(flash.data.count) // 8192
client.disconnect()
Android (Kotlin)
依赖
添加到您的 build.gradle.kts:
repositories {
maven {
url = uri("https://maven.pkg.github.com/tdaira/blerpc-protocol-kt")
credentials { /* GitHub token */ }
}
}
dependencies {
implementation("com.blerpc:blerpc-protocol-kt:0.5.0")
}
使用方法
val client = BlerpcClient(context)
// Scan for peripherals
val devices = client.scan()
client.connect(devices[0])
val response = client.echo(message = "hello")
println(response.message) // "hello"
client.disconnect()
Python (macOS / Linux)
依赖
pip install bleak protobuf
pip install git+https://github.com/tdaira/blerpc-protocol.git
生成 Protobuf 类型
protoc --python_out=central_py/blerpc/generated/ \
-I proto/ proto/blerpc.proto
使用方法
from blerpc.client import BlerpcClient
client = BlerpcClient()
# Scan for peripherals
devices = await client.scan()
await client.connect(devices[0])
resp = await client.echo(message="hello")
print(resp.message) # "hello"
flash = await client.flash_read(address=0, length=8192)
print(len(flash.data)) # 8192
await client.disconnect()
Flutter (Dart)
依赖
添加到您的 pubspec.yaml:
dependencies:
blerpc_protocol: ^0.6.0
flutter_blue_plus: ^1.35.0
protobuf: ^6.0.0
生成 Protobuf 类型
dart pub global activate protoc_plugin
protoc --dart_out=lib/proto/ \
-I proto/ proto/blerpc.proto
使用方法
final client = BlerpcClient();
// Scan for peripherals
final devices = await client.scan();
await client.connect(devices[0]);
// Type-safe RPC call
final response = await client.echo(message: 'hello');
print(response.message); // "hello"
// Read flash data
final flash = await client.flashRead(address: 0, length: 8192);
print(flash.data.length); // 8192
client.disconnect();
React Native (TypeScript)
依赖
添加到您的 package.json:
{
"dependencies": {
"@blerpc/protocol-rn": "file:../blerpc-protocol-rn",
"protobufjs": "^7.4.0",
"react-native-ble-plx": "^3.2.1",
"react-native-get-random-values": "^1.11.0",
"buffer": "^6.0.3",
"fast-text-encoding": "^1.0.6",
"@noble/ciphers": "^1.3.0",
"@noble/curves": "^1.9.7",
"@noble/hashes": "^1.8.0"
}
}
生成 Protobuf 类型
npx pbjs -t static-module -w commonjs \
-o src/proto/blerpc.js ../proto/blerpc.proto
npx pbts -o src/proto/blerpc.d.ts src/proto/blerpc.js
使用方法
import { BlerpcClient } from './client/BlerpcClient';
import { BleTransport } from './ble/BleTransport';
const transport = new BleTransport();
const devices = await transport.scan();
const client = new BlerpcClient(transport);
await client.connect(devices[0]);
// Type-safe RPC call
const response = await client.echo({ message: 'hello' });
console.log(response.message); // "hello"
// Read flash data
const flash = await client.flashRead({ address: 0, length: 8192 });
console.log(flash.data.length); // 8192
client.disconnect();
Zephyr Central (C)
生成的客户端
代码生成器会创建 generated_client.h 和 generated_client.c,其中包含所有命令的类型化包装函数。您需要实现三个传输函数(blerpc_rpc_call、blerpc_stream_receive、blerpc_stream_send),然后调用生成的 API:
#include "generated_client.h"
// Type-safe RPC call — protobuf encode/decode is handled
blerpc_EchoResponse resp;
int ret = blerpc_echo("Hello from central!", &resp);
if (ret == 0) {
LOG_INF("Echo: %s", resp.message);
}
// Read flash data (FT_CALLBACK fields handled automatically)
blerpc_FlashReadResponse flash;
uint8_t data_buf[8192];
size_t data_len;
ret = blerpc_flash_read(0, 8192, &flash, data_buf, sizeof(data_buf), &data_len);
// P2C streaming
blerpc_CounterStreamResponse results[20];
size_t count;
ret = blerpc_counter_stream(20, results, 20, &count);
构建
west build -b nrf54l15dk/nrf54l15/cpuapp central_fw
Zephyr Peripheral (C)
实现处理器
生成的处理器使用 __attribute__((weak))。在您自己的源文件中重写它们:
// handlers.c
#include "generated_handlers.h"
#include "blerpc.pb.h"
int handle_echo(const uint8_t *req_data, size_t req_len,
pb_ostream_t *ostream) {
blerpc_EchoRequest req = blerpc_EchoRequest_init_zero;
pb_istream_t stream = pb_istream_from_buffer(req_data, req_len);
if (!pb_decode(&stream, blerpc_EchoRequest_fields, &req))
return -1;
blerpc_EchoResponse resp = blerpc_EchoResponse_init_zero;
strncpy(resp.message, req.message, sizeof(resp.message) - 1);
if (!pb_encode(ostream, blerpc_EchoResponse_fields, &resp))
return -1;
return 0;
}
构建
# nRF54L15
west build -b nrf54l15dk/nrf54l15/cpuapp peripheral_fw
# EFR32xG22E
west build -b xg22_ek2710a peripheral_fw -- -DBOARD_ROOT=/path/to/blerpc
4. 使用 Python Central 进行测试
验证 peripheral 是否正常工作的最简单方法:
# Flash the peripheral firmware
west flash
# Run the Python integration tests
cd central_py
python -m pytest tests/test_integration.py -v
或者使用交互式客户端:
python -c "
import asyncio
from blerpc.client import BlerpcClient
async def main():
client = BlerpcClient()
devices = await client.scan()
await client.connect(devices[0])
resp = await client.echo(message='hello')
print(f'Echo: {resp.message}')
await client.disconnect()
asyncio.run(main())
"