Overview
TAK Can devices form an ad-hoc mesh network using Apple's MultipeerConnectivity framework (WiFi Direct + Bluetooth) and a custom BLE GATT service for background operation. All CoT messages β position reports, chat, emergency alerts β flow over the mesh exactly as they would over a server connection.
Communication Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TAK Can Mesh Network β
β β
β ββββββββββββ MultipeerConnectivity ββββββββββββ β
β β Device A ββββββββββββββββββββββββββΊβ Device B β β
β β (iPhone) β WiFi Direct / BLE β (iPhone) β β
β β β DTLS encrypted β β β
β ββββββ¬ββββββ ββββββ¬ββββββ β
β β β β
β β BLE GATT (background) β β
β β AES-GCM encrypted (PSK) β β
β β β β
β ββββββ΄ββββββ multi-hop relay ββββββ΄ββββββ β
β β Device C ββββββββββββββββββββββββββΊβ Device D β β
β β (iPad) β TTL-based routing β (iPhone) β β
β ββββββββββββ ββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Discovery Protocol
When mesh is enabled, each device advertises and browses for the service type takcan-mesh. On connection, devices exchange a discovery message:
{
"type": "discovery",
"id": "a1b2c3d4-...",
"origin": "DEVICE-UID-001",
"ttl": 2,
"hopCount": 0,
"timestamp": "2026-04-06T14:30:00Z",
"payload": {
"callsign": "ALPHA-1",
"team": "Cyan",
"role": "Team Lead",
"deviceUid": "DEVICE-UID-001",
"onboarded": true
}
}
The onboarded flag indicates whether the device has completed TAK server enrollment. This is critical for bridge security.
CoT Message Relay
Position reports, chat, and emergency alerts are wrapped in a mesh envelope:
{
"type": "cot",
"id": "e5f6g7h8-...",
"origin": "DEVICE-UID-001",
"ttl": 3,
"hopCount": 0,
"timestamp": "2026-04-06T14:30:05Z",
"payload": "<event version=\"2.0\" uid=\"DEVICE-UID-001\" type=\"a-f-G-U-C\"
time=\"2026-04-06T14:30:05Z\" start=\"...\" stale=\"...\">
<point lat=\"45.4215\" lon=\"-75.6972\" hae=\"70\" ce=\"10\" le=\"10\"/>
<detail>
<contact callsign=\"ALPHA-1\"/>
<__group name=\"Cyan\" role=\"Team Lead\"/>
</detail>
</event>"
}
Multi-Hop Relay Logic
- Device receives mesh message
- Check
idagainst seen-set (8-minute expiry) β drop if duplicate - Process locally (parse CoT, update map)
- If
ttl > 0and relay is enabled:- Decrement
ttl, incrementhopCount - Forward to all connected peers except the sender
- Decrement
Device A ββ(ttl=3)βββΊ Device B ββ(ttl=2)βββΊ Device C ββ(ttl=1)βββΊ Device D
β
(ttl=0, stop)
Bridge Mode
A device with both mesh and server connectivity acts as a bridge:
ββββββββββββ ββββββββββββ ββββββββββββββ
β Device A ββββmeshββββΊ β Device B ββββTLSββββΊ β TAK Server β
β (no net) β ββββmeshββ β (bridge) β ββββTLSββ β β
ββββββββββββ ββββββββββββ ββββββββββββββ
Mesh β Server: B forwards A's CoT to server
Server β Mesh: B forwards server CoT to A
Bridge Security
Only CoT from onboarded peers is forwarded to the server. Non-onboarded devices can communicate on the mesh but their data never reaches the server. This prevents unauthenticated devices from accessing the TAK network indirectly.
| Scenario | Mesh Chat | See on Map | Bridge to Server |
|---|---|---|---|
| Both onboarded | β | β | β |
| One not onboarded | β | β | β blocked |
| Both not onboarded | β | β | β neither bridges |
BLE Background Mesh
MultipeerConnectivity suspends when the app is backgrounded. The BLE mesh layer (CoreBluetooth GATT) maintains connectivity:
- Custom GATT service with CoT, discovery, and auth characteristics
- Message fragmentation: CoT messages split into 480-byte chunks (BLE MTU limit), reassembled on receipt
- AES-GCM encryption when PSK is configured
- Auto-reconnect with exponential backoff on disconnect
PSK Authentication & Encryption
Key Distribution:
1. Mission commander generates 256-bit PSK
2. PSK encoded as QR code: takcan-mesh-psk://<base64key>
3. Team devices scan QR at mission start
4. Key stored in iOS Keychain (ThisDeviceOnly)
Authentication (BLE connect):
Peripheral β Central: 32-byte random nonce
Central β Peripheral: HMAC-SHA256(nonce, PSK)
Peripheral verifies HMAC β accept or reject
Data Encryption:
All BLE CoT data encrypted with AES-256-GCM using the PSK
Nonce generated per message (12 bytes, random)
Tag appended for integrity verification
Mesh Modes
| Mode | Send | Receive | Bridge | Use Case |
|---|---|---|---|---|
| Listen | β | β | β (serverβmesh) | Cautious operator β see peers without revealing position. Notification on peer connect. |
| Active | β | β | β (both ways) | Full mesh participation β send and receive. |
In Listen mode, you receive all CoT from mesh peers and see them on your map, but your own position is not broadcast. When a peer connects, you receive a notification β tap to switch to Active mode when ready. Bridge mode works in Listen mode: server data is forwarded to mesh peers even when not sending your own SA.
Power Modes
| Mode | BLE Scan | BLE Advertise | Battery |
|---|---|---|---|
| Full | Always | Always | Highest |
| Balanced | 30s on / 60s off | Always | Medium |
| Low Power | Off | Always | Minimal |
Bridge devices auto-override to Full power when active with peers. Advertising is always on in all modes β your device remains discoverable even in Low Power.
Team Filter
When enabled (default), devices only connect to peers advertising the same team name. This prevents unintentional SA leakage between units operating in the same area. The team name is included in the MultipeerConnectivity discovery info and verified on both the browser and advertiser sides.