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:
145
02_ble_protocol.md
Normal file
145
02_ble_protocol.md
Normal 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 |
|
||||
Reference in New Issue
Block a user