<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>BLE composite HID device</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/80222/ble-composite-hid-device</link><description>I am trying to develop a peripheral targeted for mobile devices that can either behave as a touchscreen (several simultaneous contact points, useful for performing gestures, and no visible pointer) or a regular mouse (pointer showing) depending on certain</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 05 Oct 2021 15:08:20 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/80222/ble-composite-hid-device" /><item><title>RE: BLE composite HID device</title><link>https://devzone.nordicsemi.com/thread/332683?ContentTypeID=1</link><pubDate>Tue, 05 Oct 2021 15:08:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3af3d7dd-89ef-4d77-ac6a-fb7a2a07af70</guid><dc:creator>Sigurd</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
[quote user=""]I tried creating a composite device by using independent BLE_HID instances for the mouse and touchscreen but only the first created instance works[/quote]
&lt;p&gt;We don&amp;#39;t have any BLE HID composite examples in the nRF5 SDK, but the&amp;nbsp;&lt;a href="https://www.nordicsemi.com/Products/Reference-designs/nRFready-Smart-Remote-3-for-nRF52-Series/Download?lang=en#infotabs"&gt;Smart Remote 3 reference design&lt;/a&gt; &lt;span&gt;has one HoG(HID over GATT) Service used for audio, touchpad, keyboard, and gyro operations. It might be useful to take a look at that. The HID descriptor, also referred to as Report Map, that it uses is detailed below:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="text"&gt;#if CONFIG_AUDIO_ENABLED &amp;amp;&amp;amp; CONFIG_AUDIO_HID_ENABLED
    /*
       Audio
     */
    0x06, 0x00, 0xFF,               // Usage Page (Vendor Defined Page 1)
    0x09, AUDIO_CONFIG_ID,          // Usage (Vendor Usage)
    0xA1, 0x01,                     // Collection (Application)
    0x85, AUDIO_IN_REP_ID,          //     Report ID (AUDIO_IN_REP_ID)
    0x15, 0x00,                     //     Logical Minimum (0)
    0x25, 0xFF,                     //     Logical Maximum (255)
    0x75, AUDIO_IN_REP_SIZE,        //     Report Size (AUDIO_IN_REP_SIZE)
    0x95, AUDIO_IN_REP_COUNT,       //     Report Count (AUDIO_IN_REP_COUNT)
    0x09, 0x00,                     //     Usage (Vendor Usage 1)
    0x81, 0x02,                     //     Input (Data, Var, Abs)
#if (AUDIO_IN_REP_ID != AUDIO_OUT_REP_ID)
    0x85, AUDIO_OUT_REP_ID,         //     Report ID (AUDIO_OUT_REP_ID)
#endif
    0x95, AUDIO_OUT_REP_COUNT,      //     Report Count (AUDIO_OUT_REP_COUNT)
    0x75, AUDIO_OUT_REP_SIZE,       //     Report Size (AUDIO_OUT_REP_SIZE)
    0x09, 0x00,                     //     Usage (Vendor Usage 1)
    0x91, 0x02,                     //     Output (Data, Var, Abs)
    0xC0,                           // End Collection
