HID state module

The HID state module is the center of an application acting as a HID peripheral. It is responsible for the following operations:

  • Tracking the state of HID subscribers and HID input report subscriptions. The module can simultaneously handle HID input report subscriptions of multiple HID subscribers. The module provides HID input reports only to subscribers with the highest priority (active subscribers).

  • Providing HID input reports to the active HID subscribers. The module relies on HID report providers to aggregate the user input, form HID input reports, and submit a hid_report_event. The HID input reports can be formatted according to either HID report protocol or HID boot protocol.

  • Handling HID output reports. The module handles only the HID keyboard LED output report. The module sends a led_event to update state of the keyboard LEDs.

Module events

Source Module

Input Event

This Module

Output Event

Sink Module

HID provider consumer control module

hid_report_provider_event

hid_state

HID provider keyboard module

HID provider mouse module

HID provider system control module

Source modules for hid_report_event

hid_report_event

HID Service module

hid_report_sent_event

USB state module

HID Service module

hid_report_subscriber_event

USB state module

HID Service module

hid_report_subscription_event

USB state module

Source modules for module_state_event

module_state_event

led_event

LED stream module

LEDs module

Note

See the Application overview for more information about the event-based communication in the nRF Desktop application and about how to read this table.

Configuration

To enable the HID state module, use the CONFIG_DESKTOP_HID_STATE_ENABLE Kconfig option that is implied by the CONFIG_DESKTOP_ROLE_HID_PERIPHERAL option. Make sure to configure the peripheral type and the set of supported HID input reports and HID boot interface. For details related to HID configuration in the nRF Desktop, see the HID configuration documentation.

Number of supported HID subscribers

A HID transport (for example, HID Service module or USB state module) is a module that forwards HID reports to a HID host and forwards HID input report subscriptions of the HID host. In most cases, a HID transport registers a single HID subscriber that handles all HID input reports. If your application configuration supports more than one HID subscriber, you must align the maximum number of HID subscribers that can be handled simultaneously (CONFIG_DESKTOP_HID_STATE_SUBSCRIBER_COUNT). For example, to use a configuration that allows to simultaneously subscribe to HID input reports from HID over GATT (Bluetooth LE) and a single USB HID instance, set the value of this Kconfig option to 2.

Selective HID input report subscription

In some cases, a single HID transport can register multiple HID subscribers. Every HID subscriber handles a subset of HID input reports.

For example, an nRF Desktop peripheral might use the USB selective HID report subscription feature to split HID input reports among multiple HID-class USB instances (every HID-class USB instance handles a predefined subset of HID input report IDs). For more details regarding the feature, see the USB HID class instance configuration documentation section of the USB state module.

Using selective HID input report subscription requires increasing the value of the CONFIG_DESKTOP_HID_STATE_SUBSCRIBER_COUNT Kconfig option. For example, if a configuration allows simultaneously subscribing to HID input reports from HID over GATT (Bluetooth LE) and two USB HID instances, increase the value of the Kconfig option to 3.

HID subscriber priority

If multiple HID subscribers are simultaneously connected, the HID state module selects the ones with the highest priority as the active subscribers. The HID state module provides HID input reports only to the active subscribers. The HID state module displays the HID keyboard LED state associated with the active subscriber of the HID keyboard input report. HID subscribers with the same priority cannot simultaneously subscribe to the same HID input report.

If a HID transport uses a selective HID input report subscription, all subscribers registered by the transport must share the same priority. Otherwise, subscribers with lower priority would not receive HID input reports from the HID state.

Note

By default, a subscriber that is associated with USB has priority over a subscriber associated with Bluetooth LE. If a HID host connects through the USB while another HID host is connected over the Bluetooth LE, the HID reports will be routed to the USB.

HID keyboard LEDs

You must define which hardware LEDs are used to display state of the HID keyboard LEDs report and LED effects that should be used to display the state. See documentation of CAF: LEDs module for details about LED effects.

You must create a configuration file with the following data:

  • keyboard_led_on - LED effect defined to represent LED turned on by the host.

  • keyboard_led_off - LED effect defined to represent LED turned off by the host.

  • keyboard_led_map - IDs of the hardware LEDs used to represent state of the HID keyboard LED.

For example, the file contents should look like follows:

#include "hid_keyboard_leds.h"

static const struct led_effect keyboard_led_on = LED_EFFECT_LED_ON(LED_COLOR(255, 255, 255));
static const struct led_effect keyboard_led_off = LED_EFFECT_LED_OFF();

static const uint8_t keyboard_led_map[] = {
        [HID_KEYBOARD_LEDS_NUM_LOCK] = 2,
        [HID_KEYBOARD_LEDS_CAPS_LOCK] = 3,
        [HID_KEYBOARD_LEDS_SCROLL_LOCK] = LED_UNAVAILABLE,
        [HID_KEYBOARD_LEDS_COMPOSE] = LED_UNAVAILABLE,
        [HID_KEYBOARD_LEDS_KANA] = LED_UNAVAILABLE,
};

You must define all of the mentioned data in this configuration file, and specify its location with the CONFIG_DESKTOP_HID_STATE_HID_KEYBOARD_LEDS_DEF_PATH Kconfig option.

