# btleplug Integration Test Peripherals
This directory contains BLE test peripheral implementations for btleplug's integration test suite. Both implementations expose an identical GATT profile that the Rust tests in `tests/` exercise.
## Quick Start
### Option A: Hardware (Zephyr)
The Zephyr firmware supports multiple boards. Pick whichever you have.
**Prerequisites:**
- [Zephyr SDK](https://docs.zephyrproject.org/latest/develop/getting_started/index.html) and `west` tool
- One of the supported boards:
- [nRF52840 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF52840-DK) — also needs [nRF Command Line Tools](https://www.nordicsemi.com/Products/Development-tools/nRF-Command-Line-Tools)
- [ESP32-S3 DevKitC](https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s3/esp32-s3-devkitc-1/) — also needs `esptool` (`pip install esptool`)
**Build and flash:**
```bash
cd zephyr
# nRF52840 DK
west build -b nrf52840dk/nrf52840
west flash
# ESP32-S3 DevKitC
west build -b esp32s3_devkitc/esp32s3/procpu
west flash
```
The board boots and immediately starts advertising as `"btleplug-test"`.
**Run integration tests:**
```bash
# From the btleplug repo root:
cargo test --test '*' -- --ignored
```
### Option B: Virtual Peripheral (Bumble)
**Prerequisites:**
- Python 3.10+
- A USB BLE dongle (separate from the host's built-in BLE adapter)
- `libusb` (`brew install libusb` on macOS, `apt install libusb-1.0-0` on Linux)
**Setup:**
```bash
cd bumble
pip install -r requirements.txt
```
**Run:**
```bash
./run.sh usb:0 # USB dongle (most common)
./run.sh hci-socket:0 # Linux HCI socket (requires sudo)
```
**Run integration tests** (in another terminal):
```bash
cargo test --test '*' -- --ignored
```
## GATT Test Profile
Both peripherals implement an identical GATT profile. The canonical UUID definitions are in `tests/common/gatt_uuids.rs` (Rust) and mirrored in `zephyr/src/gatt_profile.h` (C) and `bumble/test_peripheral.py` (Python).
### Services
| Control Service | `00000001-b5a3-f393-e0a9-e50e24dcca9e` | Command interface to control peripheral behavior |
| Read/Write Test | `00000002-b5a3-f393-e0a9-e50e24dcca9e` | Read and write characteristic operations |
| Notification Test | `00000003-b5a3-f393-e0a9-e50e24dcca9e` | Notify and indicate operations |
| Descriptor Test | `00000004-b5a3-f393-e0a9-e50e24dcca9e` | Descriptor read/write operations |
### Control Commands
Write these opcodes to the Control Point characteristic (`00000101-...`):
| `0x01` | Start Notifications | Begin periodic notifications (1 Hz) |
| `0x02` | Stop Notifications | Stop all periodic notifications |
| `0x03` | Trigger Disconnect | Peripheral disconnects after 500ms |
| `0x04` | Change Advertisements | Rotate advertisement data |
| `0x05` | Reset State | Stop notifications, clear all buffers |
| `0x06` | Set Notification Payload | Remaining bytes become the notification payload |
## Environment Variables
| `BTLEPLUG_TEST_PERIPHERAL` | `btleplug-test` | Override the peripheral name to discover |
## Troubleshooting
### Tests can't find the peripheral
1. **Verify the peripheral is advertising:** Use a BLE scanner app (nRF Connect, LightBlue) to confirm `"btleplug-test"` appears.
2. **Check Bluetooth adapter:** Ensure your host has a working BLE adapter. On Linux, run `hciconfig` or `bluetoothctl show`.
3. **Check permissions:** On Linux, you may need to run tests with `sudo` or add your user to the `bluetooth` group.
4. **Increase scan timeout:** If the peripheral takes a while to appear, the default 10-second scan timeout in `peripheral_finder.rs` may need extending.
### Zephyr build fails
1. **Verify Zephyr SDK:** Run `west --version` and `cmake --version`.
2. **Verify board target:** Board targets use slashes, not underscores (e.g. `nrf52840dk/nrf52840`, `esp32s3_devkitc/esp32s3/procpu`).
3. **Clean build:** `west build -b <board> --pristine`
4. **ESP32 first build:** The Espressif HAL is large — first build takes significantly longer than subsequent builds. This is normal.
### Bumble can't find USB dongle
1. **Check connection:** `lsusb` (Linux) or `system_profiler SPUSBDataType` (macOS).
2. **Check libusb:** `python -c "import usb.core; print(list(usb.core.find(find_all=True)))"`
3. **Permissions:** On Linux, you may need udev rules for your dongle. On macOS, the dongle should work out of the box.
### Tests pass with hardware but fail with Bumble
Some tests are sensitive to hardware timing:
- **RSSI tests:** Bumble may not provide realistic RSSI values.
- **MTU tests:** MTU negotiation behavior may differ.
- **Connection parameter tests:** May not be supported over virtual transport.
These tests should pass with the nRF52840 DK.