title: Combine keyboard & consumer control in descriptor
body: <p>I have a hid_discriptor which looks like this:</p>
  
  <pre><code>// from USB HID Specification 1.1, Appendix B.1
  const uint8_t hid_descriptor_keyboard_boot_mode[] = {
      /*
         Keyboard
       */
      0x05, 0x01,                    // Usage Page (Generic Desktop)
      0x09, 0x06,                    // Usage (Keyboard)
      0xa1, 0x01,                    // Collection (Application)
  
      0x85,  0x01,                   // Report ID 1
  
      // Modifier byte
  
      0x75, 0x01,                    //   Report Size (1)
      0x95, 0x08,                    //   Report Count (8)
      0x05, 0x07,                    //   Usage Page (Key codes)
      0x19, 0xe0,                    //   Usage Minimum (Keyboard LeftControl)
      0x29, 0xe7,                    //   Usage Maxium (Keyboard Right GUI)
      0x15, 0x00,                    //   Logical Minimum (0)
      0x25, 0x01,                    //   Logical Maximum (1)
      0x81, 0x02,                    //   Input (Data, Variable, Absolute)
  
      // Reserved byte
  
      0x75, 0x01,                    //   Report Size (1)
      0x95, 0x08,                    //   Report Count (8)
      0x81, 0x03,                    //   Input (Constant, Variable, Absolute)
  
      // LED report + padding
  
      0x95, 0x05,                    //   Report Count (5)
      0x75, 0x01,                    //   Report Size (1)
      0x05, 0x08,                    //   Usage Page (LEDs)
      0x19, 0x01,                    //   Usage Minimum (Num Lock)
      0x29, 0x05,                    //   Usage Maxium (Kana)
      0x91, 0x02,                    //   Output (Data, Variable, Absolute)
  
      0x95, 0x01,                    //   Report Count (1)
      0x75, 0x03,                    //   Report Size (3)
      0x91, 0x03,                    //   Output (Constant, Variable, Absolute)
  
      // Keycodes
  
      0x95, 0x06,                    //   Report Count (6)
      0x75, 0x08,                    //   Report Size (8)
      0x15, 0x00,                    //   Logical Minimum (0)
      0x25, 0xff,                    //   Logical Maximum (1)
      0x05, 0x07,                    //   Usage Page (Key codes)
      0x19, 0x00,                    //   Usage Minimum (Reserved (no event indicated))
      0x29, 0xff,                    //   Usage Maxium (Reserved)
      0x81, 0x00,                    //   Input (Data, Array)
      0xc0,                          // End collection
  };
  </code></pre>
  
  <p>Which works for keyboard codes;</p>
  
  <p>However, i also would like to add consumer control to my sample, so i can also send volume up/down etc.</p>
  
  <pre><code>    /*
         Consumer Control
       */
      0x05, 0x0C,                     // Usage Page (Consumer Devices)
      0x09, 0x01,                     // Usage (Consumer Control)
      0xA1, 0x01,                     // Collection (Application)
      0x85, 0x02,                     //      Report ID
      0x75, 0x09, 0x01,               //      Report Size
      0x95, 0x09, 0x01,               //     Report 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,
  </code></pre>
  
  <p>The question is, that <a href="https://github.com/bluekitchen/btstack/blob/master/example/hog_keyboard_demo.c" rel="nofollow noreferrer">in the provided demo code</a>; the code to send a report is this:</p>
  
  <pre><code>static void send_report(int modifier, int keycode){
      uint8_t report[] = { /* 0xa1, */ modifier, 0, 0, keycode, 0, 0, 0, 0, 0};
      hids_device_send_input_report(con_handle, report, sizeof(report));
  }
  </code></pre>
  
  <p>This works in terms of sending keystrokes; when i trace that call in the source code, it goes <a href="https://github.com/bluekitchen/btstack/blob/master/src/ble/gatt-service/hids_device.c#L367" rel="nofollow noreferrer">to this function</a>;</p>
  
  <pre><code>void hids_device_send_input_report(hci_con_handle_t con_handle, const uint8_t * report, uint16_t report_len){
      hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
      if (!instance){
          log_error("no instance for handle 0x%02x", con_handle);
          return;
      }
      att_server_notify(con_handle, instance-&gt;hid_report_input_value_handle, report, report_len);
  }
  </code></pre>
  
  <p>Which actually uses the <code>instance-&gt;hid_report_input_value_handle</code> instead of the hid_descriptor_keyboard_boot_mode; i also know why (in case people are wondering); <a href="https://www.usb.org/sites/default/files/documents/hid1_11.pdf" rel="nofollow noreferrer">The spec mentions</a>;</p>
  
  <blockquote>
    <p>The HID Subclass 1 defines two descriptors for Boot Devices. Devices may
    append additional data to these boot reports, but the first 8 bytes of keyboard reports and the first 3 bytes of mouse reports must conform to the format defined by the Boot Report descriptor in order for the data to be correctly interpreted by the BIOS.</p>
  </blockquote>
  
  <p>...snip...</p>
  
  <blockquote>
    <p>When the HID class driver is loaded, it will issue a Change Protocol,
    changing from the boot protocol to the report protocol after reading the boot interface’s Report descriptor. </p>
  </blockquote>
  
  <p>So after the change protocol is called; the report is loaded into the <code>hid_report_input_value_handle</code>. So until now, everything is clear.</p>
  
  <p>Then the main question comes; HOW do i send consumer control to my paired device? Is it just a matter of adding the reportId? e.g.</p>
  
  <p>For keyboard keys as keydown event:</p>
  
  <pre><code>uint8_t report[] = { 0x01, modifier, 0, 0, keycode, 0, 0, 0, 0, 0};
  hids_device_send_input_report(con_handle, report, sizeof(report));
  </code></pre>
  
  <p>And for consumer control (play/pause) as keydown event:</p>
  
  <pre><code>uint8_t report[] = { 0x02, 0xCD, 0x00};
  hids_device_send_input_report(con_handle, report, sizeof(report));
  </code></pre>
  
  <p>Is that about correct? Any guidance would be welcome, BLE is new to me hence the question.</p>