Skip to content

Commit b6d9238

Browse files
committed
bluetooth: hids: Add support for HID SCI
This commit adds support for HID Shorter Connection Intervals, both on the HID Device and HID Host sides. Signed-off-by: Artur Hadasz <artur.hadasz@nordicsemi.no>
1 parent e5631ca commit b6d9238

8 files changed

Lines changed: 1196 additions & 3 deletions

File tree

include/bluetooth/services/hids.h

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,26 @@ extern "C" {
4444
/** Length of encoded HID Information. */
4545
#define BT_HIDS_INFORMATION_LEN 4
4646

47+
#if defined(CONFIG_BT_HIDS_SCI) || defined(CONFIG_BT_HOGP_SCI)
48+
/** Maximum number of connection interval groups in HID SCI Information. */
49+
#if defined(CONFIG_BT_HIDS_SCI_INFORMATION_MAX_GROUPS_COUNT_CUSTOM)
50+
#define BT_HIDS_SCI_INFORMATION_MAX_GROUPS CONFIG_BT_HIDS_SCI_INFORMATION_MAX_GROUPS_COUNT
51+
#else
52+
#define BT_HIDS_SCI_INFORMATION_MAX_GROUPS BT_CONN_LE_MAX_CONN_INTERVAL_GROUPS
53+
#endif
54+
55+
/** Max length of encoded HID SCI Information based on the HIDS specification:
56+
* Minimum supported conn interval (1B) + Num groups (1B) +
57+
* Num groups * (Group Min (2B) + Group Max (2B) + Group Stride (2B)).
58+
*/
59+
#define BT_HIDS_SCI_INFORMATION_MAX_LEN (1 + 1 + BT_HIDS_SCI_INFORMATION_MAX_GROUPS * (2 + 2 + 2))
60+
#define BT_HIDS_SCI_INFORMATION_MIN_LEN 2
61+
62+
/** The transport interval which the device must support to be compliant
63+
* with the HID specification (chapter 7.4). */
64+
#define BT_HIDS_MAX_MINIMAL_TRANSPORT_INTERVAL_US 1250
65+
#endif
66+
4767
/**
4868
* @brief Declare a HIDS instance.
4969
*
@@ -116,6 +136,10 @@ enum bt_hids_flags {
116136
BT_HIDS_REMOTE_WAKE = BIT(0),
117137
/** Device advertises when bonded but not connected. */
118138
BT_HIDS_NORMALLY_CONNECTABLE = BIT(1),
139+
/** Device is capable of supporting the HID SCI feature */
140+
BT_HIDS_SCI_CAPABLE = BIT(2),
141+
/** Device is capable of supporting the HID SCI Low Power mode feature */
142+
BT_HIDS_SCI_LOW_POWER_MODE_CAPABLE = BIT(3),
119143
};
120144

121145
/** @brief HID Control Point settings. */
@@ -124,7 +148,32 @@ enum bt_hids_control_point {
124148
BT_HIDS_CONTROL_POINT_SUSPEND = 0x00,
125149

126150
/** Exit suspend value for Control Point.*/
127-
BT_HIDS_CONTROL_POINT_EXIT_SUSPEND = 0x01
151+
BT_HIDS_CONTROL_POINT_EXIT_SUSPEND = 0x01,
152+
/** Request SCI default mode value for Control Point. */
153+
BT_HIDS_CONTROL_POINT_SCI_DEFAULT_REQ = 0x02,
154+
155+
/** Request SCI fast mode value for Control Point. */
156+
BT_HIDS_CONTROL_POINT_SCI_FAST_REQ = 0x03,
157+
158+
/** Request SCI low power mode value for Control Point. */
159+
BT_HIDS_CONTROL_POINT_SCI_LOW_POWER_REQ = 0x04,
160+
161+
/** Request SCI Full Range mode value for Control Point. */
162+
BT_HIDS_CONTROL_POINT_SCI_FULL_RANGE_REQ = 0x05,
163+
};
164+
165+
/** @brief HID SCI Mode values */
166+
enum bt_hids_sci_mode_value {
167+
/** SCI None mode. */
168+
BT_HIDS_SCI_MODE_NONE = 0x00,
169+
/** SCI Default mode. */
170+
BT_HIDS_SCI_MODE_DEFAULT = 0x02,
171+
/** SCI Fast mode. */
172+
BT_HIDS_SCI_MODE_FAST = 0x03,
173+
/** SCI Low Power mode. */
174+
BT_HIDS_SCI_MODE_LOW_POWER = 0x04,
175+
/** SCI Full Range mode. */
176+
BT_HIDS_SCI_MODE_FULL_RANGE = 0x05,
128177
};
129178

