# Exercise 304: microReticulum BLE dual-role Link ping-pong

This exercise keeps the Reticulum behavior from Exercise 303, but removes the fixed BLE central/peripheral split.

Every board runs the same firmware image. Each node starts both sides of the ESP32 BLE interface:

```text
BLE advertiser/server + BLE scanner/client
```

The nodes advertise a Reticulum BLE service name derived from the full ESP32 MAC, such as `RNS-Node-48CA435A93DD`. When two nodes see each other, the lower BLE address initiates the BLE GATT client connection and the other node remains available as the server. This deterministic tie-breaker avoids both boards trying to connect to each other at the same time.

After the BLE connection is established, the Reticulum flow is the same as Exercise 303:

```text
BLE GATT connection -> Identity -> SINGLE destination -> announce -> peer learns identity/path -> LINKREQUEST/LRPROOF handshake -> ACTIVE Link -> link DATA packets
```

Startup order should not matter for this exercise. Either board can be reset first.

## Build, Upload, And Monitor

Use the neutral `tbeam` environment when you want the exact same compiled firmware image on both boards. The board identity is derived at runtime from the ESP32 MAC address.

In one console:

```bash
source /home/jlpoole/rnsenv/bin/activate
cd /usr/local/src/microreticulum/microReticulumTbeam
pio run -d exercises/304_microReticulum_ble_dual_role_ping_pong -e tbeam -t upload --upload-port /dev/ttytAMY && \
pio device monitor -p /dev/ttytAMY -b 115200
```

In another console:

```bash
source /home/jlpoole/rnsenv/bin/activate
cd /usr/local/src/microreticulum/microReticulumTbeam
pio run -d exercises/304_microReticulum_ble_dual_role_ping_pong -e tbeam -t upload --upload-port /dev/ttytBOB && \
pio device monitor -p /dev/ttytBOB -b 115200
```

The `amy`, `bob`, `cy`, `dan`, and `ed` environments remain as upload/monitor aliases. They do not define BLE role or node label, but separate PlatformIO environments can still produce different `.bin` hashes because the environment path/name can appear in compiled artifacts. For strict same-binary testing, use `-e tbeam` for every board.

The shorter alias form should also work once the symlinks exist:

```bash
pio run -d exercises/304_microReticulum_ble_dual_role_ping_pong -e amy -t upload
pio device monitor -d exercises/304_microReticulum_ble_dual_role_ping_pong -e amy
```

## Expected Output

Each board derives a node label from its MAC and starts dual-role BLE:

```text
Node=Node-48CA435A93DD
BLE role=dual-role service=37145b00-442d-4a94-917f-8f42c5da28e3
BLE dual-role: local addr=48:ca:43:5a:93:dd label=Node-48CA435A93DD
BLE dual-role: starting advertiser and scanner
```

One side will decide it should initiate the BLE connection:

```text
BLE dual-role: peer candidate found: 48:ca:43:5b:bf:69 label=Node-48CA435BBF69
BLE dual-role: connected and identity handshake sent
```

The other side remains the server and accepts it:

```text
BLE dual-role: central connected to local server
BLE dual-role: identity handshake received by local server
```

Then Reticulum announces, opens the negotiated Link, and exchanges payloads:

```text
TX ANNOUNCE: Node-48CA435A93DD
RX ANNOUNCE: label=Node-48CA435BBF69 hash=...
TX LINKREQUEST: opening link to Node-48CA435BBF69
LINK ACTIVE: initiator link established
TX LINK BLE: Node-48CA435A93DD -> Node-48CA435BBF69 iter=0
RX LINK BLE: Node-48CA435BBF69 -> Node-48CA435A93DD iter=0
```
![](../../img/20260519_144250_Tue.png)
## Notes

- This is the first equal-peer BLE transport exercise in the 300 series.
- Equal-peer means equal at the BLE transport startup layer. The BLE interface uses address ordering to decide which side initiates the GATT connection, and Reticulum still uses label ordering to decide which node opens the first Link.
- The next natural exercise is simultaneous text transfer over this same dual-role Link foundation, with the text corpus selected from `platformio.ini`.
