@@ -192,49 +192,93 @@ static void report_sent_cb(struct bt_conn *conn, void *user_data)
192192 hid_report_sent (conn , report_id , false);
193193}
194194
195- static void broadcast_kbd_leds_report (struct bt_hids_rep * rep , struct bt_conn * conn , bool write )
195+ static void output_report_handler_async (struct bt_hids_rep * rep , struct bt_conn * conn , bool write )
196196{
197- /* Ignore HID keyboard LEDs report read. */
198197 if (!write ) {
198+ /* Ignore reads on output reports. */
199199 return ;
200200 }
201201
202- struct hid_report_event * event = new_hid_report_event (rep -> size + 1 );
202+ /* Check if report is supported. */
203+ size_t i ;
204+
205+ for (i = 0 ; i < ARRAY_SIZE (output_reports ); i ++ ) {
206+ if (rep -> id == output_reports [i ]) {
207+ break ;
208+ }
209+ }
210+
211+ if (i == ARRAY_SIZE (output_reports )) {
212+ LOG_ERR ("Unsupported output report ID: 0x%" PRIx8 , rep -> id );
213+ return ;
214+ }
215+
216+ if (rep -> size > REPORT_BUFFER_SIZE_OUTPUT_REPORT ) {
217+ LOG_ERR ("Unsupported output report size %" PRIu8 , rep -> size );
218+ return ;
219+ }
220+
221+ size_t dyndata_len = sizeof (rep -> id ) + rep -> size ;
222+ struct hid_report_event * event = new_hid_report_event (dyndata_len );
203223
204224 event -> source = conn ;
205225 /* Subscriber is not specified for HID output report. */
206226 event -> subscriber = NULL ;
207- event -> dyndata .data [0 ] = REPORT_ID_KEYBOARD_LEDS ;
208- memcpy (& event -> dyndata .data [1 ], rep -> data , rep -> size );
209227
228+ uint8_t * evt_buf = event -> dyndata .data ;
229+
230+ /* Explicitly add report ID. */
231+ evt_buf [0 ] = rep -> id ;
232+ evt_buf ++ ;
233+
234+ memcpy (evt_buf , rep -> data , rep -> size );
210235 APP_EVENT_SUBMIT (event );
211236}
212237
213- static void feature_report_handler (struct bt_hids_rep * rep ,
214- struct bt_conn * conn ,
215- bool write )
238+ static bool is_supported_config_channel_report_id (uint8_t rep_id )
216239{
217- if ( IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE )) {
218- if (! write ) {
219- int err = config_channel_transport_get ( & cfg_chan_transport ,
220- rep -> data ,
221- rep -> size );
240+ return (( IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE ) &&
241+ ( rep_id == REPORT_ID_USER_CONFIG )) ||
242+ ( IS_ENABLED ( CONFIG_DESKTOP_CONFIG_CHANNEL_OUT_REPORT ) &&
243+ ( rep_id == REPORT_ID_USER_CONFIG_OUT )));
244+ }
222245
223- if ( err ) {
224- LOG_WRN ( "Failed to process report get" );
225- }
226- } else {
227- int err = config_channel_transport_set ( & cfg_chan_transport ,
228- rep -> data ,
229- rep -> size );
246+ static void config_channel_report_handler_async ( struct bt_hids_rep * rep , struct bt_conn * conn ,
247+ bool write )
248+ {
249+ if (! is_supported_config_channel_report_id ( rep -> id )) {
250+ LOG_ERR ( "Not a supported config channel report ID: 0x%" PRIx8 , rep -> id );
251+ return ;
252+ }
230253
231- if (err ) {
232- LOG_WRN ("Failed to process report set" );
233- }
254+ if (!write ) {
255+ int err = config_channel_transport_get (& cfg_chan_transport ,
256+ rep -> data ,
257+ rep -> size );
258+ if (err ) {
259+ LOG_WRN ("config_channel_transport_get failed (err: %d)" , err );
260+ }
261+ } else {
262+ int err = config_channel_transport_set (& cfg_chan_transport ,
263+ rep -> data ,
264+ rep -> size );
265+ if (err ) {
266+ LOG_WRN ("config_channel_transport_set failed (err: %d)" , err );
234267 }
235268 }
236269}
237270
271+ static void boot_keyboard_output_report_handler (struct bt_hids_rep * rep ,
272+ struct bt_conn * conn ,
273+ bool write )
274+ {
275+ /* Update the passed report ID. */
276+ struct bt_hids_rep updated_rep = * rep ;
277+
278+ updated_rep .id = REPORT_ID_KEYBOARD_LEDS ;
279+ return output_report_handler_async (& updated_rep , conn , write );
280+ }
281+
238282static int module_init (void )
239283{
240284 /* HID service configuration */
@@ -324,9 +368,9 @@ static int module_init(void)
324368 hids_init_param .inp_rep_group_init .cnt = ir_pos ;
325369
326370 if (IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE )) {
327- feature_report [feat_pos ].id = REPORT_ID_USER_CONFIG ;
328- feature_report [feat_pos ].size = REPORT_SIZE_USER_CONFIG ;
329- feature_report [feat_pos ].handler = feature_report_handler ;
371+ feature_report [feat_pos ].id = REPORT_ID_USER_CONFIG ;
372+ feature_report [feat_pos ].size = REPORT_SIZE_USER_CONFIG ;
373+ feature_report [feat_pos ].handler = config_channel_report_handler_async ;
330374
331375 report_index [feature_report [feat_pos ].id ] = feat_pos ;
332376 feat_pos ++ ;
@@ -335,19 +379,20 @@ static int module_init(void)
335379 hids_init_param .feat_rep_group_init .cnt = feat_pos ;
336380
337381 if (IS_ENABLED (CONFIG_DESKTOP_HID_REPORT_KEYBOARD_SUPPORT )) {
338- output_report [or_pos ].id = REPORT_ID_KEYBOARD_LEDS ;
339- output_report [or_pos ].size = REPORT_SIZE_KEYBOARD_LEDS ;
340- output_report [or_pos ].handler = broadcast_kbd_leds_report ;
382+ output_report [or_pos ].id = REPORT_ID_KEYBOARD_LEDS ;
383+ output_report [or_pos ].size = REPORT_SIZE_KEYBOARD_LEDS ;
384+ output_report [or_pos ].handler = output_report_handler_async ;
341385
342386 report_index [output_report [or_pos ].id ] = or_pos ;
343387 or_pos ++ ;
344388 }
345389
346390 if (IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_OUT_REPORT )) {
347- __ASSERT_NO_MSG (IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE ));
348- output_report [or_pos ].id = REPORT_ID_USER_CONFIG_OUT ;
349- output_report [or_pos ].size = REPORT_SIZE_USER_CONFIG ;
350- output_report [or_pos ].handler = feature_report_handler ;
391+ BUILD_ASSERT (!IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_OUT_REPORT ) ||
392+ IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE ));
393+ output_report [or_pos ].id = REPORT_ID_USER_CONFIG_OUT ;
394+ output_report [or_pos ].size = REPORT_SIZE_USER_CONFIG ;
395+ output_report [or_pos ].handler = config_channel_report_handler_async ;
351396
352397 report_index [output_report [or_pos ].id ] = or_pos ;
353398 or_pos ++ ;
@@ -365,7 +410,7 @@ static int module_init(void)
365410 if (IS_ENABLED (CONFIG_DESKTOP_HID_BOOT_INTERFACE_KEYBOARD )) {
366411 hids_init_param .is_kb = true;
367412 hids_init_param .boot_kb_notif_handler = boot_keyboard_notif_handler ;
368- hids_init_param .boot_kb_outp_rep_handler = broadcast_kbd_leds_report ;
413+ hids_init_param .boot_kb_outp_rep_handler = boot_keyboard_output_report_handler ;
369414 }
370415
371416 if (IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE )) {
0 commit comments