# 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://: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 |