BLE HID can first identify whether IOS or Android sends different report descriptors

最近,我做了一个HID项目,发现其他蓝牙设备可以根据连接的主机是IOS还是Android发送不同的报告描述符。

Parents
  • 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

Reply
  • 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

Children
  • BLEHID.rar

    Hi

    This is the packet capture data of two products

    Thank you

  • 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

Related