BMR11/ble-validation-platform

GitHub: BMR11/ble-validation-platform

一个基于配置文件的BLE设备模拟平台,用于加速医疗和IoT设备的开发、测试和验证,减少对物理硬件的依赖。

Stars: 10 | Forks: 0

BLE validation platform logo

# BLE验证平台 用于连接系统的、基于配置文件的BLE模拟、故障注入与验证平台。 它包含一个 React Native **外设** 应用(GATT服务器),一个 React Native **中心** 应用(扫描器/GATT客户端),可复用的 **JSON设备配置文件**,以及通过真实BLE通信进行本地或远程配置文件加载。 ## 🚀 为什么需要它 BLE开发工作通常要求合适的硬件、固件版本和设备状态同时就绪。 这个项目为团队提供了一种方式,可以明确地定义这些行为,重现它们,并在更早的阶段验证应用与设备的边界。 它是 BLE验证平台三部曲系列 的实现: - [第1部分:别再等待硬件了](https://medium.com/@rajnibhaimgediya/stop-waiting-for-hardware-rethinking-how-we-build-and-validate-ble-systems-65d22a8b5871) - [第2部分:设计基于配置文件的BLE系统](https://medium.com/@rajnibhaimgediya/designing-profile-driven-ble-systems-architecture-and-execution-1ba02f94a73e) - [第3部分:从模拟到验证](https://medium.com/@rajnibhaimgediya/from-simulation-to-validation-building-reliable-ble-systems-at-scale-12ede42a1f5c) ## 🚀 实现功能 - 在硬件就绪前模拟BLE外设 - 注入可重复的故障和边缘案例场景 - 通过真实BLE通信端到端地验证中心应用行为 ## 概述 本文档展示了如何模拟蓝牙低功耗设备行为,如何注入故障条件,以及如何使用真实的移动应用进行端到端的系统行为验证。 其目标并非取代物理硬件测试,而是为了减少开发与验证工作被硬件可用性阻碍的频率,同时仍使用真实的BLE通信。 这项工作的灵感来自于在生产环境中构建和验证支持BLE的系统的真实经验。 ## 问题 BLE开发和测试通常**依赖物理硬件**来覆盖每个场景。这既昂贵、难以并行化,在CI中也很笨拙。重现诸如电量耗尽、错误状态或Nordic风格的LED/按钮服务等边缘案例,通常需要多台设备和手动设置。 其他挑战包括: - 硬件在环(HIL)设置成本高且难以扩展 - 在固件/硬件未就绪时(原型/EVT阶段)开发受阻 - 跨多台设备的并行验证受限 - 故障场景难以确定性地重现 ## 项目功能 - 通过可复用的JSON配置文件定义BLE设备 - 在真实的BLE外设上运行基于配置文件的行为 - 在中心与外设应用之间使用真实的BLE通信 - 重现仅靠硬件难以复现的验证场景 - 支持本地捆绑的配置文件和远程管理的配置文件版本 ## 解决方案 本仓库提供: - [`profiles/local/`](profiles/local/) 目录下的**JSON配置文件**(以及可选的远程副本),用于描述服务、特征、广播、可选状态机和UI提示。 - 一个**外设**React Native应用,加载这些配置文件(本地捆绑或HTTP),应用`valueGenerator`扩展,并通过`rn-ble-peripheral-module`运行它们(逻辑已从上游`test-pripheral-config-profile-mar23`分支的示例中迁移)。 - 一个使用`react-native-ble-manager`的**中心**React Native应用,用于扫描、连接、读取**设备信息服务**字段、订阅和写入(Nordic LED)——证明端到端通信。 - **`remote-profile/`** — Vite + Express 演示,用于**服务器驱动的配置文件**:按`profileId`版本化、发布和拉取**最新发布的**JSON到外设,无需更改应用代码。 本仓库展示了一种面向**平台**的BLE模拟与验证方法。 它实现了: ### 🚀 加速开发 - 即使固件/硬件未就绪也能模拟BLE外设 - 在原型和EVT阶段实现早期集成 ### 🧪 可扩展的QA与验证 - 在廉价设备(Android/iOS/Mac)上运行多个模拟外设 - 无需复杂硬件设置即可并行测试 ### 💰 降低HIL(硬件在环)测试成本 - 消除对昂贵物理设置的依赖 - 使用现有移动设备模拟BLE外设 ### 🔍 改进调试 - 设备端日志提供BLE通信的可见性 - 有助于实时诊断问题 ### ⚡ 灵活的设备建模 - 基于配置文件的系统允许: - 在不同设备类型间切换 - 使用同一应用测试多种配置 ## 🚀 从哪里开始 - 刚接触这个想法?从[第1部分](https://medium.com/@rajnibhaimgediya/stop-waiting-for-hardware-rethinking-how-we-build-and-validate-ble-systems-65d22a8b5871)开始。 - 正在思考架构?阅读[第2部分](https://medium.com/@rajnibhaimgediya/designing-profile-driven-ble-systems-architecture-and-execution-1ba02f94a73e)。 - 专注于测试和验证?阅读[第3部分](https://medium.com/@rajnibhaimgediya/from-simulation-to-validation-building-reliable-ble-systems-at-scale-12ede42a1f5c)。 然后运行本README中的演示流程,查看中心应用如何通过BLE连接到基于配置文件的外设。 ## 工作原理 该平台遵循一个简单的流程: ``` profile -> execution engine -> BLE peripheral -> central app interaction ``` 一个配置文件描述了设备名称、服务、特征、值、生成器以及可选的状态行为。 外设应用加载该配置文件,展开动态值,并通过设备BLE协议栈暴露结果。中心应用扫描、连接、读取、订阅和写入,就像对待物理设备一样。 这不是一个模拟API。交互仍然通过真实的BLE通信进行。 ## 社区洞察 在实践中,BLE团队很少在仅使用模拟或仅使用硬件之间做选择。大多数团队需要混合使用。 模拟速度快,对应用逻辑有用,但它们无法测试BLE协议栈。硬件能给出最真实的信号,但难以扩展且难以强制覆盖每个边缘案例。基于配置文件的外设介于这两者之间:足够可控以支持可重复的验证,同时仍接近真实的BLE行为。 一个实际的挑战是随着服务、特征和行为的变化,保持模拟与固件同步。本仓库包含了本地配置文件和远程配置文件演示来探索这个问题,但固件-配置文件同步仍然是一个未来的方向。 最棘手的问题通常出现在移动应用与固件的边界:时序、重连、通知行为、触发状态变化的写入操作,以及应用在不同界面间切换时数据的变化。本项目旨在使这些交互更易于重现和讨论。 ## 包含内容 - **`profiles/local/`**:用于演示设备的捆绑JSON配置文件。 - **`peripheral-app/`**:使用`rn-ble-peripheral-module`执行配置文件的React Native GATT服务器。 - **`central-app/`**:使用`react-native-ble-manager`的React Native BLE中心应用。 - **`remote-profile/`**:Vite + Express 演示,用于版本化、服务器驱动的配置文件。 - **`docs/`**:架构说明、配置文件模式、远程配置文件文档和演示流程。 ## 验证场景 该平台可以模拟难以手动重复的场景: - 变化的传感器值 - 电量耗尽和低电量状态 - 突然断开连接 - 延迟或异常的通知 - 协议不一致或意外值 - 交互驱动的行为,如LED写入或按钮通知 这些场景有助于验证中心应用在真实硬件上的每个用例都可用之前的行为。 ## 故障与边缘案例测试 该平台能够受控地模拟难以使用真实硬件复现的场景: - 突然断开连接 - 电量耗尽和低电量状态 - RSSI波动 - 高频或异常的通知 - 协议不一致或无效数据 这些场景有助于验证中心应用在真实世界故障条件下的行为。 ## 🔄 高级验证场景 这种方法支持测试复杂的BLE工作流程,包括: - 空中下载固件更新流程 - 重连和恢复处理 - 实时数据流验证 - 设备异常行为下的压力测试 ## 本地配置文件 vs 远程配置文件 | 模式 | 来源 | 何时使用 | |------|------|----------| | **本地** | `profiles/local/*.json`,捆绑在外设应用中 | 默认,离线,CI友好的基线 | | **远程** | `remote-profile` HTTP API (`GET /api/profiles`, `GET /api/profiles/:id/latest`) | 演示集中管理、版本历史、发布/草稿工作流 | 远程模式使用与本地JSON**相同**的`applyValueGenerators` + `ProfileEngine`管道。详情请参阅:[docs/remote-profiles.md](docs/remote-profiles.md)。 **固件同步**(OTA、从固件自动导入等)**尚未实现**;在[remote-profile/README.md](remote-profile/README.md)中被记录为未来方向。 ## 📚 文章与深入探讨 本项目附有一系列详细的技术文章: - [别再等待硬件了:重新思考BLE开发](https://medium.com/@rajnibhaimgediya/stop-waiting-for-hardware-rethinking-how-we-build-and-validate-ble-systems-65d22a8b5871) - [设计基于配置文件的BLE系统](https://medium.com/@rajnibhaimgediya/designing-profile-driven-ble-systems-architecture-and-execution-1ba02f94a73e) - [从模拟到验证:构建可靠的BLE系统](https://medium.com/@rajnibhaimgediya/from-simulation-to-validation-building-reliable-ble-systems-at-scale-12ede42a1f5c) 这些文章解释了本平台背后的**架构、动机和实际用例**。 ## 架构概述 ble-excalidraw - **外设** (`peripheral-app/`):从 `../profiles/local/*.json` 加载本地捆绑配置文件和/或从 remote-profile 获取;执行 `ProfileEngine`。 - **中心** (`central-app/`):用户选择一个演示目标(心率 vs Nordic LBS),按服务UUID扫描,连接,将DIS读入一个可展开的**信息**面板,发现服务,订阅,为Nordic设备写入LED。 - **远程配置文件** (`remote-profile/`):React 管理界面 + Express API + JSON文件存储 — 参见 [remote-profile/README.md](remote-profile/README.md)。 更多详情:[docs/architecture.md](docs/architecture.md)。 ## 文件夹结构 ``` ble-validation-platform/ peripheral-app/ central-app/ remote-profile/ client/ # Vite React admin server/ # Express API + JSON persistence profiles/ local/ # Bundled JSON (heart-rate, nordic-lbs) remote/ # Docs / optional exported samples automation/ docs/ README.md ``` ## 安装设置 要求:**Node 18+**,**JDK 17**(用于Android),Xcode + CocoaPods(用于iOS中心应用构建)。 1. **外设应用** ```bash cd peripheral-app npm install cp .env.example .env ``` 编辑 **`.env`**:为连接Wi‑Fi的实体手机设置 **`REMOTE_PROFILE_LAN_HOST`**(参见 [docs/remote-profiles.md](docs/remote-profiles.md))。切勿提交 **`.env`** 文件。更改 **`.env`** 后,重启Metro;如果远程URL看起来仍不正确,使用 `yarn start --reset-cache` 或 `npm start -- --reset-cache`。 该应用通过 `file:../local_modules/rn-ble-peripheral-module` 依赖本地库(路径相对于 `peripheral-app/`)。 2. **中心应用** ```bash cd central-app npm install ``` 3. **远程配置文件**(可选,用于服务器驱动的配置文件) ```bash cd remote-profile/server && npm install && cp .env.example .env && npm run dev cd remote-profile/client && npm install && npm run dev ``` 可选的 **`server/.env`** 仅覆盖 `PORT` / `HOST`。登录凭据:`demo@example.com` / `demo123`(仅限公共演示 — 参见 [docs/remote-profiles.md](docs/remote-profiles.md))。 4. **iOS(仅中心应用,或如果你添加iOS用途也包括外设应用)** ```bash cd central-app/ios && bundle install && bundle exec pod install && cd ../.. ``` ## 运行 peripheral-app ``` cd peripheral-app npm start # echnical jargon. Similarly, "native dependency" – keep it as "native dependency". "change" can be translated as "更改" or "变更". So, the phrase could be "每次clone或native dependency更改时". npm run android ``` 流程: 1. 授予蓝牙权限(Android 12+:广播 + 连接)。 2. **配置文件来源**:**本地**(默认)或**远程**(需要 remote-profile 服务器)。 3. 对于**远程**模式:点击**获取远程配置文件**,然后选择一行(加载**最新发布的**)。 4. 点击**启动外设**。 5. 在**日志面板**中观察广播、服务注册、读写操作和状态转换。 **远程API URL** 来自 **`peripheral-app/.env`**(`REMOTE_PROFILE_LAN_HOST` 或 `REMOTE_PROFILE_TUNNEL_BASE`)— 参见 [docs/remote-profiles.md](docs/remote-profiles.md)。 ## 运行 central-app ``` cd central-app npm install # But to make it grammatically correct in Chinese, I need to adjust the structure. The original has "once per clone / native dependency change", which might mean "once per clone or native dependency change". So in Chinese: "每次clone或native dependency更改时". npm run pod-install npm start npm run android # - "iOS (simulator example; physical device needs a signing Team in Xcode)": "iOS" keep in English. "simulator example" – "simulator" is a technical term, often kept as "simulator" in Chinese tech contexts, but it can be translated as "模拟器". The instruction says to keep technical jargon in English, so I should keep "simulator" as "simulator"? However, in common usage, "simulator" is often translated. To be safe, I'll check the examples: in the given examples, terms like "Naabu", "Kubernetes", "API" are kept in English. "simulator" might be considered a tool or technical term, but it's more generic. I think it's acceptable to translate it. Let's see the context: it's part of "simulator example", so I can translate "example" as "示例", and "simulator" as "模拟器". But the instruction says "keep all professional terms... in their original English form." Is "simulator" a professional term? It might be, but in this heading, it's likely referring to the iOS simulator, which is a tool. I'll lean towards keeping it in English to be consistent with "Xcode" which is a proper noun. Actually, "simulator" here is part of "simulator example", so perhaps "模拟器示例" is fine, but to be precise, I'll keep "simulator" in English if it's a tool name. However, "iOS Simulator" is a proper tool in Xcode, so it might be kept as "iOS Simulator". But the heading says "simulator example", so it's describing an example with the simulator. I think for clarity, I'll translate "example" but keep "simulator" as is? Let's decide. npm run ios -- --simulator "iPhone 16" ``` 有关CocoaPods区域设置问题、**`BleCentralDemo.xcworkspace`** 以及在真实iPhone上的**签名与功能**设置,请参阅 [central-app/README.md](central-app/README.md)。 流程: 1. 选择**目标配置文件**(与 `profiles/local/` 中的ID匹配)。 2. **扫描(8秒)** — 按该配置文件的主服务UUID过滤。 3. 点击设备行进行**连接**(扫描停止;**目标**和**扫描**按钮保持禁用状态直到断开连接)。 4. 展开设备卡片上的**信息**,查看**DIS**字符串(制造商、型号、序列号、固件等,如果外设暴露了的话)。 5. 观察**实时指标**和**日志**(心率 + 电量,或 Nordic 按钮 + **LED 开启** / **LED 关闭**写入)。 ## 配置文件 | 文件 | ID | 广播名称(典型) | 备注 | |------|-----|------------------|------| | `profiles/local/heart-rate.json` | `heart-rate-monitor` | `RN_BLE_HR_Demo` | 心率服务 (0x180D),电池服务 (0x180F),DIS,状态机,用于心率和电量模拟的 `valueGenerator`。 | | `profiles/local/nordic-lbs.json` | `nordic-lbs` | `My_LBS` | Nordic LBS UUID,按钮通知,LED写入,电池服务。 | 模式和 `valueGenerator` 键:[docs/profile-schema.md](docs/profile-schema.md)。 **远程播种历史**(v1 vs v2 的故事)在 [docs/profile-versioning.md](docs/profile-versioning.md) 中有描述。 ## 文档索引 - [docs/README.md](docs/README.md) — 文档地图和建议的阅读路径。 - [docs/remote-profiles.md](docs/remote-profiles.md) — 服务器驱动的配置文件概念和外设集成。 - [docs/remote-profile-api.md](docs/remote-profile-api.md) — HTTP API 参考。 - [docs/profile-versioning.md](docs/profile-versioning.md) — 草稿/发布/最新规则。 - [docs/demo-flows.md](docs/demo-flows.md) — 端到端流程。 ## 演示流程(端到端) 有关两部手机和可选错误状态测试的分步说明,请参阅 [docs/demo-flows.md](docs/demo-flows.md)。 简要版本: 1. 启动 **peripheral-app** → 选择配置文件 → **启动外设**。 2. 启动 **central-app** → 选择匹配的目标 → **扫描** → **连接**。 3. 在UI和日志中确认**通知**,可选**信息(DIS)**,以及 **LED 开启** 然后 **LED 关闭**(对于Nordic设备)。 https://github.com/user-attachments/assets/f006b81c-21bd-40e6-8a2f-f46200ce6cea ## 使用场景 - **BLE测试** — 无需自定义固件即可实现可重复的外设行为。 - **物联网开发** — 原型验证应用对标准及供应商特定GATT布局的反应。 - **医疗/可穿戴设备验证** — 以受控方式测试心率配置文件风格的服务和状态转换(不用于临床认证;仅用于演示/教育目的)。 ## 🌍 适用性 这种方法适用于依赖BLE连接系统的各行各业,包括: - 医疗保健和医疗设备 - 可穿戴技术 - 物联网平台 - 工业和传感器系统 ## ⚠️ 免责声明 本平台旨在用于**开发、模拟和验证工作流**,并不能替代使用真实硬件设备进行的测试。 虽然它能够受控地模拟BLE行为和故障场景,但**最终使用实际设备进行验证仍然至关重要**,特别是在生产环境和受监管环境中。 这种方法旨在通过以下方式补充传统的基于硬件的测试: - 实现更早的开发和集成 - 通过可重现的场景提高测试覆盖率 - 在开发和QA期间减少对物理设置的依赖 ## 🔮 未来方向 - **自动化**:编排中心和外设应用,并使用像 [Agent Device (Callstack)](https://github.com/callstack/agent-device) 这样的工具端到端地验证行为,实现可重复且可扩展的BLE验证工作流。 - **固件-配置文件同步平台**:实现设备固件与BLE配置文件之间的自动同步。固件中服务或特征的更改(例如通过拉取请求)可以触发CI集成的webhook管道,该管道更新或生成远程配置文件系统中的相应配置文件,保持模拟设备与真实固件行为的一致性。 - **拖放式配置文件构建器**:提供基于UI的工作流,无需代码即可创建和修改BLE配置文件,降低QA和跨职能团队的入门门槛。 - **遥测与AI驱动的配置文件生成**:捕获中心与外设设备之间真实的BLE通信轨迹,并用它们生成可重用的配置文件。未来的增强可能利用AI/ML技术推断设备行为模式,模拟真实的边缘案例,并根据观察到的系统行为自动调整配置文件。 - **云配置文件注册表**:引入一个集中式的、版本化的BLE配置文件注册表,支持访问控制,使团队能够在不同环境中共享、重用和管理设备定义。 - **高级OTA模拟**:扩展平台以模拟固件更新工作流和边缘案例,无需实际硬件更新即可验证OTA管道。 - **共享逻辑层(固件 ↔ 移动端)**:探索使用共享的基于C的逻辑层,该层可在设备固件和Android原生外设实现之间复用。这将允许核心设备行为(状态处理、值生成、交互逻辑)在两种环境中保持一致,而仅BLE传输层不同。目标是减少模拟与真实设备行为之间的差异,使验证更能代表生产系统。 - **遥测驱动的配置文件生成(AI辅助)**:捕获中心与外设设备之间的真实BLE通信轨迹,并用它们自动生成可重用的配置文件。这有助于更可靠地重现真实世界的问题,并缩小模拟与生产行为之间的差距。随着时间的推移,AI辅助方法可能有助于识别模式、生成边缘案例,并使配置文件与设备在实践中的行为保持一致。 ## 许可证 / 上游 外设BLE引擎和类型位于 [`local_modules/rn-ble-peripheral-module`](local_modules/rn-ble-peripheral-module) 下的 **`rn-ble-peripheral-module`** 供应商包中。 ## ⭐ 支持 如果这个项目对你有帮助: - ⭐ 给仓库点个星 - 🧪 在你的工作流中尝试一下 - 🤝 分享反馈 这有助于使BLE开发更加普及和可扩展。 这有助于使示例扎根于BLE团队实际遇到的问题中。
标签:BLE模拟器, GATT协议, Homebrew安装, JSON配置文件, MITM代理, React Native, SOC Prime, 医疗设备, 开发工具, 故障注入, 测试自动化, 物联网, 硬件无关开发, 移动应用开发, 系统验证, 自动化攻击, 蓝牙低功耗, 设备模拟, 验证平台