- 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
5.6 KiB
5.6 KiB
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
00805f9b34fbwhile DAF4-DAF7/9999 use uppercase00805F9B34FB. 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
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
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:
packageSequencestarts at 0, increments per packettotalPackagesindicates 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 |