Add complete DWARFLAB protocol documentation

- Architecture overview, BLE and WebSocket protocols
- All 19 modules with command IDs validated against smali source
- BLE packet format with CRC-16/MODBUS pseudocode
- Complete WsCmd index (~300 commands)
- Connection flow with pseudocode examples
- Methodology section explaining APK decompilation process
This commit is contained in:
Jacquin Antoine
2026-06-13 00:21:19 +02:00
parent fe534ce77b
commit be87e8a4ca
14 changed files with 2373 additions and 0 deletions

145
02_ble_protocol.md Normal file
View File

@ -0,0 +1,145 @@
# BLE Protocol
## GATT Architecture
The device exposes a single BLE service with multiple characteristics:
| UUID | Type | Role |
|------|------|------|
| `0000180A-0000-1000-8000-00805F9B34FB` | Service | Device Information (standard) |
| `0000DAF2-0000-1000-8000-00805f9b34fb` | Service | **DWARF Primary Service** |
| `0000DAF3-0000-1000-8000-00805f9b34fb` | Characteristic | **Write** — Send protobuf requests |
| `0000DAF4-0000-1000-8000-00805F9B34FB` | Characteristic | **Notify** — Receive protobuf responses |
| `0000DAF5-0000-1000-8000-00805F9B34FB` | Characteristic | **Write** — STA mode configuration |
| `0000DAF6-0000-1000-8000-00805F9B34FB` | Characteristic | **Notify** — STA mode responses |
| `0000DAF7-0000-1000-8000-00805F9B34FB` | Characteristic | **Write** — AP mode configuration |
| `00009999-0000-1000-8000-00805F9B34FB` | Characteristic | **Notify** — AP mode responses |
> **Note**: UUIDs DAF2/DAF3 use lowercase `00805f9b34fb` while DAF4-DAF7/9999 use uppercase `00805F9B34FB`. This is as-is in the source code (`cg1.smali`).
## BLE Packet Format (BluetoothPacket)
All BLE data is framed in a custom packet format before being sent over GATT characteristics.
### Binary Layout
```
Offset Size Field Description
------ ---- ----------------- -------------------------------------------
0 1 magic 0xAA (constant)
1 1 protocolVersion Protocol version (typically 1)
2 1 cmdInstruction Command type (0-7, see below)
3 1 packageSequence Current packet sequence number (0-based)
4 1 totalPackages Total number of packets for this message
5 2 extendedProtocol Extended protocol field (big-endian, usually 0)
7 2 validDataLength Length of protobuf payload (big-endian)
9 N dataPayload Protobuf-encoded BleProto message
9+N 2 crc CRC-16/MODBUS (poly=0x8005, init=0xFFFF, reflected, XOR=0x0000)
11+N 1 endMarker 0x0D (constant)
Total packet size = validDataLength + 12
```
### Pseudocode: Building a BLE Packet
```python
import struct
def build_ble_packet(cmd: int, protobuf_data: bytes, seq: int = 0, total: int = 1) -> bytes:
"""Build a BLE packet from protobuf data."""
header = struct.pack('>BBBH', # big-endian: B=cmd, B=seq, B=total, H=extended
0xAA, # magic byte
1, # protocolVersion
cmd, # cmdInstruction
seq, # packageSequence
total, # totalPackages
0 # extendedProtocol (reserved)
)
# validDataLength
length_bytes = struct.pack('>H', len(protobuf_data))
# CRC over header + length + data
crc_input = header + length_bytes + protobuf_data
crc = crc16_modbus(crc_input)
crc_bytes = struct.pack('>H', crc)
# Assemble: header(7B) + length(2B) + data(NB) + crc(2B) + end(1B)
return header + length_bytes + protobuf_data + crc_bytes + b'\x0D'
```
### Pseudocode: CRC-16/MODBUS
```python
def crc16_modbus(data: bytes) -> int:
"""CRC-16/MODBUS: poly=0x8005, init=0xFFFF, reflected=True, XOR_out=0x0000"""
crc = 0xFFFF
for byte in data:
crc ^= byte
for _ in range(8):
if crc & 0x0001:
crc = (crc >> 1) ^ 0xA001 # reflected poly
else:
crc >>= 1
return crc & 0xFFFF
```
### Fragmentation
When a protobuf message exceeds the BLE MTU, it is split across multiple packets:
- `packageSequence` starts at 0, increments per packet
- `totalPackages` indicates total number of packets for the message
- Each packet contains a fragment of the protobuf payload
- `isLastPacket` = (`packageSequence` == `totalPackages` - 1)
## BLE Commands
| cmdInstruction | Name | Description |
|----------------|------|-------------|
| 0 | Unknown | Reserved |
| 1 | GetWiFiConfig | Authenticate and get device config |
| 2 | SetApMode | Configure device as WiFi hotspot (AP) |
| 3 | SetSTAMode | Configure device to connect to WiFi (STA) |
| 4 | SetNamePwd | Set BLE/WiFi name and password |
| 5 | Reset | Factory reset |
| 6 | GetWiFiList | Scan available WiFi networks |
| 7 | GetDeviceInfo | Get system info (protocol version, MAC, firmware) |
## Authentication Flow
```
App Device
│ │
│ BLE SCAN: discover "DWARF*" │
│ GATT CONNECT to service DAF2 │
│ │
│ ReqGetconfig {blePsd, clientId} │
│ ──── DAF3 (write) ────────────────► │
│ │
│ ResGetconfig {code, ip, ssid, ...} │
│ ◄──── DAF4 (notify) ────────────── │
│ │
│ [Optional] ReqSta/ReqAp │
│ ──── DAF5/DAF7 ───────────────────► │
│ │
│ Connect to ws://<ip>:9900 │
│ │
```
## Connection States
| State | Description |
|-------|-------------|
| Loading | Connecting |
| Success | Connected |
| PwdError | Authentication failed |
| DeviceError | Device error |
| Disconnecting | Disconnecting |
| Disconnected | Disconnected |
## BLE Error Types
| Error | Description |
|-------|-------------|
| BluetoothConnection | BLE connection failure |
| MTU | MTU negotiation failure |
| Communication | Communication error |
| ConfigFailed | Configuration failed |