Recording Mobile HCI Logs

In the Developer Options of a VIVO smartphone, enable Bluetooth HCI snoop log.

After connecting the phone to a computer via USB, change the USB mode to File Transfer.

adb bugreport vivo_btsnoop

This will generate a log under /data/user_de/0/com.android.shell/files/ and automatically pull it to the computer.

Inside bugreport.zip, you can find the HCI log at \FS\data\misc\bluetooth\logs:


Knowledge Base

UUID

A UUID (Universally Unique Identifier) is a 128-bit (16-byte) unique identifier used in Bluetooth protocols to identify types and functions of various components such as Services, Characteristics, and Descriptors.


Service

A Service is a collection of functionalities provided by the Bluetooth device. Each Service contains one or more Characteristics.

Services are divided into Primary Services and Secondary Services.


Characteristic

A Characteristic is a specific data point inside a Service, used for read, write, and notify operations. Each Characteristic contains:


Packet Capturing

I already confirmed that this is a BLE (Bluetooth Low Energy) device, so we just need to look at Attribute Protocol communication:

On Android, I also found a pretty good domestic Bluetooth debugging tool called E Debug.

We communicate with Bluetooth in a browser environment using the Web Bluetooth API:

// Bluetooth functionality
if (!navigator.bluetooth) {
 console.error('Web Bluetooth API is not supported on this browser');
} else {
 async function connectAndWrite() {
  try {
   console.log("Requesting Bluetooth Device...");
   
   // Scan and select device
   const device = await navigator.bluetooth.requestDevice({
    // acceptAllDevices: true,
    filters: [{ name: 'JEU-Lush139-XT' }],
    optionalServices: ['generic_access', '53300001-0023-4bd4-bbd5-a6920e4c5653'] // Specify target services
   });

   console.log("Device:", device.name);
   
   // Connect to GATT server
   const server = await device.gatt.connect();
   console.log("Connected to GATT Server");

   // Get Service
   const service = await server.getPrimaryService("53300001-0023-4bd4-bbd5-a6920e4c5653");
   console.log("Service:", service.uuid);

   // Notify
   const characteristic = await service.getCharacteristic("53300002-0023-4bd4-bbd5-a6920e4c5653");
   await characteristic.startNotifications();
   characteristic.addEventListener('characteristicvaluechanged', (event) => {
    const value = event.target.value;
    console.log("Received value:", value);
   });
   const close_cmd = [0x85, 0x8b, 0x5b, 0x55, 0x67, 0x7a, 0x7b, 0x7c, 0x1a];
   const open_cmd = [0x85, 0x8b, 0x5b, 0x55, 0x66, 0x6a, 0x6b, 0x6c, 0x0b];
   const characteristic2 = await service.getCharacteristic("53300003-0023-4bd4-bbd5-a6920e4c5653");
   characteristic2.writeValue(new Uint8Array(open_cmd));
   console.log("Data written successfully!");

   // Disconnect
   device.gatt.disconnect();
   console.log("Disconnected");
  } catch (error) {
   console.error("Error:", error);
  }
 }
}