130179
/** HID Service Protocol Mode events. */
@@ -141,6 +190,14 @@ enum bt_hids_cp_evt {
141190
BT_HIDS_CP_EVT_HOST_SUSP,
142191
/** Exit suspend command received. */
143192
BT_HIDS_CP_EVT_HOST_EXIT_SUSP,
193+
/** SCI Default mode request received. */
194+
BT_HIDS_CP_EVT_HOST_SCI_DEFAULT_REQ,
195+
/** SCI Fast mode request received. */
196+
BT_HIDS_CP_EVT_HOST_SCI_FAST_REQ,
197+
/** SCI Low Power mode request received. */
198+
BT_HIDS_CP_EVT_HOST_SCI_LOW_POWER_REQ,
199+
/** SCI Full Range mode request received. */
200+
BT_HIDS_CP_EVT_HOST_SCI_FULL_RANGE_REQ,
144201
};
145202

146203
/** HID notification events. */
@@ -393,6 +450,34 @@ struct bt_hids_cp {
393450
bt_hids_cp_evt_handler_t evt_handler;
394451
};
395452

453+
#if defined(CONFIG_BT_HIDS_SCI)
454+
/** @brief Function to be called when the SCI mode is updated. */
455+
typedef void (*bt_hids_sci_mode_update_handler_t) (struct bt_conn *conn,
456+
enum bt_hids_sci_mode_value mode);
457+
458+
/** @brief SCI mode.
459+
*/
460+
struct bt_hids_sci_mode_data {
461+
/** CCC descriptor. */
462+
struct bt_gatt_ccc_managed_user_data ccc;
463+
464+
/** Index in the service attribute array. */
465+
uint8_t att_ind;
466+
467+
/** Callback with new SCI mode. */
468+
bt_hids_sci_mode_update_handler_t update_handler;
469+
};
470+
471+
/** @brief SCI Information data. */
472+
struct bt_hids_sci_info_data {
473+
/** Pointer to the SCI information. */
474+
uint8_t sci_info[BT_HIDS_SCI_INFORMATION_MAX_LEN];
475+
476+
/** Size of the SCI information. */
477+
ssize_t sci_info_len;
478+
};
479+
#endif
480+
396481
/** @brief HID initialization.
397482
*/
398483
struct bt_hids_init_param {
@@ -414,7 +499,9 @@ struct bt_hids_init_param {
414499
/** Callback for Protocol Mode characteristic. */
415500
bt_hids_pm_evt_handler_t pm_evt_handler;
416501

417-
/** Callback for Control Point characteristic. */
502+
/** Callback for Control Point (suspend and exit-suspend only;
503+
* mode requests are handled internally).
504+
*/
418505
bt_hids_cp_evt_handler_t cp_evt_handler;
419506

420507
/** Callback for Boot Mouse Input Report. */
@@ -426,6 +513,11 @@ struct bt_hids_init_param {
426513
/** Callback for Boot Keyboard Output Report. */
427514
bt_hids_rep_handler_t boot_kb_outp_rep_handler;
428515

516+
#if defined(CONFIG_BT_HIDS_SCI)
517+
/** Callback for SCI mode update. */
518+
bt_hids_sci_mode_update_handler_t sci_mode_update_handler;
519+
#endif
520+
429521
/** Flag indicating that the device has mouse capabilities. */
430522
bool is_mouse;
431523

@@ -466,6 +558,13 @@ struct bt_hids {
466558
/** Control Point. */
467559
struct bt_hids_cp cp;
468560

561+
#if defined(CONFIG_BT_HIDS_SCI)
562+
/** SCI mode data. */
563+
struct bt_hids_sci_mode_data sci_mode_data;
564+
565+
/** HID SCI Information data. */
566+
struct bt_hids_sci_info_data sci_info_data;
567+
#endif
469568
/** Buffer with encoded HID Information. */
470569
uint8_t info[BT_HIDS_INFORMATION_LEN];
471570

@@ -502,6 +601,14 @@ struct bt_hids_conn_data {
502601

503602
/** Pointer to Feature Reports Context data. */
504603
uint8_t *feat_rep_ctx;
604+
605+
#if defined(CONFIG_BT_HIDS_SCI)
606+
/** Pending SCI mode value. */
607+
uint8_t pending_sci_mode;
608+
609+
/** SCI mode value. */
610+
uint8_t sci_mode;
611+
#endif
505612
};
506613

507614

include/bluetooth/services/hogp.h

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,57 @@ struct bt_hogp_init_params {
142142
*/
143143
struct bt_hogp_rep_info;
144144

145+
#if defined(CONFIG_BT_HOGP_SCI)
146+
/** @brief Callback function that is called when the HID SCI mode is changed.
147+
*
148+
* @param conn HOGP object.
149+
* @param mode New SCI mode value.
150+
*/
151+
typedef void (*bt_hogp_sci_mode_changed_cb)(struct bt_conn *conn, const uint8_t mode);
152+
153+
/**
154+
* @brief Callback function that is called when a HID SCI mode is read.
155+
*
156+
* @param hogp HOGP object.
157+
* @param err ATT error code.
158+
* @param mode SCI mode value.
159+
*/
160+
typedef void (*bt_hogp_sci_mode_read_cb)(struct bt_hogp *hogp, uint8_t err,
161+
enum bt_hids_sci_mode_value mode);
162+
163+
/** @brief SCI mode data.
164+
*
165+
* This structure is defined here as it is needed in the bt_hogp structure definition.
166+
* Do not use any of the fields here directly.
167+
*/
168+
struct bt_hogp_sci_mode_data {
169+
/** Function to call when the SCI mode is changed. */
170+
bt_hogp_sci_mode_changed_cb notify_cb;
171+
172+
/** Notify params. */
173+
struct bt_gatt_subscribe_params notify_params;
174+
175+
/** Function to call when the SCI mode is read. */
176+
bt_hogp_sci_mode_read_cb read_cb;
177+
178+
/** Read params. */
179+
struct bt_gatt_read_params read_params;
180+
};
181+
182+
/** @brief SCI Information.
183+
*/
184+
struct bt_hogp_sci_info {
185+
/** Minimum supported connection interval in units of 125us. */
186+
uint8_t min_supported_conn_interval_125us;
187+
188+
/** Number of connection interval groups. */
189+
uint8_t num_groups;
190+
191+
/** Connection interval groups. */
192+
struct bt_conn_le_min_conn_interval_group groups[BT_HIDS_SCI_INFORMATION_MAX_GROUPS];
193+
};
194+
#endif
195+
145196
/**
146197
* @brief HOGP object.
147198
*
@@ -156,6 +207,15 @@ struct bt_hogp {
156207
struct bt_conn *conn;
157208
/** HIDS client information. */
158209
struct bt_hids_info info_val;
210+
211+
#if defined(CONFIG_BT_HOGP_SCI)
212+
/** HID SCI Mode data. */
213+
struct bt_hogp_sci_mode_data sci_mode_data;
214+
215+
/** Cached HID SCI Information. */
216+
struct bt_hogp_sci_info sci_info;
217+
#endif
218+
159219
/** Handlers for descriptors */
160220
struct bt_hogp_handlers {
161221
/** Protocol Mode Characteristic value handle. */
@@ -166,6 +226,14 @@ struct bt_hogp {
166226
uint16_t info;
167227
/** HID Control Point Characteristic handle. */
168228
uint16_t cp;
229+
#if defined(CONFIG_BT_HOGP_SCI)
230+
/** HID SCI Information Characteristic handle. */
231+
uint16_t sci_info;
232+
/** HID SCI Mode Characteristic handle. */
233+
uint16_t sci_mode;
234+
/** HID SCI Mode CCC handle. */
235+
uint16_t sci_mode_ccc;
236+
#endif
169237
} handlers;
170238
/**
171239
* @brief Callback for HIDS client ready
@@ -192,6 +260,10 @@ struct bt_hogp {
192260
* @sa bt_hogp::read_params_sem
193261
*/
194262
struct bt_gatt_read_params read_params;
263+
264+
#if defined(CONFIG_BT_HOGP_SCI)
265+
struct bt_gatt_read_params sci_info_read_params;
266+
#endif
195267
/**
196268
* @brief The semaphore for common read parameters protection.
197269
*
@@ -524,6 +596,64 @@ int bt_hogp_suspend(struct bt_hogp *hogp);
524596
*/
525597
int bt_hogp_exit_suspend(struct bt_hogp *hogp);
526598

599+
#if defined(CONFIG_BT_HOGP_SCI)
600+
/**
601+
* @brief Read the current HID SCI mode from the HID device.
602+
* @param hogp HOGP object.
603+
* @param mode Pointer to the HID SCI mode value to read.
604+
*
605+
* @retval 0 If the operation was successful.
606+
* Otherwise, a (negative) error code is returned.
607+
*/
608+
int bt_hogp_sci_mode_read(struct bt_hogp *hogp, bt_hogp_sci_mode_read_cb func);
609+
610+
/**
611+
* @brief Request HID SCI mode activation.
612+
*
613+
* This function is used to request that the HID device enters a specific
614+
* HID SCI mode
615+
*
616+
* @param hogp HOGP object.
617+
* @param mode HID SCI mode to enable
618+
*
619+
* @retval 0 If the operation was successful.
620+
* Otherwise, a (negative) error code is returned.
621+
*/
622+
int bt_hogp_sci_mode_req(struct bt_hogp *hogp, enum bt_hids_sci_mode_value mode);
623+
624+
/**
625+
* @brief Subscribe to HID SCI mode changed notifications.
626+
* @param hogp HOGP object.
627+
* @param func Function to call when the SCI mode is changed.
628+
*
629+
* @retval 0 If the operation was successful.
630+
* Otherwise, a (negative) error code is returned.
631+
*/
632+
int bt_hogp_sci_mode_subscribe(struct bt_hogp *hogp, bt_hogp_sci_mode_changed_cb func);
633+
634+
/**
635+
* @brief Unsubscribe from SCI mode changed notifications.
636+
* @param hogp HOGP object.
637+
*
638+
* @retval 0 If the operation was successful.
639+
* Otherwise, a (negative) error code is returned.
640+
*/
641+
int bt_hogp_sci_mode_unsubscribe(struct bt_hogp *hogp);
642+
/**
643+
* @brief Get the cached HID SCI Information.
644+
*
645+
* This function fills the SCI Information structure with the cached SCI Information.
646+
* It does not generate any traffic on the radio.
647+
*
648+
* @param hogp HOGP object.
649+
* @param sci_info Pointer to the SCI Information structure to fill.
650+
*
651+
* @retval 0 If the operation was successful.
652+
* Otherwise, a (negative) error code is returned.
653+
*/
654+
int bt_hogp_sci_info_get(struct bt_hogp *hogp, struct bt_hogp_sci_info *sci_info);
655+
656+
#endif
527657

528658
/**
529659
* @brief Get the connection object from the HIDS client.

subsys/bluetooth/services/Kconfig.hids

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ config BT_HIDS_DEFAULT_PERM_RW_AUTHEN
6868

6969
endchoice
7070

71+
rsource "Kconfig.hids.sci"
72+
7173
module = BT_HIDS
7274
module-str = HIDS
7375
source "$(ZEPHYR_BASE)/subsys/logging/Kconfig.template.log_config"

0 commit comments

Comments
 (0)