Note

The configuration file should be included only by the configured module. Do not include the configuration file in other source files.

HID report providers

The HID state module relies on the HID report providers to collect user input, form HID input reports, and submit a hid_report_event. The module selects the CONFIG_DESKTOP_HID_REPORT_PROVIDER_EVENT Kconfig option to enable the HID report provider event and default HID report providers for all HID input reports enabled in the configuration. The HID providers for mouse and keyboard input reports also handle the respective HID boot input reports if the boot report support is enabled in the configuration.

Note

You can provide an alternative implementation of a HID report provider to generate a HID report in a custom way. You can also add a new HID report provider to introduce support for another HID input report. See the Providing HID input reports section for implementation details related to HID report providers integration.

Implementation details

This section describes implementation details related to responsibilities of the HID state module.

Tracking state of HID subscribers

A HID transport reports the state of a HID subscriber using the hid_report_subscriber_event. When the connection to the HID host is indicated by this event, the HID state module will create an associated subscriber. The HID state module tracks the state of the HID subscribers.

As part of the hid_report_subscriber_event, the subscriber provides the following parameters:

  • Subscriber priority - The HID state module provides HID input reports only to subscribers with the highest priority (active subscribers).

  • Pipeline size - The HID state module forwards this information to the HID report providers. The information can be used, for example, to synchronize sensor sampling with sending the HID input reports to the HID host. See the HID mouse report handling section for information how the pipeline size is used for HID mouse reports.

  • Maximum number of processed HID input reports - The HID state module limits the number of HID input reports processed by a HID subscriber at a time by delaying providing the subsequent HID input report until the previous report is sent to a HID host.

Tracking state of HID report subscriptions

For each subscriber, the HID state module tracks the state of HID input report subscriptions. The HID input reports are only provided after one of the active subscribers enables the subscription. The subscriber updates its HID report subscriptions using a hid_report_subscription_event.

The HID report subscriptions are tracked in the subscriber’s structure subscriber. This structure’s member state is an array of report_state structures. Each element corresponds to one HID input report.

The report_state structure serves the following purposes:

  • Tracks the state of the report subscription.

  • Contains the link connecting the object to the right provider structure which contains the HID report provider info such as report ID and API (hid_report_provider_api).

  • Tracks the number of reports with a given ID in flight.

Providing HID input reports

The HID state module relies on the HID providers to collect user input, form HID input reports, and submit a hid_report_event. Every HID input report ID is handled by a dedicated HID report provider API (hid_report_provider_api).

HID report provider event

The hid_report_provider_event is used to establish two-way callbacks between the HID state module and the HID report providers. The event allows to exchange the API structures between the HID state module and HID report providers (hid_report_provider_api and hid_state_api). The API structures allow for direct function calls between the modules.

The HID state module requests the HID report providers to generate HID reports and notifies the providers about the connection state changes and report sent occurrences. The HID report providers can notify the HID state module when new data is available (on user input) to trigger generating a HID input report.

On a HID state module’s request, a HID report provider submits a hid_report_event to provide a HID input report to the active HID subscriber. The hid_report_sent_event is submitted by the HID transport related to the subscriber to confirm that the HID report was sent to the HID host. The HID state module relies on this event to track the number of HID reports in flight and notify the providers.

See the hid_report_provider_event event documentation page for detailed information regarding the communication between the HID state module and HID report providers.

Default HID providers

The following application modules are used as default implementations of HID report providers:

The respective HID report provider is automatically enabled if support for a given HID input report is enabled in the HID configuration. See the documentation page of a HID report provider for detailed information about the provider.

Custom HID providers

You can implement your own HID report provider as part of the application. The HID report provider can perform one of the following two actions:

  • Handle a HID input report that is already supported by the application instead of a default HID report provider (substitute the default HID report provider). Make sure to disable the default HID report provider while implementing the custom provider.

  • Support a new HID input report.

HID report map update

If your HID report provider implementation uses a different HID input report format or you add a new HID input report, you need to align the HID report configuration (including the HID report map). If the default HID report descriptor is used (CONFIG_DESKTOP_USE_DEFAULT_REPORT_DESCR), the configuration is defined by the following files:

  • configuration/common/hid_report_desc.h

  • configuration/common/hid_report_desc.c

Note

nRF Desktop dongles share a common HID report format with the nRF Desktop peripherals. The aligned HID report configuration is required for the dongle to forward HID input reports from the peripherals.

HID transport update

If you add a new HID input report, you might also need to update the modules that act as HID transports (for example HID Service module or USB state module). This is needed to fulfill the following requirements:

  • Proper configuration of the module and libraries used by the module.

  • Support for the newly added HID input report.

HID output reports

When the HID state module receives a hid_report_event that contains a HID output report, it updates the stored information about the state of the HID output report of the appropriate subscriber.

By default, nRF Desktop supports only HID keyboard LED output report. The nRF Desktop peripheral displays the state of the keyboard LEDs that was specified by the active HID subscriber of a HID keyboard input report. When the subscriber changes or updates the state of the keyboard LEDs, the HID state module sends a leds_event to update the state of the hardware LEDs.