I have a hid_discriptor which looks like this:
// 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
};
Which works for keyboard codes;
However, i also would like to add consumer control to my sample, so i can also send volume up/down etc.
/*
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,
The question is, that in the provided demo code; the code to send a report is this:
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));
}
This works in terms of sending keystrokes; when i trace that call in the source code, it goes to this function;
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->hid_report_input_value_handle, report, report_len);
}
Which actually uses the instance->hid_report_input_value_handle
instead of the hid_descriptor_keyboard_boot_mode; i also know why (in case people are wondering); The spec mentions;
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.
...snip...
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.
So after the change protocol is called; the report is loaded into the hid_report_input_value_handle
. So until now, everything is clear.
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.
For keyboard keys as keydown event:
uint8_t report[] = { 0x01, modifier, 0, 0, keycode, 0, 0, 0, 0, 0};
hids_device_send_input_report(con_handle, report, sizeof(report));
And for consumer control (play/pause) as keydown event:
uint8_t report[] = { 0x02, 0xCD, 0x00};
hids_device_send_input_report(con_handle, report, sizeof(report));
Is that about correct? Any guidance would be welcome, BLE is new to me hence the question.