xref: /btstack/src/classic/hid_device.c (revision e9c5f44ee8add45f6cd4be8b6faa9e09a2804fcc)
1 /*
2  * Copyright (C) 2014 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define __BTSTACK_FILE__ "hid_device.c"
39 
40 #include <string.h>
41 
42 #include "classic/hid_device.h"
43 #include "classic/sdp_util.h"
44 #include "bluetooth.h"
45 #include "bluetooth_sdp.h"
46 #include "l2cap.h"
47 #include "btstack_event.h"
48 #include "btstack_debug.h"
49 #include "btstack_hid_parser.h"
50 
51 typedef enum {
52     HID_DEVICE_IDLE,
53     HID_DEVICE_CONNECTED,
54     HID_DEVICE_W2_GET_REPORT,
55     HID_DEVICE_W2_SET_REPORT,
56     HID_DEVICE_W2_GET_PROTOCOL,
57     HID_DEVICE_W2_SET_PROTOCOL,
58     HID_DEVICE_W2_ANSWER_SET_PROTOCOL,
59     HID_DEVICE_W2_SEND_UNSUPPORTED_REQUEST,
60 } hid_device_state_t;
61 
62 // hid device state
63 typedef struct hid_device {
64     uint16_t  cid;
65     bd_addr_t bd_addr;
66     hci_con_handle_t con_handle;
67     uint16_t  control_cid;
68     uint16_t  interrupt_cid;
69     uint8_t   incoming;
70     uint8_t   connected;
71     hid_device_state_t state;
72     hid_report_type_t report_type;
73     uint16_t  report_id;
74     uint16_t  expected_report_size;
75     uint16_t  report_size;
76 
77     hid_handshake_param_type_t report_status;
78     hid_protocol_mode_t protocol_mode;
79 } hid_device_t;
80 
81 static hid_device_t _hid_device;
82 static uint8_t hid_boot_protocol_mode_supported;
83 static const uint8_t * hid_descriptor;
84 static uint16_t hid_descriptor_len;
85 
86 static int dummy_write_report(uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id, int * out_report_size, uint8_t * out_report){
87     UNUSED(hid_cid);
88     UNUSED(report_type);
89     UNUSED(report_id);
90     UNUSED(out_report_size);
91     UNUSED(out_report);
92     return -1;
93 }
94 
95 static void dummy_set_report(uint16_t hid_cid, hid_report_type_t report_type, int report_size, uint8_t * report){
96     UNUSED(hid_cid);
97     UNUSED(report_type);
98     UNUSED(report_size);
99     UNUSED(report);
100 }
101 
102 static void dummy_report_data(uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id, int report_size, uint8_t * report){
103     UNUSED(hid_cid);
104     UNUSED(report_type);
105     UNUSED(report_id);
106     UNUSED(report_size);
107     UNUSED(report);
108 }
109 
110 static int  (*hci_device_get_report) (uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id, int * out_report_size, uint8_t * out_report) = dummy_write_report;
111 static void (*hci_device_set_report)   (uint16_t hid_cid, hid_report_type_t report_type, int report_size, uint8_t * report) = dummy_set_report;
112 static void (*hci_device_report_data)  (uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id, int report_size, uint8_t * report) = dummy_report_data;
113 
114 static btstack_packet_handler_t hid_callback;
115 
116 static uint16_t hid_device_cid = 0;
117 
118 static uint16_t hid_device_get_next_cid(void){
119     hid_device_cid++;
120     if (!hid_device_cid){
121         hid_device_cid = 1;
122     }
123     return hid_device_cid;
124 }
125 
126 // TODO: store hid device connection into list
127 static hid_device_t * hid_device_get_instance_for_cid(uint16_t cid){
128     // printf("control_cid 0x%02x, interrupt_cid 0x%02x, query_cid 0x%02x \n", _hid_device.control_cid,  _hid_device.interrupt_cid, cid);
129     if (_hid_device.cid == cid || _hid_device.control_cid == cid || _hid_device.interrupt_cid == cid){
130         return &_hid_device;
131     }
132     return NULL;
133 }
134 
135 static hid_device_t * hid_device_provide_instance_for_bt_addr(bd_addr_t bd_addr){
136     if (!_hid_device.cid){
137         memcpy(_hid_device.bd_addr, bd_addr, 6);
138         _hid_device.cid = hid_device_get_next_cid();
139         _hid_device.protocol_mode = HID_PROTOCOL_MODE_REPORT;
140     }
141     return &_hid_device;
142 }
143 
144 static hid_device_t * hid_device_get_instance_for_con_handle(uint16_t con_handle){
145     UNUSED(con_handle);
146     return &_hid_device;
147 }
148 
149 static hid_device_t * hid_device_create_instance(void){
150 
151     return &_hid_device;
152 }
153 
154 void hid_create_sdp_record(
155     uint8_t *service,
156     uint32_t service_record_handle,
157     uint16_t hid_device_subclass,
158     uint8_t  hid_country_code,
159     uint8_t  hid_virtual_cable,
160     uint8_t  hid_reconnect_initiate,
161     uint8_t  hid_boot_device,
162     const uint8_t * descriptor, uint16_t descriptor_size,
163     const char *device_name){
164 
165     uint8_t * attribute;
166     de_create_sequence(service);
167 
168     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
169     de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
170 
171     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
172     attribute = de_push_sequence(service);
173     {
174         de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
175     }
176     de_pop_sequence(service, attribute);
177 
178     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
179     attribute = de_push_sequence(service);
180     {
181         uint8_t * l2cpProtocol = de_push_sequence(attribute);
182         {
183             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
184             de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, PSM_HID_CONTROL);
185         }
186         de_pop_sequence(attribute, l2cpProtocol);
187 
188         uint8_t * hidProtocol = de_push_sequence(attribute);
189         {
190             de_add_number(hidProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_HIDP);
191         }
192         de_pop_sequence(attribute, hidProtocol);
193     }
194     de_pop_sequence(service, attribute);
195 
196     // TODO?
197     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
198     attribute = de_push_sequence(service);
199     {
200         de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x656e);
201         de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x006a);
202         de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x0100);
203     }
204     de_pop_sequence(service, attribute);
205 
206     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS);
207     attribute = de_push_sequence(service);
208     {
209         uint8_t * additionalDescriptorAttribute = de_push_sequence(attribute);
210         {
211             uint8_t * l2cpProtocol = de_push_sequence(additionalDescriptorAttribute);
212             {
213                 de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
214                 de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, PSM_HID_INTERRUPT);
215             }
216             de_pop_sequence(additionalDescriptorAttribute, l2cpProtocol);
217 
218             uint8_t * hidProtocol = de_push_sequence(additionalDescriptorAttribute);
219             {
220                 de_add_number(hidProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_HIDP);
221             }
222             de_pop_sequence(additionalDescriptorAttribute, hidProtocol);
223         }
224         de_pop_sequence(attribute, additionalDescriptorAttribute);
225     }
226     de_pop_sequence(service, attribute);
227 
228     // 0x0100 "ServiceName"
229     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
230     de_add_data(service,  DE_STRING, strlen(device_name), (uint8_t *) device_name);
231 
232     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
233     attribute = de_push_sequence(service);
234     {
235         uint8_t * hidProfile = de_push_sequence(attribute);
236         {
237             de_add_number(hidProfile,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
238             de_add_number(hidProfile,  DE_UINT, DE_SIZE_16, 0x0101);    // Version 1.1
239         }
240         de_pop_sequence(attribute, hidProfile);
241     }
242     de_pop_sequence(service, attribute);
243 
244     // Deprecated in v1.1.1
245     // de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DEVICE_RELEASE_NUMBER);
246     // de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0101);
247 
248     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_PARSER_VERSION);
249     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0111);  // v1.1.1
250 
251     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DEVICE_SUBCLASS);
252     de_add_number(service,  DE_UINT, DE_SIZE_8,  hid_device_subclass);
253 
254     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_COUNTRY_CODE);
255     de_add_number(service,  DE_UINT, DE_SIZE_8,  hid_country_code);
256 
257     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_VIRTUAL_CABLE);
258     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_virtual_cable);
259 
260     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_RECONNECT_INITIATE);
261     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_reconnect_initiate);
262 
263     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST);
264     attribute = de_push_sequence(service);
265     {
266         uint8_t* hidDescriptor = de_push_sequence(attribute);
267         {
268             de_add_number(hidDescriptor,  DE_UINT, DE_SIZE_8, 0x22);    // Report Descriptor
269             de_add_data(hidDescriptor,  DE_STRING, descriptor_size, (uint8_t *) descriptor);
270         }
271         de_pop_sequence(attribute, hidDescriptor);
272     }
273     de_pop_sequence(service, attribute);
274 
275     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HIDLANGID_BASE_LIST);
276     attribute = de_push_sequence(service);
277     {
278         uint8_t* hig_lang_base = de_push_sequence(attribute);
279         {
280             // see: http://www.usb.org/developers/docs/USB_LANGIDs.pdf
281             de_add_number(hig_lang_base,  DE_UINT, DE_SIZE_16, 0x0409);    // HIDLANGID = English (US)
282             de_add_number(hig_lang_base,  DE_UINT, DE_SIZE_16, 0x0100);    // HIDLanguageBase = 0x0100 default
283         }
284         de_pop_sequence(attribute, hig_lang_base);
285     }
286     de_pop_sequence(service, attribute);
287 
288     uint8_t hid_remote_wake = 1;
289     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_REMOTE_WAKE);
290     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_remote_wake);
291 
292     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_BOOT_DEVICE);
293     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_boot_device);
294 }
295 
296 static inline void hid_device_emit_connected_event(hid_device_t * context, uint8_t status){
297     uint8_t event[15];
298     int pos = 0;
299     event[pos++] = HCI_EVENT_HID_META;
300     pos++;  // skip len
301     event[pos++] = HID_SUBEVENT_CONNECTION_OPENED;
302     little_endian_store_16(event,pos,context->cid);
303     pos+=2;
304     event[pos++] = status;
305     reverse_bd_addr(context->bd_addr, &event[pos]);
306     pos += 6;
307     little_endian_store_16(event,pos,context->con_handle);
308     pos += 2;
309     event[pos++] = context->incoming;
310     event[1] = pos - 2;
311     if (pos != sizeof(event)) log_error("hid_device_emit_connected_event size %u", pos);
312     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
313 }
314 
315 static inline void hid_device_emit_connection_closed_event(hid_device_t * context){
316     uint8_t event[5];
317     int pos = 0;
318     event[pos++] = HCI_EVENT_HID_META;
319     pos++;  // skip len
320     event[pos++] = HID_SUBEVENT_CONNECTION_CLOSED;
321     little_endian_store_16(event,pos,context->cid);
322     pos+=2;
323     event[1] = pos - 2;
324     if (pos != sizeof(event)) log_error("hid_device_emit_connection_closed_event size %u", pos);
325     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
326 }
327 
328 static inline void hid_device_emit_can_send_now_event(hid_device_t * context){
329     uint8_t event[5];
330     int pos = 0;
331     event[pos++] = HCI_EVENT_HID_META;
332     pos++;  // skip len
333     event[pos++] = HID_SUBEVENT_CAN_SEND_NOW;
334     little_endian_store_16(event,pos,context->cid);
335     pos+=2;
336     event[1] = pos - 2;
337     if (pos != sizeof(event)) log_error("hid_device_emit_can_send_now_event size %u", pos);
338     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
339 }
340 
341 static inline void hid_device_emit_event(hid_device_t * context, uint8_t subevent_type){
342     uint8_t event[4];
343     int pos = 0;
344     event[pos++] = HCI_EVENT_HID_META;
345     pos++;  // skip len
346     event[pos++] = subevent_type;
347     little_endian_store_16(event,pos,context->cid);
348     pos+=2;
349     event[1] = pos - 2;
350     if (pos != sizeof(event)) log_error("hid_device_emit_event size %u", pos);
351     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
352 }
353 
354 static int hid_report_size_valid(uint16_t cid, int report_id, hid_report_type_t report_type, int report_size){
355     if (!report_size) return 0;
356     if (hid_device_in_boot_protocol_mode(cid)){
357         switch (report_id){
358             case HID_BOOT_MODE_KEYBOARD_ID:
359                 if (report_size < 8) return 0;
360                 break;
361             case HID_BOOT_MODE_MOUSE_ID:
362                 if (report_size < 1) return 0;
363                 break;
364             default:
365                 return 0;
366         }
367     } else {
368         int size =  btstack_hid_get_report_size_for_id(report_id, report_type, hid_descriptor_len, hid_descriptor);
369         if (size == 0 || size != report_size) return 0;
370     }
371     return 1;
372 }
373 
374 static int hid_get_report_size_for_id(uint16_t cid, int report_id, hid_report_type_t report_type, uint16_t descriptor_len, const uint8_t * descriptor){
375     if (hid_device_in_boot_protocol_mode(cid)){
376         switch (report_id){
377             case HID_BOOT_MODE_KEYBOARD_ID:
378                 return 8;
379             case HID_BOOT_MODE_MOUSE_ID:
380                 return 3;
381             default:
382                 return 0;
383         }
384     } else {
385         return btstack_hid_get_report_size_for_id(report_id, report_type, descriptor_len, descriptor);
386     }
387 }
388 
389 static hid_report_id_status_t hid_report_id_status(uint16_t cid, uint16_t report_id){
390     if (hid_device_in_boot_protocol_mode(cid)){
391         switch (report_id){
392             case HID_BOOT_MODE_KEYBOARD_ID:
393             case HID_BOOT_MODE_MOUSE_ID:
394                 return HID_REPORT_ID_VALID;
395             default:
396                 return HID_REPORT_ID_INVALID;
397         }
398     } else {
399         return btstack_hid_id_valid(report_id, hid_descriptor_len, hid_descriptor);
400     }
401 }
402 
403 static hid_handshake_param_type_t hid_device_set_report_cmd_is_valid(uint16_t cid, hid_report_type_t report_type, int report_size, uint8_t * report){
404     int pos = 0;
405     int report_id = 0;
406 
407     if (btstack_hid_report_id_declared(hid_descriptor_len, hid_descriptor)){
408         report_id = report[pos++];
409         hid_report_id_status_t report_id_status = hid_report_id_status(cid, report_id);
410         switch (report_id_status){
411             case HID_REPORT_ID_INVALID:
412                 return HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_REPORT_ID;
413             default:
414                 break;
415         }
416         // printf("hid_device_set_report_cmd_is_valid: report_id %d, status %d \n", report_id, report_id_status);
417     }
418 
419     if (!hid_report_size_valid(cid, report_id, report_type, report_size-pos)){
420         // TODO clarify DCT/BI-03c
421         return HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
422     }
423     return HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL;
424 }
425 
426 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t packet_size){
427     UNUSED(channel);
428     UNUSED(packet_size);
429     int connected_before;
430     uint16_t psm;
431     uint8_t status;
432     hid_device_t * device = NULL;
433     uint8_t param;
434     bd_addr_t address;
435     uint16_t local_cid;
436     int pos = 0;
437     int report_size;
438     uint8_t report[48];
439     hid_message_type_t message_type;
440 
441     switch (packet_type){
442         case L2CAP_DATA_PACKET:
443             device = hid_device_get_instance_for_cid(channel);
444             if (!device) {
445                 log_error("no device with cid 0x%02x", channel);
446                 return;
447             }
448             message_type = (hid_message_type_t)(packet[0] >> 4);
449             // printf("L2CAP_DATA_PACKET message_type %d, packet_size %d  \n", message_type, packet_size);
450             switch (message_type){
451                 case HID_MESSAGE_TYPE_GET_REPORT:
452 
453                     pos = 0;
454                     device->report_type = (hid_report_type_t)(packet[pos++] & 0x03);
455                     device->report_id = 0;
456                     device->report_status = HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL;
457                     device->state = HID_DEVICE_W2_GET_REPORT;
458 
459                     switch (device->protocol_mode){
460                         case HID_PROTOCOL_MODE_BOOT:
461                             if (packet_size < 2){
462                                 device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
463                                 break;
464                             }
465                             device->report_id = packet[pos++];
466                             break;
467                         case HID_PROTOCOL_MODE_REPORT:
468                             if (!btstack_hid_report_id_declared(hid_descriptor_len, hid_descriptor)) {
469                                 if (packet_size < 2) break;
470                                 if (packet[0] & 0x08){
471                                     if (packet_size > 2) {
472                                         device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_REPORT_ID;
473                                     }
474                                 } else {
475                                     if (packet_size > 1) {
476                                         device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_REPORT_ID;
477                                     }
478                                 }
479                                 break;
480                             }
481                             if (packet_size < 2){
482                                 device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
483                                 break;
484                             }
485                             device->report_id = packet[pos++];
486                             break;
487                     }
488                     if (device->report_status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL){
489                         hid_device_request_can_send_now_event(channel);
490                         break;
491                     }
492                     switch (hid_report_id_status(device->cid, device->report_id)){
493                         case HID_REPORT_ID_INVALID:
494                             device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_REPORT_ID;
495                             break;
496                         default:
497                             break;
498                     }
499 
500                     device->expected_report_size = hid_get_report_size_for_id(device->cid, device->report_id, device->report_type, hid_descriptor_len, hid_descriptor);
501                     report_size =  device->expected_report_size + pos; // add 1 for header size and report id
502 
503                     if ((packet[0] & 0x08) && packet_size >= pos + 1){
504                         device->report_size = btstack_min(btstack_min(little_endian_read_16(packet, pos), report_size), sizeof(report));
505                     } else {
506                         device->report_size = btstack_min(btstack_min(l2cap_max_mtu(), report_size), sizeof(report));
507                     }
508 
509                     hid_device_request_can_send_now_event(channel);
510                     break;
511 
512                 case HID_MESSAGE_TYPE_SET_REPORT:
513                     device->state = HID_DEVICE_W2_SET_REPORT;
514                     device->report_size = l2cap_max_mtu();
515                     device->report_type = (hid_report_type_t)(packet[0] & 0x03);
516                     if (packet_size < 1){
517                         device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
518                         break;
519                     }
520 
521                     switch (device->protocol_mode){
522                         case HID_PROTOCOL_MODE_BOOT:
523                             // printf("HID_PROTOCOL_MODE_BOOT \n");
524                             if (packet_size < 3){
525                                 device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
526                                 break;
527                             }
528                             device->report_id = packet[1];
529                             device->report_status = hid_device_set_report_cmd_is_valid(device->cid, device->report_type, packet_size - 1, &packet[1]);
530                             if (device->report_status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL) break;
531                             (*hci_device_set_report)(device->cid, device->report_type, packet_size-1, &packet[1]);
532                             break;
533                         case HID_PROTOCOL_MODE_REPORT:
534                             // printf("HID_PROTOCOL_MODE_REPORT \n");
535                             device->report_status = hid_device_set_report_cmd_is_valid(device->cid, device->report_type, packet_size - 1, &packet[1]);
536                             if (device->report_status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL) break;
537 
538                             if (packet_size >= 2){
539                                 (*hci_device_set_report)(device->cid, device->report_type, packet_size-1, &packet[1]);
540                             } else {
541                                 uint8_t payload[] = {0};
542                                 (*hci_device_set_report)(device->cid, device->report_type, 1, payload);
543                             }
544                             break;
545                     }
546                     device->report_type = (hid_report_type_t)(packet[0] & 0x03);
547                     hid_device_request_can_send_now_event(channel);
548                     // l2cap_request_can_send_now_event(device->control_cid);
549                     break;
550                 case HID_MESSAGE_TYPE_GET_PROTOCOL:
551                     // printf(" HID_MESSAGE_TYPE_GET_PROTOCOL\n");
552                     device->state = HID_DEVICE_W2_GET_PROTOCOL;
553                     if (packet_size != 1) {
554                         device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
555                         break;
556                     }
557                     device->report_status = HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL;
558                     // hid_device_request_can_send_now_event(channel);
559                     // printf("HID_MESSAGE_TYPE_GET_PROTOCOL l2cap_request_can_send_now_event\n");
560                     l2cap_request_can_send_now_event(device->control_cid);
561                     break;
562 
563                 case HID_MESSAGE_TYPE_SET_PROTOCOL:
564                     device->state = HID_DEVICE_W2_SET_PROTOCOL;
565                     if (packet_size != 1) {
566                         device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
567                         break;
568                     }
569                     param = packet[0] & 0x01;
570                     if (param == HID_PROTOCOL_MODE_BOOT && !hid_boot_protocol_mode_supported){
571                         device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
572                         break;
573                     }
574                     device->protocol_mode = (hid_protocol_mode_t) param;
575                     switch (device->protocol_mode){
576                         case HID_PROTOCOL_MODE_BOOT:
577                             // printf("Set protocol mode to BOOT\n");
578                             break;
579                         case HID_PROTOCOL_MODE_REPORT:
580                             // printf("Set protocol mode to REPORT\n");
581                             break;
582                     }
583                     device->report_status = HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL;
584                     hid_device_request_can_send_now_event(channel);
585                     break;
586 
587                 case HID_MESSAGE_TYPE_HID_CONTROL:
588                     param = packet[0] & 0x0F;
589                     switch (param){
590                         case HID_CONTROL_PARAM_SUSPEND:
591                             hid_device_emit_event(device, HID_SUBEVENT_SUSPEND);
592                             break;
593                         case HID_CONTROL_PARAM_EXIT_SUSPEND:
594                             hid_device_emit_event(device, HID_SUBEVENT_EXIT_SUSPEND);
595                             break;
596                         default:
597                             device->state = HID_DEVICE_W2_SEND_UNSUPPORTED_REQUEST;
598                             hid_device_request_can_send_now_event(channel);
599                             // l2cap_request_can_send_now_event(device->control_cid);
600                             break;
601                     }
602                     break;
603 
604                 case HID_MESSAGE_TYPE_DATA:
605                     if (packet_size < 2) {
606                         break;
607                     }
608                     pos = 0;
609                     device->report_type = (hid_report_type_t)(packet[pos++] & 0x03);
610                     device->report_id = 0;
611                     if (btstack_hid_report_id_declared(hid_descriptor_len, hid_descriptor)){
612                         device->report_id = packet[pos++];
613                     }
614 
615                     if (hid_report_id_status(device->cid, device->report_id) == HID_REPORT_ID_INVALID){
616                         log_info("Ignore invalid report data packet");
617                         break;
618                     }
619                     if (!hid_report_size_valid(device->cid, device->report_id, device->report_type, packet_size - pos)){
620                         log_info("Ignore invalid report data packet, invalid size");
621                         break;
622                     }
623                     (*hci_device_report_data)(device->cid, device->report_type, device->report_id, packet_size - pos, &packet[pos]);
624                     break;
625                 default:
626                     // printf("HID_DEVICE_W2_SEND_UNSUPPORTED_REQUEST %d  \n", message_type);
627                     device->state = HID_DEVICE_W2_SEND_UNSUPPORTED_REQUEST;
628                     // l2cap_request_can_send_now_event(device->control_cid);
629                     hid_device_request_can_send_now_event(channel);
630                     break;
631             }
632             break;
633         case HCI_EVENT_PACKET:
634             switch (packet[0]){
635                 case L2CAP_EVENT_INCOMING_CONNECTION:
636                     switch (l2cap_event_incoming_connection_get_psm(packet)){
637                         case PSM_HID_CONTROL:
638                         case PSM_HID_INTERRUPT:
639                             l2cap_event_incoming_connection_get_address(packet, address);
640                             device = hid_device_provide_instance_for_bt_addr(address);
641                             if (!device) {
642                                 log_error("L2CAP_EVENT_INCOMING_CONNECTION, no hid device for con handle 0x%02x", l2cap_event_incoming_connection_get_handle(packet));
643                                 l2cap_decline_connection(channel);
644                                 break;
645                             }
646                             if (device->con_handle == 0 || l2cap_event_incoming_connection_get_handle(packet) == device->con_handle){
647                                 device->con_handle = l2cap_event_incoming_connection_get_handle(packet);
648                                 device->incoming = 1;
649                                 l2cap_event_incoming_connection_get_address(packet, device->bd_addr);
650                                 l2cap_accept_connection(channel);
651                             } else {
652                                 l2cap_decline_connection(channel);
653                                 log_error("L2CAP_EVENT_INCOMING_CONNECTION, decline connection for con handle 0x%02x", l2cap_event_incoming_connection_get_handle(packet));
654                             }
655                             break;
656                         default:
657                             l2cap_decline_connection(channel);
658                             break;
659                     }
660                     break;
661                 case L2CAP_EVENT_CHANNEL_OPENED:
662                     device = hid_device_get_instance_for_con_handle(l2cap_event_channel_opened_get_handle(packet));
663                     if (!device) {
664                         log_error("L2CAP_EVENT_CHANNEL_OPENED, no hid device for local cid 0x%02x", l2cap_event_channel_opened_get_local_cid(packet));
665                         return;
666                     }
667                     status = l2cap_event_channel_opened_get_status(packet);
668                     if (status) {
669                         if (device->incoming == 0){
670                             // report error for outgoing connection
671                             hid_device_emit_connected_event(device, status);
672                         }
673                         return;
674                     }
675                     psm = l2cap_event_channel_opened_get_psm(packet);
676                     connected_before = device->connected;
677                     switch (psm){
678                         case PSM_HID_CONTROL:
679                             device->control_cid = l2cap_event_channel_opened_get_local_cid(packet);
680                             // printf("HID Control opened, cid 0x%02x\n", device->control_cid);
681                             break;
682                         case PSM_HID_INTERRUPT:
683                             device->interrupt_cid = l2cap_event_channel_opened_get_local_cid(packet);
684                             // printf("HID Interrupt opened, cid 0x%02x\n", device->interrupt_cid);
685                             break;
686                         default:
687                             break;
688                     }
689 
690                     // connect HID Interrupt for outgoing
691                     if (device->incoming == 0 && psm == PSM_HID_CONTROL){
692                         // printf("Create outgoing HID Interrupt\n");
693                         status = l2cap_create_channel(packet_handler, device->bd_addr, PSM_HID_INTERRUPT, 48, &device->interrupt_cid);
694                         break;
695                     }
696                     if (!connected_before && device->control_cid && device->interrupt_cid){
697                         device->connected = 1;
698                         // printf("HID Connected\n");
699                         hid_device_emit_connected_event(device, 0);
700                     }
701                     break;
702                 case L2CAP_EVENT_CHANNEL_CLOSED:
703                     device = hid_device_get_instance_for_cid(l2cap_event_channel_closed_get_local_cid(packet));
704                     if (!device) return;
705 
706                     // connected_before = device->connected;
707                     device->incoming  = 0;
708                     if (l2cap_event_channel_closed_get_local_cid(packet) == device->interrupt_cid){
709                         // printf("HID Interrupt closed\n");
710                         device->interrupt_cid = 0;
711                     }
712                     if (l2cap_event_channel_closed_get_local_cid(packet) == device->control_cid){
713                         // printf("HID Control closed\n");
714                         device->control_cid = 0;
715                     }
716                     if (!device->interrupt_cid && !device->control_cid){
717                         device->connected = 0;
718                         device->con_handle = 0;
719                         device->cid = 0;
720                         // printf("HID Disconnected\n");
721                         hid_device_emit_connection_closed_event(device);
722                     }
723                     break;
724 
725                 case L2CAP_EVENT_CAN_SEND_NOW:
726                     local_cid = l2cap_event_can_send_now_get_local_cid(packet);
727                     device = hid_device_get_instance_for_cid(local_cid);
728 
729                     if (!device) return;
730                     switch (device->state){
731                         case HID_DEVICE_W2_GET_REPORT:{
732                             printf("HID_DEVICE_W2_GET_REPORT. on entry device->report_status %d \n", device->report_status);
733                             if (device->report_status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL) {
734                                 report[0] = (HID_MESSAGE_TYPE_HANDSHAKE << 4) | device->report_status;
735                                 hid_device_send_control_message(device->cid, &report[0], 1);
736                                 break;
737                             }
738 
739                             pos = 0;
740                             report[pos++] = (HID_MESSAGE_TYPE_DATA << 4) | device->report_type;
741                             if (device->report_id){
742                                 report[pos++] = device->report_id;
743                             }
744                             printf(" report size with header and id %d\n", pos);
745 
746                             report_size = 0;
747                             status = (*hci_device_get_report)(device->cid, device->report_type, device->report_id, &report_size, &report[pos]);
748                             printf(" report size %d, status after callback %d, expected report_size %d\n", report_size + pos, status, device->report_size + pos);
749 
750                             switch (status){
751                                 case 0:
752                                     device->report_status = HID_HANDSHAKE_PARAM_TYPE_NOT_READY;
753                                     break;
754                                 case 1:
755                                     if (report_size == 0){
756                                         device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_UNSUPPORTED_REQUEST;
757                                         break;
758                                     }
759                                     if (device->expected_report_size != report_size){
760                                         log_error("Expected report size of %d bytes, received %d", device->expected_report_size, report_size);
761                                         device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_UNSUPPORTED_REQUEST;
762                                         break;
763                                     }
764                                     break;
765                                 default:
766                                     device->report_status = HID_HANDSHAKE_PARAM_TYPE_ERR_UNSUPPORTED_REQUEST;
767                                     break;
768                             }
769                             if (device->report_status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL){
770                                 report[0] = (HID_MESSAGE_TYPE_HANDSHAKE << 4) | device->report_status;
771                                 hid_device_send_control_message(device->cid, &report[0], 1);
772                                 break;
773                             }
774 
775                             // if (report_size > l2cap_max_mtu()){
776                             //     report[0] = (HID_MESSAGE_TYPE_HANDSHAKE << 4) | HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
777                             //     hid_device_send_control_message(device->cid, &report[0], 1);
778                             //     break;
779                             // }
780 
781                             // printf("report type %d, report_size %d, report_size %d \n", device->report_type, report_size, device->report_size);
782                             hid_device_send_control_message(device->cid, &report[0], device->report_size);
783                             //     device->state = HID_DEVICE_IDLE;
784                             break;
785                         }
786                         case HID_DEVICE_W2_SET_REPORT:
787                         case HID_DEVICE_W2_SET_PROTOCOL:
788                             report[0] = (HID_MESSAGE_TYPE_HANDSHAKE << 4) | device->report_status;
789                             hid_device_send_control_message(device->cid, &report[0], 1);
790                             break;
791                         case HID_DEVICE_W2_GET_PROTOCOL:
792                             if (device->report_status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL){
793                                 // printf("send HID_MESSAGE_TYPE_HANDSHAKE, report_status %d \n", device->report_status);
794                                 report[0] = (HID_MESSAGE_TYPE_HANDSHAKE << 4) | device->report_status;
795                                 hid_device_send_control_message(device->cid, &report[0], 1);
796                                 break;
797                             }
798 
799                             // printf("send HID_MESSAGE_TYPE_DATA, protocol_mode %d \n", device->protocol_mode);
800                             report[0] = (HID_MESSAGE_TYPE_DATA << 4);
801                             report[1] =  device->protocol_mode;
802                             hid_device_send_control_message(device->cid, &report[0], 2);
803                             break;
804 
805 
806                         case HID_DEVICE_W2_SEND_UNSUPPORTED_REQUEST:
807                             report[0] = (HID_MESSAGE_TYPE_HANDSHAKE << 4) | HID_HANDSHAKE_PARAM_TYPE_ERR_UNSUPPORTED_REQUEST;
808                             hid_device_send_control_message(device->cid, &report[0], 1);
809                             break;
810                         default:
811                             log_info("HID Can send now, emit event");
812                             hid_device_emit_can_send_now_event(device);
813                             // device->state = HID_DEVICE_IDLE;
814                             break;
815                     }
816                     device->state = HID_DEVICE_IDLE;
817                     break;
818                 default:
819                     break;
820             }
821             break;
822         default:
823             break;
824     }
825 }
826 
827 /**
828  * @brief Set up HID Device
829  */
830 void hid_device_init(uint8_t boot_protocol_mode_supported, uint16_t descriptor_len, const uint8_t * descriptor){
831     hid_boot_protocol_mode_supported = boot_protocol_mode_supported;
832     hid_descriptor =  descriptor;
833     hid_descriptor_len = descriptor_len;
834     hci_device_get_report = dummy_write_report;
835     hci_device_set_report = dummy_set_report;
836     hci_device_report_data = dummy_report_data;
837 
838     l2cap_register_service(packet_handler, PSM_HID_INTERRUPT, 100, LEVEL_2);
839     l2cap_register_service(packet_handler, PSM_HID_CONTROL,   100, LEVEL_2);
840 }
841 
842 /**
843  * @brief Register callback for the HID Device client.
844  * @param callback
845  */
846 void hid_device_register_packet_handler(btstack_packet_handler_t callback){
847     hid_callback = callback;
848 }
849 
850 
851 
852 void hid_device_register_report_request_callback(int (*callback)(uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id, int * out_report_size, uint8_t * out_report)){
853     if (callback == NULL){
854         callback = dummy_write_report;
855     }
856     hci_device_get_report = callback;
857 }
858 
859 void hid_device_register_set_report_callback(void (*callback)(uint16_t hid_cid, hid_report_type_t report_type, int report_size, uint8_t * report)){
860     if (callback == NULL){
861         callback = dummy_set_report;
862     }
863     hci_device_set_report = callback;
864 }
865 
866 void hid_device_register_report_data_callback(void (*callback)(uint16_t cid, hid_report_type_t report_type, uint16_t report_id, int report_size, uint8_t * report)){
867     if (callback == NULL){
868         callback = dummy_report_data;
869     }
870     hci_device_report_data = callback;
871 }
872 
873 
874 /**
875  * @brief Request can send now event to send HID Report
876  * @param hid_cid
877  */
878 void hid_device_request_can_send_now_event(uint16_t hid_cid){
879     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
880     if (!hid_device || !hid_device->control_cid){
881          hid_device->state = HID_DEVICE_IDLE;
882          return;
883     }
884     l2cap_request_can_send_now_event(hid_device->control_cid);
885 }
886 
887 /**
888  * @brief Send HID messageon interrupt channel
889  * @param hid_cid
890  */
891 void hid_device_send_interrupt_message(uint16_t hid_cid, const uint8_t * message, uint16_t message_len){
892     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
893     if (!hid_device || !hid_device->interrupt_cid) return;
894     l2cap_send(hid_device->interrupt_cid, (uint8_t*) message, message_len);
895 }
896 
897 /**
898  * @brief Send HID messageon control channel
899  * @param hid_cid
900  */
901 void hid_device_send_control_message(uint16_t hid_cid, const uint8_t * message, uint16_t message_len){
902     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
903     if (!hid_device || !hid_device->control_cid) return;
904     l2cap_send(hid_device->control_cid, (uint8_t*) message, message_len);
905 }
906 
907 /*
908  * @brief Create HID connection to HID Host
909  * @param addr
910  * @param hid_cid to use for other commands
911  * @result status
912  */
913 uint8_t hid_device_connect(bd_addr_t addr, uint16_t * hid_cid){
914     hid_device_t * hid_device = hid_device_create_instance();
915     if (!hid_device){
916         log_error("hid_device_connect: could not create a hid device instace");
917         return BTSTACK_MEMORY_ALLOC_FAILED;
918     }
919     // assign hic_cid
920     *hid_cid = hid_device_get_next_cid();
921     // store address
922     memcpy(hid_device->bd_addr, addr, 6);
923 
924     // reset state
925     hid_device->cid           = *hid_cid;
926     hid_device->incoming      = 0;
927     hid_device->connected     = 0;
928     hid_device->control_cid   = 0;
929     hid_device->interrupt_cid = 0;
930     // create l2cap control using fixed HID L2CAP PSM
931     log_info("Create outgoing HID Control");
932     uint8_t status = l2cap_create_channel(packet_handler, hid_device->bd_addr, PSM_HID_CONTROL, 48, &hid_device->control_cid);
933     return status;
934 }
935 
936 /*
937  * @brief Disconnect from HID Host
938  * @param hid_cid
939  * @result status
940  */
941 void hid_device_disconnect_interrupt_channel(uint16_t hid_cid){
942     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
943     if (!hid_device){
944         log_error("hid_device_disconnect_interrupt_channel: could not find hid device instace");
945         return;
946     }
947     log_info("Disconnect from interrupt channel HID Host");
948     if (hid_device->interrupt_cid){
949         l2cap_disconnect(hid_device->interrupt_cid, 0);  // reason isn't used
950     }
951 }
952 
953 void hid_device_disconnect_control_channel(uint16_t hid_cid){
954     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
955     if (!hid_device){
956         log_error("hid_device_disconnect_control_channel: could not find hid device instace");
957         return;
958     }
959     log_info("Disconnect from control channel HID Host");
960     if (hid_device->control_cid){
961         l2cap_disconnect(hid_device->control_cid, 0);  // reason isn't used
962     }
963 }
964 
965 void hid_device_disconnect(uint16_t hid_cid){
966     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
967     if (!hid_device){
968         log_error("hid_device_disconnect: could not find hid device instace");
969         return;
970     }
971     log_info("Disconnect from HID Host");
972     if (hid_device->interrupt_cid){
973         l2cap_disconnect(hid_device->interrupt_cid, 0);  // reason isn't used
974     }
975     if (hid_device->control_cid){
976         l2cap_disconnect(hid_device->control_cid, 0); // reason isn't used
977     }
978 }
979 
980 int hid_device_in_boot_protocol_mode(uint16_t hid_cid){
981     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
982     if (!hid_device){
983         log_error("hid_device_in_boot_protocol_mode: could not find hid device instace");
984         return 0;
985     }
986     return hid_device->protocol_mode == HID_PROTOCOL_MODE_BOOT;
987 }
988