#endif /* CONFIG_AUDIO_ENABLED &amp;amp;&amp;amp; CONFIG_AUDIO_HID_ENABLED */
    /*
       Keyboard
     */
    0x05, 0x01,                     // Usage Page (Generic Desktop)
    0x09, 0x06,                     // Usage (Keyboard)
    0xA1, 0x01,                     // Collection (Application)
    0x85, KEYBOARD_IN_REP_ID,       //      Report ID (KEYBOARD_IN_REP_ID)
    0x75, KEYBOARD_IN_REP_SIZE,     //      Report Size (KEYBOARD_IN_REP_SIZE)
    0x95, KEYBOARD_IN_REP_COUNT,    //      Report Count (KEYBOARD_IN_REP_COUNT)
    0x15, 0x00,                     //      Logical Minimum (0)
    0x25, 0xFF,                     //      Logical Maximum (255)
    0x05, 0x07,                     //      Usage Page (Keyboard)
    0x19, 0x00,                     //      Usage Minimum (0)
    0x29, 0xFF,                     //      Usage Maximum (255)
    0x81, 0x00,                     //      Input (Data, Ary, Abs)
    0xC0,                           // End Collection
    /*
       Consumer Control
     */
    0x05, 0x0C,                     // Usage Page (Consumer Devices)
    0x09, 0x01,                     // Usage (Consumer Control)
    0xA1, 0x01,                     // Collection (Application)
    0x85, CONSUMER_CTRL_IN_REP_ID,  //      Report ID (CONSUMER_CTRL_IN_REP_ID)
    0x75, CONSUMER_CTRL_IN_REP_SIZE,//      Report Size (CONSUMER_CTRL_IN_REP_SIZE)
    0x95, CONSUMER_CTRL_IN_REP_COUNT,//     Report Count (CONSUMER_CTRL_IN_REP_COUNT)
    0x15, 0x00,                     //      Logical Minimum (0)
    0x26, 0xFF, 0x07,               //      Logical Maximum (2047)
    0x19, 0x00,                     //      Usage Minimum (0)
    0x2A, 0xFF, 0x07,               //      Usage Maximum (2047)
    0x81, 0x00,                     //      Input (Data, Ary, Abs)
    0xC0,                           // End Collection
    /*
       Mouse
     */
    0x05, 0x01,                     // Usage Page (Generic Desktop)
    0x09, 0x02,                     // Usage (Mouse)
    0xA1, 0x01,                     // Collection (Application)
    0x09, 0x01,                     //       Usage (Pointer)
    0xA1, 0x00,                     //       Collection (Physical)
    0x85, MOUSE_BTN_IN_REP_ID,      //          Report ID (MOUSE_BTN_IN_REP_ID)
    0x75, MOUSE_BTN_IN_REP_SIZE,    //          Report Size (MOUSE_BTN_IN_REP_SIZE)
    0x95, MOUSE_BTN_IN_REP_COUNT,   //          Report Count (MOUSE_BTN_IN_REP_COUNT)
    0x15, 0x00,                     //          Logical Minimum (0)
    0x25, 0x01,                     //          Logical Maximum (1)
    0x05, 0x09,                     //          Usage Page (Button)
    0x19, 0x01,                     //          Usage Minimum (Button 1)
    0x29, 0x08,                     //          Usage Maximum (Button 8)
    0x81, 0x02,                     //          Input (Data, Var, Abs)
    0xC0,                           //      End Collection
    0xA1, 0x00,                     //      Collection (Physical)
    0x85, MOUSE_XY_IN_REP_ID,       //          Report ID (MOUSE_XY_IN_REP_ID)
    0x75, MOUSE_XY_IN_REP_SIZE,     //          Report Size (MOUSE_XY_IN_REP_SIZE)
    0x95, MOUSE_XY_IN_REP_COUNT,    //          Report Count (MOUSE_XY_IN_REP_COUNT)
    0x16, 0x01, 0xF8,               //          Logical Minimum (-2047)
    0x26, 0xFF, 0x07,               //          Logical Maximum (2047)
    0x05, 0x01,                     //          Usage Page (Generic Desktop)
    0x09, 0x30,                     //          Usage (X)
    0x09, 0x31,                     //          Usage (Y)
    0x81, 0x06,                     //          Input (Data, Var, Rel)
    0xC0,                           //      End Collection
    0xA1, 0x00,                     //      Collection (Physical)
    0x85, MOUSE_WP_IN_REP_ID,       //          Report ID (MOUSE_WP_IN_REP_ID)
    0x75, MOUSE_WP_IN_REP_SIZE,     //          Report Size (MOUSE_WP_IN_REP_SIZE)
    0x95, 0x01,                     //          Report Count (1)
    0x15, 0x81,                     //          Logical Minimum (-127)
    0x25, 0x7F,                     //          Logical Maximum (127)
    0x05, 0x01,                     //          Usage Page (Generic Desktop)
    0x09, 0x38,                     //          Usage (Wheel)
    0x81, 0x06,                     //          Input (Data, Var, Rel)
    0x75, MOUSE_WP_IN_REP_SIZE,     //          Report Size (MOUSE_WP_IN_REP_SIZE)
    0x95, 0x01,                     //          Report Count (1)
    0x15, 0x81,                     //          Logical Minimum (-127)
    0x25, 0x7F,                     //          Logical Maximum (127)
    0x05, 0x0C,                     //          Usage Page (Consumer Devices)
    0x0A, 0x38, 0x02,               //          Usage (AC Pan)
    0x81, 0x06,                     //          Input (Data, Var, Rel)
    0xC0,                           //      End Collection
    0xC0,                           // End Collection
&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
[quote user=""]When bonding with the host, I get a BLE_ERROR_GATTS_SYS_ATTR_MISSING[/quote]
&lt;p&gt;Normally the Peer Manager should handle this for you. Maybe delay sending data until you get e.g. the first&amp;nbsp;PM_EVT_LOCAL_DB_CACHE_APPLIED event, see this post:&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/61014/getting-a-0x3401-ble_error_gatts_sys_attr_missing-from-sd_ble_gatts_hvx"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/61014/getting-a-0x3401-ble_error_gatts_sys_attr_missing-from-sd_ble_gatts_hvx&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>