最近,我做了一个HID项目,发现其他蓝牙设备可以根据连接的主机是IOS还是Android发送不同的报告描述符。
最近,我做了一个HID项目,发现其他蓝牙设备可以根据连接的主机是IOS还是Android发送不同的报告描述符。
Hi
If I understand you correctly you want a BLE HID device to know if it is connected to and Android or an iOS phone?
I don't think there is a good way to do this unfortunately, but I will do some investigating internally and get back to you.
Best regards
Torbjørn
Yes, I need to know the host's operating system before sending the report descriptor
Hi
If the peripheral device implements a GATT client and performs service discovery on the server in the phone (after connecting) it should find some Apple specific services when connecting to an iOS device, such as the Apple Notification Center service.
Many phones will also expose the Device Information Service, which allows you to read the manufacturer and name of the device.
The problem is that you won't be able to delay service discovery from the phone side, which might cause the phone to read the report descriptor before you are able to figure out if it is an Android or iOS device.
Are you planning to have a custom app that the user can use to connect to your device, or do you want to connect directly from the Bluetooth interface of the phone without a custom app?
Best regards
Torbjørn
Hi
I want to connect directly from the Bluetooth interface of the phone without a custom app!
At present, I don't know what principle other people's products use to identify operating systems. I found through packet capturing that the values they send to different operating systems are different,
Thank you
Hi
Would you be able to share those packet capture traces with me so I can try to understand what these devices are doing?
It might be possible to connect to the phone with a generic HID report, then perform service discovery of the server in the phone and use that to determine whether the phone is an Android or iOS device.
Then you have to change the HID report based on which platform you're on, and use the Service Changed characteristic to inform the phone that the services are changed and that service discovery needs to be repeated.
This has never been tested by us though, and I don't know if it would be a reliable method across different phones. This is why it would be interesting to take a look at the traces you captured.
Best regards
Torbjørn
Hi
Would you be able to share those packet capture traces with me so I can try to understand what these devices are doing?
It might be possible to connect to the phone with a generic HID report, then perform service discovery of the server in the phone and use that to determine whether the phone is an Android or iOS device.
Then you have to change the HID report based on which platform you're on, and use the Service Changed characteristic to inform the phone that the services are changed and that service discovery needs to be repeated.
This has never been tested by us though, and I don't know if it would be a reliable method across different phones. This is why it would be interesting to take a look at the traces you captured.
Best regards
Torbjørn
This product is designed to control the phone's self timer, Tiktok and sliding up and down. It can only run smoothly on a specific operating system version, because it needs to be compatible with two operating systems on one product
Android 报告描述符 0x05, 0x0D, // Usage Page (Digitizer) 0x09, 0x04, // Usage (Touch Screen) 0xA1, 0x01, // Collection (Application) 0x85, 0x01, // Report ID (1) 0x09, 0x22, // Usage (Finger) 0xA1, 0x02, // Collection (Logical) 0x09, 0x42, // Usage (Tip Switch) 0x09, 0x32, // Usage (In Range) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x02, // Report Count (2) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x75, 0x01, // Report Size (1) 0x95, 0x06, // Report Count (6) 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xE8, 0x03, // Logical Maximum (1000) 0x35, 0x00, // Physical Minimum (0) 0x45, 0x00, // Physical Maximum (0) 0x55, 0x00, // Unit Exponent (0) 0x65, 0x00, // Unit (None) 0x75, 0x10, // Report Size (16) 0x95, 0x02, // Report Count (2) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xC0, // End Collection 0x05, 0x0C, // Usage Page (Consumer) 0x09, 0x01, // Usage (Consumer Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x02, // Report ID (2) 0x75, 0x10, // Report Size (16) 0x95, 0x01, // Report Count (1) 0x15, 0x01, // Logical Minimum (1) 0x26, 0x8C, 0x02, // Logical Maximum (652) 0x19, 0x01, // Usage Minimum (Consumer Control) 0x2A, 0x8C, 0x02, // Usage Maximum (AC Send) 0x81, 0x60, // Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State) 0xC0, // End Collection 0x05, 0x0C, // Usage Page (Consumer) 0x09, 0x01, // Usage (Consumer Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x03, // Report ID (3) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x18, // Report Count (24) 0x0A, 0x40, 0x00, // Usage (Menu) 0x0A, 0x92, 0x01, // Usage (AL Calculator) 0x0A, 0x83, 0x01, // Usage (AL Consumer Control Configuration) 0x0A, 0x23, 0x02, // Usage (AC Home) 0x0A, 0x8A, 0x01, // Usage (AL Email Reader) 0x0A, 0x82, 0x01, // Usage (AL Programmable Button Configuration) 0x0A, 0x21, 0x02, // Usage (AC Search) 0x0A, 0x24, 0x02, // Usage (AC Back) 0x0A, 0x25, 0x02, // Usage (AC Forward) 0x0A, 0x26, 0x02, // Usage (AC Stop) 0x0A, 0x27, 0x02, // Usage (AC Refresh) 0x09, 0xB6, // Usage (Scan Previous Track) 0x09, 0xB5, // Usage (Scan Next Track) 0x09, 0xB7, // Usage (Stop) 0x09, 0xCD, // Usage (Play/Pause) 0x09, 0xE9, // Usage (Volume Increment) 0x09, 0xEA, // Usage (Volume Decrement) 0x09, 0xE2, // Usage (Mute) 0x09, 0xB8, // Usage (Eject) 0x09, 0x30, // Usage (Power) 0x09, 0xCF, // Usage (0xCF) 0x09, 0xB9, // Usage (Random Play) 0x0A, 0xB1, 0x01, // Usage (AL Screen Saver) 0x0A, 0x04, 0x02, // Usage (AC Exit) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x06, // Usage (Keyboard) 0xA1, 0x01, // Collection (Application) 0x85, 0x04, // Report ID (4) 0x05, 0x07, // Usage Page (Kbrd/Keypad) 0x19, 0xE0, // Usage Minimum (0xE0) 0x29, 0xE7, // Usage Maximum (0xE7) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x08, // Report Count (8) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x01, // Report Count (1) 0x75, 0x08, // Report Size (8) 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x05, // Report Count (5) 0x75, 0x01, // Report Size (1) 0x05, 0x08, // Usage Page (LEDs) 0x19, 0x01, // Usage Minimum (Num Lock) 0x29, 0x05, // Usage Maximum (Kana) 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0x95, 0x01, // Report Count (1) 0x75, 0x03, // Report Size (3) 0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0x95, 0x06, // Report Count (6) 0x75, 0x08, // Report Size (8) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x65, // Logical Maximum (101) 0x05, 0x07, // Usage Page (Kbrd/Keypad) 0x19, 0x00, // Usage Minimum (0x00) 0x29, 0x65, // Usage Maximum (0x65) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0x05, 0x0C, // Usage Page (Consumer) 0x09, 0x01, // Usage (Consumer Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x05, // Report ID (5) 0x75, 0x10, // Report Size (16) 0x95, 0x01, // Report Count (1) 0x15, 0x01, // Logical Minimum (1) 0x26, 0x8C, 0x02, // Logical Maximum (652) 0x19, 0x01, // Usage Minimum (Consumer Control) 0x2A, 0x8C, 0x02, // Usage Maximum (AC Send) 0x81, 0x60, // Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State) 0xC0, // End Collection IOS 报告描述符 05 01 09 06 a1 01 85 04 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 81 02 95 01 75 08 81 01 95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 01 95 06 75 08 15 00 25 65 05 07 19 00 29 65 81 00 c0 05 0c 09 01 a1 01 85 05 75 10 95 01 15 01 26 8c 02 19 01 2a 8c 02 81 60 c0 05 01 09 02 a1 01 85 01 09 01 a1 00 75 08 95 01 05 01 09 38 15 81 25 7f 81 06 05 0c 0a 38 02 95 01 81 06 c0 85 02 09 01 a1 00 95 03 75 01 05 09 19 01 29 03 15 00 25 01 81 02 95 01 75 01 81 03 75 0e 95 02 05 01 09 30 09 31 16 01 e0 26 ff 1f 81 06 c0 c0 05 0c 09 01 a1 01 85 03 15 00 25 01 75 01 95 18 0a 40 00 0a 92 01 0a 83 01 0a 23 02 0a 8a 01 0a 82 01 0a 21 02 0a 24 02 0a 25 02 0a 26 02 0a 27 02 09 b6 09 b5 09 b7 09 cd 09 e9 09 ea 09 e2 09 b8 09 30 09 cf 09 b9 0a b1 01 0a 04 02 81 02 c0 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x06, // Usage (Keyboard) 0xA1, 0x01, // Collection (Application) 0x85, 0x04, // Report ID (4) 0x05, 0x07, // Usage Page (Kbrd/Keypad) 0x19, 0xE0, // Usage Minimum (0xE0) 0x29, 0xE7, // Usage Maximum (0xE7) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x08, // Report Count (8) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x01, // Report Count (1) 0x75, 0x08, // Report Size (8) 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x05, // Report Count (5) 0x75, 0x01, // Report Size (1) 0x05, 0x08, // Usage Page (LEDs) 0x19, 0x01, // Usage Minimum (Num Lock) 0x29, 0x05, // Usage Maximum (Kana) 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0x95, 0x01, // Report Count (1) 0x75, 0x03, // Report Size (3) 0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0x95, 0x06, // Report Count (6) 0x75, 0x08, // Report Size (8) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x65, // Logical Maximum (101) 0x05, 0x07, // Usage Page (Kbrd/Keypad) 0x19, 0x00, // Usage Minimum (0x00) 0x29, 0x65, // Usage Maximum (0x65) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0x05, 0x0C, // Usage Page (Consumer) 0x09, 0x01, // Usage (Consumer Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x05, // Report ID (5) 0x75, 0x10, // Report Size (16) 0x95, 0x01, // Report Count (1) 0x15, 0x01, // Logical Minimum (1) 0x26, 0x8C, 0x02, // Logical Maximum (652) 0x19, 0x01, // Usage Minimum (Consumer Control) 0x2A, 0x8C, 0x02, // Usage Maximum (AC Send) 0x81, 0x60, // Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State) 0xC0, // End Collection 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x02, // Usage (Mouse) 0xA1, 0x01, // Collection (Application) 0x85, 0x01, // Report ID (1) 0x09, 0x01, // Usage (Pointer) 0xA1, 0x00, // Collection (Physical) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x38, // Usage (Wheel) 0x15, 0x81, // Logical Minimum (-127) 0x25, 0x7F, // Logical Maximum (127) 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) 0x05, 0x0C, // Usage Page (Consumer) 0x0A, 0x38, 0x02, // Usage (AC Pan) 0x95, 0x01, // Report Count (1) 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0x85, 0x02, // Report ID (2) 0x09, 0x01, // Usage (Consumer Control) 0xA1, 0x00, // Collection (Physical) 0x95, 0x03, // Report Count (3) 0x75, 0x01, // Report Size (1) 0x05, 0x09, // Usage Page (Button) 0x19, 0x01, // Usage Minimum (0x01) 0x29, 0x03, // Usage Maximum (0x03) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x01, // Report Count (1) 0x75, 0x01, // Report Size (1) 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x75, 0x0E, // Report Size (14) 0x95, 0x02, // Report Count (2) 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) 0x16, 0x01, 0xE0, // Logical Minimum (-8191) 0x26, 0xFF, 0x1F, // Logical Maximum (8191) 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0xC0, // End Collection 0x05, 0x0C, // Usage Page (Consumer) 0x09, 0x01, // Usage (Consumer Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x03, // Report ID (3) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x18, // Report Count (24) 0x0A, 0x40, 0x00, // Usage (Menu) 0x0A, 0x92, 0x01, // Usage (AL Calculator) 0x0A, 0x83, 0x01, // Usage (AL Consumer Control Configuration) 0x0A, 0x23, 0x02, // Usage (AC Home) 0x0A, 0x8A, 0x01, // Usage (AL Email Reader) 0x0A, 0x82, 0x01, // Usage (AL Programmable Button Configuration) 0x0A, 0x21, 0x02, // Usage (AC Search) 0x0A, 0x24, 0x02, // Usage (AC Back) 0x0A, 0x25, 0x02, // Usage (AC Forward) 0x0A, 0x26, 0x02, // Usage (AC Stop) 0x0A, 0x27, 0x02, // Usage (AC Refresh) 0x09, 0xB6, // Usage (Scan Previous Track) 0x09, 0xB5, // Usage (Scan Next Track) 0x09, 0xB7, // Usage (Stop) 0x09, 0xCD, // Usage (Play/Pause) 0x09, 0xE9, // Usage (Volume Increment) 0x09, 0xEA, // Usage (Volume Decrement) 0x09, 0xE2, // Usage (Mute) 0x09, 0xB8, // Usage (Eject) 0x09, 0x30, // Usage (Power) 0x09, 0xCF, // Usage (0xCF) 0x09, 0xB9, // Usage (Random Play) 0x0A, 0xB1, 0x01, // Usage (AL Screen Saver) 0x0A, 0x04, 0x02, // Usage (AC Exit) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 10 00 fe 7f 01 00 c8 00 01 00 c8 00 00 00 00 00 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f 20 03 70 fe 20 03 70 fe 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f e0 01 70 fe e0 01 70 fe 01 00 c8 00 01 00 c8 00 01 00 c8 00 00 00 00 00 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f e0 01 70 fe e0 01 70 fe 01 00 c8 00 01 00 c8 00 01 00 c8 00 00 00 00 00 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f e0 01 70 fe e0 01 70 fe 01 00 c8 00 01 00 c8 00 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f e0 01 70 fe e0 01 70 fe 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f e0 01 70 fe e0 01 70 fe 01 00 c8 00 01 00 c8 00 01 00 c8 00 00 00 00 00 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f e0 01 c0 fe 01 00 38 ff 01 00 38 ff 01 00 38 ff 00 00 00 00 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f e0 01 c0 fe e0 01 c0 fe 01 00 38 ff 00 00 00 00 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f 10 00 fe 7f e0 01 c0 fe e0 01 c0 fe 01 00 38 ff 01 00 38 ff 01 00 38 ff 00 00 00 00 10 00 fe 7f
At present, I just don't know how it distinguishes between IOS and Android. Maybe we can see his solution in the packet capture information, but I still can't know his method