@@ -82,44 +82,21 @@ static struct usb_hid_device *dev_to_hid(const struct device *dev)
8282 return usb_hid ;
8383}
8484
85- static int get_report (const struct device * dev ,
86- struct usb_setup_packet * setup ,
87- int32_t * len_to_set , uint8_t * * data )
85+ static int get_report (const struct device * dev , uint8_t report_type , uint8_t report_id ,
86+ uint8_t * buf , size_t size )
8887{
89- uint8_t request_value [2 ];
90-
91- sys_put_le16 (setup -> wValue , request_value );
88+ int err = - ENOTSUP ;
9289
93- switch (request_value [ 1 ] ) {
90+ switch (report_type ) {
9491 case REPORT_TYPE_FEATURE :
9592 if (IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE ) &&
96- (request_value [0 ] == REPORT_ID_USER_CONFIG ) &&
97- (setup -> wLength == (REPORT_SIZE_USER_CONFIG + sizeof (uint8_t )))) {
98- size_t length = setup -> wLength ;
99- uint8_t * buffer = * data ;
100-
101- /* HID Feature report ID is specific to USB.
102- * Config channel does not use it.
103- */
104- buffer [0 ] = REPORT_ID_USER_CONFIG ;
105-
106- int err = 0 ;
107-
93+ (report_id == REPORT_ID_USER_CONFIG ) &&
94+ (size == REPORT_SIZE_USER_CONFIG )) {
10895 if (dev == usb_hid_device [0 ].dev ) {
109- err = config_channel_transport_get (& cfg_chan_transport ,
110- & buffer [1 ],
111- length - 1 );
96+ err = config_channel_transport_get (& cfg_chan_transport , buf , size );
11297 } else {
113- err = config_channel_transport_get_disabled (& buffer [1 ], length - 1 );
114- }
115-
116- if (err ) {
117- LOG_WRN ("Failed to process report get (err: %d)" , err );
98+ err = config_channel_transport_get_disabled (buf , size );
11899 }
119-
120- * len_to_set = length ;
121-
122- return err ;
123100 }
124101 break ;
125102
@@ -132,46 +109,26 @@ static int get_report(const struct device *dev,
132109 break ;
133110 }
134111
135- LOG_WRN ("Unsupported get report" );
136- LOG_WRN ("bmRequestType: %02X bRequest: %02X wValue: %04X wIndex: %04X"
137- " wLength: %04X" , setup -> bmRequestType , setup -> bRequest ,
138- setup -> wValue , setup -> wIndex , setup -> wLength );
139-
140- return - ENOTSUP ;
112+ return err ;
141113}
142114
143- static int set_report (const struct device * dev ,
144- struct usb_setup_packet * setup ,
145- int32_t * len , uint8_t * * data )
115+ static int set_report (const struct device * dev , uint8_t report_type , uint8_t report_id ,
116+ const uint8_t * buf , size_t size )
146117{
147- uint8_t request_value [ 2 ] ;
118+ int err = - ENOTSUP ;
148119
149- sys_put_le16 (setup -> wValue , request_value );
150-
151- switch (request_value [1 ]) {
120+ switch (report_type ) {
152121 case REPORT_TYPE_FEATURE :
153122 if (IS_ENABLED (CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE ) &&
154- (request_value [ 0 ] == REPORT_ID_USER_CONFIG ) &&
155- (setup -> wLength == ( REPORT_SIZE_USER_CONFIG + sizeof ( uint8_t )) )) {
123+ (report_id == REPORT_ID_USER_CONFIG ) &&
124+ (size == REPORT_SIZE_USER_CONFIG )) {
156125 if (dev == usb_hid_device [0 ].dev ) {
157- size_t length = setup -> wLength ;
158- uint8_t * buffer = * data ;
159-
160- /* HID Feature report ID is specific to USB.
161- * Config channel does not use it.
162- */
163- int err = config_channel_transport_set (& cfg_chan_transport ,
164- & buffer [1 ],
165- length - 1 );
166-
167- if (err ) {
168- LOG_WRN ("Failed to process report set" );
169- }
170-
171- return err ;
126+ err = config_channel_transport_set (& cfg_chan_transport , buf , size );
172127 } else {
173- /* Configuration channel does not use this USB HID instance. */
174- return 0 ;
128+ /* Ignore the request. Configuration channel does not use this USB
129+ * HID instance.
130+ */
131+ err = 0 ;
175132 }
176133 }
177134 break ;
@@ -180,38 +137,37 @@ static int set_report(const struct device *dev,
180137 if (IS_ENABLED (CONFIG_DESKTOP_HID_REPORT_KEYBOARD_SUPPORT )) {
181138 struct usb_hid_device * usb_hid = dev_to_hid (dev );
182139
183- if ((request_value [ 0 ] == REPORT_ID_KEYBOARD_LEDS ) &&
140+ if ((report_id == REPORT_ID_KEYBOARD_LEDS ) &&
184141 (usb_hid -> hid_protocol == HID_PROTOCOL_REPORT ) &&
185- (setup -> wLength == ( REPORT_SIZE_KEYBOARD_LEDS + sizeof ( uint8_t )) )) {
142+ (size == REPORT_SIZE_KEYBOARD_LEDS )) {
186143 /* Handle HID keyboard LEDs report. */
187144 } else if (IS_ENABLED (CONFIG_DESKTOP_HID_BOOT_INTERFACE_KEYBOARD ) &&
188- (request_value [ 0 ] == REPORT_ID_RESERVED ) &&
145+ (report_id == REPORT_ID_RESERVED ) &&
189146 (usb_hid -> hid_protocol == HID_PROTOCOL_BOOT ) &&
190- (setup -> wLength == REPORT_SIZE_KEYBOARD_LEDS )) {
147+ (size == REPORT_SIZE_KEYBOARD_LEDS )) {
191148 /* Handle HID boot keyboard LEDs report. */
192149 } else {
193150 /* Ignore invalid report. */
194151 break ;
195152 }
196153
197- size_t dyndata_len = REPORT_SIZE_KEYBOARD_LEDS + sizeof (uint8_t );
154+ size_t dyndata_len = sizeof (uint8_t ) + REPORT_SIZE_KEYBOARD_LEDS ;
198155 struct hid_report_event * event = new_hid_report_event (dyndata_len );
199156
200157 event -> source = usb_hid ;
201158 /* Subscriber is not specified for HID output report. */
202159 event -> subscriber = NULL ;
203160
204- uint8_t * buf = event -> dyndata .data ;
205-
206- if (setup -> wLength == REPORT_SIZE_KEYBOARD_LEDS ) {
207- * buf = REPORT_ID_KEYBOARD_LEDS ;
208- buf ++ ;
209- }
161+ uint8_t * evt_buf = event -> dyndata .data ;
210162
211- memcpy (buf , * data , setup -> wLength );
163+ /* Explicitly add report ID. */
164+ evt_buf [0 ] = REPORT_ID_KEYBOARD_LEDS ;
165+ evt_buf ++ ;
212166
167+ memcpy (evt_buf , buf , size );
213168 APP_EVENT_SUBMIT (event );
214- return 0 ;
169+
170+ err = 0 ;
215171 }
216172 break ;
217173
@@ -221,12 +177,7 @@ static int set_report(const struct device *dev,
221177 break ;
222178 }
223179
224- LOG_WRN ("Unsupported set report" );
225- LOG_WRN ("bmRequestType: %02X bRequest: %02X wValue: %04X wIndex: %04X"
226- " wLength: %04X" , setup -> bmRequestType , setup -> bRequest ,
227- setup -> wValue , setup -> wIndex , setup -> wLength );
228-
229- return - ENOTSUP ;
180+ return err ;
230181}
231182
232183static void report_sent (const struct device * dev , bool error )
@@ -630,11 +581,99 @@ static void verify_report_bm(void)
630581#endif
631582}
632583
584+ static void report_legacy_wValue_parse (uint16_t wValue , uint8_t * report_type , uint8_t * report_id )
585+ {
586+ uint8_t request_value [2 ];
587+
588+ sys_put_le16 (wValue , request_value );
589+ * report_type = request_value [1 ];
590+ * report_id = request_value [0 ];
591+ }
592+
593+ static int get_report_legacy (const struct device * dev , struct usb_setup_packet * setup ,
594+ int32_t * len_to_set , uint8_t * * data )
595+ {
596+ __ASSERT_NO_MSG (dev );
597+ __ASSERT_NO_MSG (setup );
598+ __ASSERT_NO_MSG (len_to_set );
599+ __ASSERT_NO_MSG (data );
600+
601+ uint8_t report_type ;
602+ uint8_t report_id ;
603+ uint8_t * buf = * data ;
604+ size_t size = setup -> wLength ;
605+
606+ report_legacy_wValue_parse (setup -> wValue , & report_type , & report_id );
607+
608+ if (report_id != REPORT_ID_RESERVED ) {
609+ buf [0 ] = report_id ;
610+ buf ++ ;
611+ size -- ;
612+ }
613+
614+ int err = get_report (dev , report_type , report_id , buf , size );
615+
616+ if (err ) {
617+ LOG_WRN ("get_report_legacy failed (err: %d)" , err );
618+ LOG_WRN ("bmRequestType: %02X bRequest: %02X wValue: %04X wIndex: %04X"
619+ " wLength: %04X" , setup -> bmRequestType , setup -> bRequest ,
620+ setup -> wValue , setup -> wIndex , setup -> wLength );
621+ LOG_HEXDUMP_WRN (buf , size , "Get report" );
622+ } else {
623+ * len_to_set = setup -> wLength ;
624+ }
625+
626+ return err ;
627+ }
628+
629+ static int set_report_legacy (const struct device * dev , struct usb_setup_packet * setup ,
630+ int32_t * len , uint8_t * * data )
631+ {
632+ __ASSERT_NO_MSG (dev );
633+ __ASSERT_NO_MSG (setup );
634+ __ASSERT_NO_MSG (len );
635+ __ASSERT_NO_MSG (data );
636+
637+ uint8_t report_type ;
638+ uint8_t report_id ;
639+ uint8_t * buf = * data ;
640+ size_t size = setup -> wLength ;
641+
642+ report_legacy_wValue_parse (setup -> wValue , & report_type , & report_id );
643+
644+ int err = 0 ;
645+
646+ if (report_id != REPORT_ID_RESERVED ) {
647+ /* The first byte of buf is report ID. Validate it and omit. */
648+ if (report_id == buf [0 ]) {
649+ buf ++ ;
650+ size -- ;
651+ } else {
652+ LOG_WRN ("HID report ID mismatch" );
653+ err = - EINVAL ;
654+ }
655+ }
656+
657+ if (!err ) {
658+ err = set_report (dev , report_type , report_id , buf , size );
659+ }
660+
661+ if (err ) {
662+ LOG_WRN ("set_report_legacy failed (err: %d)" , err );
663+ LOG_WRN ("bmRequestType: %02X bRequest: %02X wValue: %04X wIndex: %04X"
664+ " wLength: %04X" , setup -> bmRequestType , setup -> bRequest ,
665+ setup -> wValue , setup -> wIndex , setup -> wLength );
666+ LOG_HEXDUMP_WRN (buf , size , "Set report" );
667+ }
668+
669+ return err ;
670+ }
671+
633672static int usb_init (void )
634673{
635674 static const struct hid_ops hid_ops = {
636- .get_report = get_report ,
637- .set_report = set_report ,
675+ .get_report = get_report_legacy ,
676+ .set_report = set_report_legacy ,
638677 .int_in_ready = report_sent_cb ,
639678 .protocol_change = protocol_change ,
640679 };
0 commit comments