xref: /btstack/src/classic/hid_device.c (revision 6420389d1a158883e8ea2b4bc8a58cdca363bf96)
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 
50 typedef enum {
51     HID_DEVICE_IDLE,
52     HID_DEVICE_CONNECTED,
53     HID_DEVICE_W2_SEND_REPORT,
54     HID_DEVICE_W2_SEND_UNSUPPORTED_REQUEST
55 } hid_device_state_t;
56 
57 // hid device state
58 typedef struct hid_device {
59     uint16_t  cid;
60     bd_addr_t bd_addr;
61     hci_con_handle_t con_handle;
62     uint16_t  control_cid;
63     uint16_t  interrupt_cid;
64     uint8_t   incoming;
65     uint8_t   connected;
66     hid_device_state_t state;
67     hid_report_type_t report_type;
68     uint16_t   report_id;
69     uint16_t   max_num_bytes_to_transfer;
70     uint8_t    report_id_is_valid;
71 } hid_device_t;
72 
73 static hid_device_t _hid_device;
74 
75 static hid_handshake_param_type_t dummy_write_report(uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id, uint8_t report_max_size, int * out_report_size, uint8_t * out_report){
76     UNUSED(hid_cid);
77     UNUSED(report_type);
78     UNUSED(report_id);
79     UNUSED(report_max_size);
80     UNUSED(out_report_size);
81     UNUSED(out_report);
82     return HID_HANDSHAKE_PARAM_TYPE_ERR_UNKNOWN;
83 }
84 
85 static hid_handshake_param_type_t (*hci_device_write_report) (uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id, uint8_t report_max_size, int * out_report_size, uint8_t * out_report) = dummy_write_report;
86 
87 static btstack_packet_handler_t hid_callback;
88 
89 static uint16_t hid_device_cid = 0;
90 
91 static uint16_t hid_device_get_next_cid(void){
92     hid_device_cid++;
93     if (!hid_device_cid){
94         hid_device_cid = 1;
95     }
96     return hid_device_cid;
97 }
98 
99 // TODO: store hid device connection into list
100 static hid_device_t * hid_device_get_instance_for_cid(uint16_t cid){
101     // printf("control_cid 0x%02x, interrupt_cid 0x%02x, query_cid 0x%02x \n", _hid_device.control_cid,  _hid_device.interrupt_cid, cid);
102     if (_hid_device.cid == cid || _hid_device.control_cid == cid || _hid_device.interrupt_cid == cid){
103         return &_hid_device;
104     }
105     return NULL;
106 }
107 
108 static hid_device_t * hid_device_create_instance_for_bt_addr(bd_addr_t bd_addr){
109     memcpy(_hid_device.bd_addr, bd_addr, 6);
110     if (!_hid_device.cid){
111         _hid_device.cid = hid_device_get_next_cid();
112     }
113     return &_hid_device;
114 }
115 
116 static hid_device_t * hid_device_get_instance_for_con_handle(uint16_t con_handle){
117     UNUSED(con_handle);
118     return &_hid_device;
119 }
120 
121 static hid_device_t * hid_device_create_instance(void){
122     return &_hid_device;
123 }
124 
125 void hid_create_sdp_record(
126     uint8_t *service,
127     uint32_t service_record_handle,
128     uint16_t hid_device_subclass,
129     uint8_t  hid_country_code,
130     uint8_t  hid_virtual_cable,
131     uint8_t  hid_reconnect_initiate,
132     uint8_t  hid_boot_device,
133     const uint8_t * hid_descriptor, uint16_t hid_descriptor_size,
134     const char *device_name){
135 
136     uint8_t * attribute;
137     de_create_sequence(service);
138 
139     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
140     de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
141 
142     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
143     attribute = de_push_sequence(service);
144     {
145         de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
146     }
147     de_pop_sequence(service, attribute);
148 
149     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
150     attribute = de_push_sequence(service);
151     {
152         uint8_t * l2cpProtocol = de_push_sequence(attribute);
153         {
154             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
155             de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, PSM_HID_CONTROL);
156         }
157         de_pop_sequence(attribute, l2cpProtocol);
158 
159         uint8_t * hidProtocol = de_push_sequence(attribute);
160         {
161             de_add_number(hidProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_HIDP);
162         }
163         de_pop_sequence(attribute, hidProtocol);
164     }
165     de_pop_sequence(service, attribute);
166 
167     // TODO?
168     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
169     attribute = de_push_sequence(service);
170     {
171         de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x656e);
172         de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x006a);
173         de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x0100);
174     }
175     de_pop_sequence(service, attribute);
176 
177     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS);
178     attribute = de_push_sequence(service);
179     {
180         uint8_t * additionalDescriptorAttribute = de_push_sequence(attribute);
181         {
182             uint8_t * l2cpProtocol = de_push_sequence(additionalDescriptorAttribute);
183             {
184                 de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
185                 de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, PSM_HID_INTERRUPT);
186             }
187             de_pop_sequence(additionalDescriptorAttribute, l2cpProtocol);
188 
189             uint8_t * hidProtocol = de_push_sequence(attribute);
190             {
191                 de_add_number(hidProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_HIDP);
192             }
193             de_pop_sequence(attribute, hidProtocol);
194         }
195         de_pop_sequence(attribute, additionalDescriptorAttribute);
196     }
197     de_pop_sequence(service, attribute);
198 
199     // 0x0100 "ServiceName"
200     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
201     de_add_data(service,  DE_STRING, strlen(device_name), (uint8_t *) device_name);
202 
203     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
204     attribute = de_push_sequence(service);
205     {
206         uint8_t * hidProfile = de_push_sequence(attribute);
207         {
208             de_add_number(hidProfile,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE);
209             de_add_number(hidProfile,  DE_UINT, DE_SIZE_16, 0x0101);    // Version 1.1
210         }
211         de_pop_sequence(attribute, hidProfile);
212     }
213     de_pop_sequence(service, attribute);
214 
215     // Deprecated in v1.1.1
216     // de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DEVICE_RELEASE_NUMBER);
217     // de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0101);
218 
219     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_PARSER_VERSION);
220     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0111);  // v1.1.1
221 
222     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DEVICE_SUBCLASS);
223     de_add_number(service,  DE_UINT, DE_SIZE_8,  hid_device_subclass);
224 
225     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_COUNTRY_CODE);
226     de_add_number(service,  DE_UINT, DE_SIZE_8,  hid_country_code);
227 
228     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_VIRTUAL_CABLE);
229     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_virtual_cable);
230 
231     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_RECONNECT_INITIATE);
232     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_reconnect_initiate);
233 
234     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST);
235     attribute = de_push_sequence(service);
236     {
237         uint8_t* hidDescriptor = de_push_sequence(attribute);
238         {
239             de_add_number(hidDescriptor,  DE_UINT, DE_SIZE_8, 0x22);    // Report Descriptor
240             de_add_data(hidDescriptor,  DE_STRING, hid_descriptor_size, (uint8_t *) hid_descriptor);
241         }
242         de_pop_sequence(attribute, hidDescriptor);
243     }
244     de_pop_sequence(service, attribute);
245 
246     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HIDLANGID_BASE_LIST);
247     attribute = de_push_sequence(service);
248     {
249         uint8_t* hig_lang_base = de_push_sequence(attribute);
250         {
251             // see: http://www.usb.org/developers/docs/USB_LANGIDs.pdf
252             de_add_number(hig_lang_base,  DE_UINT, DE_SIZE_16, 0x0409);    // HIDLANGID = English (US)
253             de_add_number(hig_lang_base,  DE_UINT, DE_SIZE_16, 0x0100);    // HIDLanguageBase = 0x0100 default
254         }
255         de_pop_sequence(attribute, hig_lang_base);
256     }
257     de_pop_sequence(service, attribute);
258 
259     uint8_t hid_remote_wake = 1;
260     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_REMOTE_WAKE);
261     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_remote_wake);
262 
263     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_BOOT_DEVICE);
264     de_add_number(service,  DE_BOOL, DE_SIZE_8,  hid_boot_device);
265 }
266 
267 static inline void hid_device_emit_connected_event(hid_device_t * context, uint8_t status){
268     uint8_t event[15];
269     int pos = 0;
270     event[pos++] = HCI_EVENT_HID_META;
271     pos++;  // skip len
272     event[pos++] = HID_SUBEVENT_CONNECTION_OPENED;
273     little_endian_store_16(event,pos,context->cid);
274     pos+=2;
275     event[pos++] = status;
276     reverse_bd_addr(context->bd_addr, &event[pos]);
277     pos += 6;
278     little_endian_store_16(event,pos,context->con_handle);
279     pos += 2;
280     event[pos++] = context->incoming;
281     event[1] = pos - 2;
282     if (pos != sizeof(event)) log_error("hid_device_emit_connected_event size %u", pos);
283     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
284 }
285 
286 static inline void hid_device_emit_connection_closed_event(hid_device_t * context){
287     uint8_t event[5];
288     int pos = 0;
289     event[pos++] = HCI_EVENT_HID_META;
290     pos++;  // skip len
291     event[pos++] = HID_SUBEVENT_CONNECTION_CLOSED;
292     little_endian_store_16(event,pos,context->cid);
293     pos+=2;
294     event[1] = pos - 2;
295     if (pos != sizeof(event)) log_error("hid_device_emit_connection_closed_event size %u", pos);
296     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
297 }
298 
299 static inline void hid_device_emit_can_send_now_event(hid_device_t * context){
300     uint8_t event[5];
301     int pos = 0;
302     event[pos++] = HCI_EVENT_HID_META;
303     pos++;  // skip len
304     event[pos++] = HID_SUBEVENT_CAN_SEND_NOW;
305     little_endian_store_16(event,pos,context->cid);
306     pos+=2;
307     event[1] = pos - 2;
308     if (pos != sizeof(event)) log_error("hid_device_emit_can_send_now_event size %u", pos);
309     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
310 }
311 
312 static inline void hid_device_emit_event(hid_device_t * context, uint8_t subevent_type){
313     uint8_t event[4];
314     int pos = 0;
315     event[pos++] = HCI_EVENT_HID_META;
316     pos++;  // skip len
317     event[pos++] = subevent_type;
318     little_endian_store_16(event,pos,context->cid);
319     pos+=2;
320     event[1] = pos - 2;
321     if (pos != sizeof(event)) log_error("hid_device_emit_event size %u", pos);
322     hid_callback(HCI_EVENT_PACKET, context->cid, &event[0], pos);
323 }
324 
325 static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t packet_size){
326     UNUSED(channel);
327     UNUSED(packet_size);
328     int connected_before;
329     uint16_t psm;
330     uint8_t status;
331     hid_device_t * device = NULL;
332     uint8_t report[20];
333     int report_size;
334     uint8_t param;
335     bd_addr_t address;
336     hid_handshake_param_type_t report_status;
337 
338     switch (packet_type){
339         case L2CAP_DATA_PACKET:
340             device = hid_device_get_instance_for_cid(channel);
341             if (!device) {
342                 log_error("no device with cid 0x%02x", channel);
343                 return;
344             }
345             hid_message_type_t message_type = packet[0] >> 4;
346 
347             switch (message_type){
348                 case HID_MESSAGE_TYPE_GET_REPORT:
349                     device->report_type = packet[0] & 0x03;
350                     device->report_id = 0;
351                     if (packet_size > 1){
352                         device->report_id = packet[1];
353                     }
354                     if ((packet[0] & 0x08) && packet_size >= 4){
355                         device->max_num_bytes_to_transfer = little_endian_read_16(packet, 2);
356                     } else {
357                         device->max_num_bytes_to_transfer = l2cap_max_mtu();
358                     }
359 
360                     device->state = HID_DEVICE_W2_SEND_REPORT;
361                     l2cap_request_can_send_now_event(device->control_cid);
362                     break;
363                 case HID_MESSAGE_TYPE_HID_CONTROL:
364                     param = packet[0] & 0x0F;
365                     switch (param){
366                         case HID_CONTROL_PARAM_SUSPEND:
367                             hid_device_emit_event(device, HID_SUBEVENT_SUSPEND);
368                             break;
369                         case HID_CONTROL_PARAM_EXIT_SUSPEND:
370                             hid_device_emit_event(device, HID_SUBEVENT_EXIT_SUSPEND);
371                             break;
372                         default:
373                             device->state = HID_DEVICE_W2_SEND_UNSUPPORTED_REQUEST;
374                             l2cap_request_can_send_now_event(device->control_cid);
375                             break;
376                     }
377                     break;
378                 default:
379                     // printf("L2CAP_DATA_PACKET %d  \n", message_type);
380                     device->state = HID_DEVICE_W2_SEND_UNSUPPORTED_REQUEST;
381                     l2cap_request_can_send_now_event(device->control_cid);
382                     break;
383             }
384             break;
385         case HCI_EVENT_PACKET:
386             switch (packet[0]){
387                 case L2CAP_EVENT_INCOMING_CONNECTION:
388                     switch (l2cap_event_incoming_connection_get_psm(packet)){
389                         case PSM_HID_CONTROL:
390                         case PSM_HID_INTERRUPT:
391                             l2cap_event_incoming_connection_get_address(packet, address);
392                             device = hid_device_create_instance_for_bt_addr(address);
393                             if (!device) {
394                                 log_error("L2CAP_EVENT_INCOMING_CONNECTION, no hid device for con handle 0x%02x", l2cap_event_incoming_connection_get_handle(packet));
395                                 l2cap_decline_connection(channel);
396                                 break;
397                             }
398                             if (device->con_handle == 0 || l2cap_event_incoming_connection_get_handle(packet) == device->con_handle){
399                                 device->con_handle = l2cap_event_incoming_connection_get_handle(packet);
400                                 device->incoming = 1;
401                                 l2cap_event_incoming_connection_get_address(packet, device->bd_addr);
402                                 l2cap_accept_connection(channel);
403                             } else {
404                                 l2cap_decline_connection(channel);
405                                 log_error("L2CAP_EVENT_INCOMING_CONNECTION, decline connection for con handle 0x%02x", l2cap_event_incoming_connection_get_handle(packet));
406                             }
407                             break;
408                         default:
409                             l2cap_decline_connection(channel);
410                             break;
411                     }
412                     break;
413                 case L2CAP_EVENT_CHANNEL_OPENED:
414                     device = hid_device_get_instance_for_con_handle(l2cap_event_channel_opened_get_handle(packet));
415                     if (!device) {
416                         log_error("L2CAP_EVENT_CHANNEL_OPENED, no hid device for local cid 0x%02x", l2cap_event_channel_opened_get_local_cid(packet));
417                         return;
418                     }
419                     status = l2cap_event_channel_opened_get_status(packet);
420                     if (status) {
421                         if (device->incoming == 0){
422                             // report error for outgoing connection
423                             hid_device_emit_connected_event(device, status);
424                         }
425                         return;
426                     }
427                     psm = l2cap_event_channel_opened_get_psm(packet);
428                     connected_before = device->connected;
429                     switch (psm){
430                         case PSM_HID_CONTROL:
431                             device->control_cid = l2cap_event_channel_opened_get_local_cid(packet);
432                             log_info("HID Control opened, cid 0x%02x", device->control_cid);
433                             break;
434                         case PSM_HID_INTERRUPT:
435                             device->interrupt_cid = l2cap_event_channel_opened_get_local_cid(packet);
436                             log_info("HID Interrupt opened, cid 0x%02x", device->interrupt_cid);
437                             break;
438                         default:
439                             break;
440                     }
441 
442                     // connect HID Interrupt for outgoing
443                     if (device->incoming == 0 && psm == PSM_HID_CONTROL){
444                         log_info("Create outgoing HID Interrupt");
445                         status = l2cap_create_channel(packet_handler, device->bd_addr, PSM_HID_INTERRUPT, 48, &device->interrupt_cid);
446                         break;
447                     }
448                     if (!connected_before && device->control_cid && device->interrupt_cid){
449                         device->connected = 1;
450                         log_info("HID Connected");
451                         hid_device_emit_connected_event(device, 0);
452                     }
453                     break;
454                 case L2CAP_EVENT_CHANNEL_CLOSED:
455                     device = hid_device_get_instance_for_cid(l2cap_event_channel_closed_get_local_cid(packet));
456                     if (!device) return;
457 
458                     // connected_before = device->connected;
459                     device->incoming  = 0;
460                     if (l2cap_event_channel_closed_get_local_cid(packet) == device->interrupt_cid){
461                         log_info("HID Interrupt closed");
462                         device->interrupt_cid = 0;
463                     }
464                     if (l2cap_event_channel_closed_get_local_cid(packet) == device->control_cid){
465                         log_info("HID Control closed");
466                         device->control_cid = 0;
467                     }
468                     if (!device->interrupt_cid && !device->control_cid){
469                         device->connected = 0;
470                         device->con_handle = 0;
471                         device->cid = 0;
472                         log_info("HID Disconnected");
473                         hid_device_emit_connection_closed_event(device);
474                     }
475                     break;
476 
477                 case L2CAP_EVENT_CAN_SEND_NOW:
478                     device = hid_device_get_instance_for_cid(l2cap_event_can_send_now_get_local_cid(packet));
479                     if (!device) return;
480                     switch (device->state){
481                         case HID_DEVICE_W2_SEND_REPORT:
482                             report_status = (*hci_device_write_report)(device->cid, device->report_type, device->report_id, (uint16_t) sizeof(report) - 1, &report_size, &report[1]);
483                             report_size += 1;
484 
485                             if (report_status != HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL){
486                                 report[0] = (HID_MESSAGE_TYPE_HANDSHAKE << 4) | report_status;
487                                 hid_device_send_control_message(device->cid, &report[0], 1);
488                                 break;
489                             }
490 
491                             if (report_size > l2cap_max_mtu()){
492                                 report[0] = (HID_MESSAGE_TYPE_HANDSHAKE << 4) | HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
493                                 hid_device_send_control_message(device->cid, &report[0], 1);
494                                 break;
495                             }
496 
497                             report[0] = (HID_MESSAGE_TYPE_DATA << 4) | device->report_type;
498                             hid_device_send_control_message(device->cid, &report[0], btstack_min(report_size, device->max_num_bytes_to_transfer));
499                             //     device->state = HID_DEVICE_IDLE;
500                             break;
501                         case HID_DEVICE_W2_SEND_UNSUPPORTED_REQUEST:
502                             report[0] = (HID_MESSAGE_TYPE_HANDSHAKE << 4) | HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER;
503                             hid_device_send_control_message(device->cid, &report[0], 1);
504                             device->state = HID_DEVICE_IDLE;
505                             break;
506                         default:
507                             log_info("HID Can send now, emit event");
508                             hid_device_emit_can_send_now_event(device);
509                             device->state = HID_DEVICE_IDLE;
510                             break;
511                     }
512                     break;
513                 default:
514                     break;
515             }
516             break;
517         default:
518             break;
519     }
520 }
521 
522 /**
523  * @brief Set up HID Device
524  */
525 void hid_device_init(void){
526     l2cap_register_service(packet_handler, PSM_HID_INTERRUPT, 100, LEVEL_2);
527     l2cap_register_service(packet_handler, PSM_HID_CONTROL,   100, LEVEL_2);
528 }
529 
530 /**
531  * @brief Register callback for the HID Device client.
532  * @param callback
533  */
534 void hid_device_register_packet_handler(btstack_packet_handler_t callback){
535     hid_callback = callback;
536 }
537 
538 
539 
540 void hid_device_register_report_request_callback(hid_handshake_param_type_t (*callback) (uint16_t hid_cid, hid_report_type_t report_type, uint16_t report_id, uint8_t report_max_size, int * out_report_size, uint8_t * out_report)){
541     if (callback == NULL){
542         callback = dummy_write_report;
543     }
544     hci_device_write_report = callback;
545 }
546 
547 
548 /**
549  * @brief Request can send now event to send HID Report
550  * @param hid_cid
551  */
552 void hid_device_request_can_send_now_event(uint16_t hid_cid){
553     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
554     if (!hid_device || !hid_device->control_cid) return;
555     l2cap_request_can_send_now_event(hid_device->control_cid);
556 }
557 
558 /**
559  * @brief Send HID messageon interrupt channel
560  * @param hid_cid
561  */
562 void hid_device_send_interrupt_message(uint16_t hid_cid, const uint8_t * message, uint16_t message_len){
563     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
564     if (!hid_device || !hid_device->interrupt_cid) return;
565     l2cap_send(hid_device->interrupt_cid, (uint8_t*) message, message_len);
566 }
567 
568 /**
569  * @brief Send HID messageon control channel
570  * @param hid_cid
571  */
572 void hid_device_send_control_message(uint16_t hid_cid, const uint8_t * message, uint16_t message_len){
573     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
574     if (!hid_device || !hid_device->control_cid) return;
575     l2cap_send(hid_device->control_cid, (uint8_t*) message, message_len);
576 }
577 
578 /*
579  * @brief Create HID connection to HID Host
580  * @param addr
581  * @param hid_cid to use for other commands
582  * @result status
583  */
584 uint8_t hid_device_connect(bd_addr_t addr, uint16_t * hid_cid){
585     hid_device_t * hid_device = hid_device_create_instance();
586     if (!hid_device){
587         log_error("hid_device_connect: could not create a hid device instace");
588         return BTSTACK_MEMORY_ALLOC_FAILED;
589     }
590     // assign hic_cid
591     *hid_cid = hid_device_get_next_cid();
592     // store address
593     memcpy(hid_device->bd_addr, addr, 6);
594 
595     // reset state
596     hid_device->cid           = *hid_cid;
597     hid_device->incoming      = 0;
598     hid_device->connected     = 0;
599     hid_device->control_cid   = 0;
600     hid_device->interrupt_cid = 0;
601     // create l2cap control using fixed HID L2CAP PSM
602     log_info("Create outgoing HID Control");
603     uint8_t status = l2cap_create_channel(packet_handler, hid_device->bd_addr, PSM_HID_CONTROL, 48, &hid_device->control_cid);
604     return status;
605 }
606 
607 /*
608  * @brief Disconnect from HID Host
609  * @param hid_cid
610  * @result status
611  */
612 void hid_device_disconnect_interrupt_channel(uint16_t hid_cid){
613     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
614     if (!hid_device){
615         log_error("hid_device_disconnect_interrupt_channel: could not find hid device instace");
616         return;
617     }
618     log_info("Disconnect from interrupt channel HID Host");
619     if (hid_device->interrupt_cid){
620         l2cap_disconnect(hid_device->interrupt_cid, 0);  // reason isn't used
621     }
622 }
623 
624 void hid_device_disconnect_control_channel(uint16_t hid_cid){
625     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
626     if (!hid_device){
627         log_error("hid_device_disconnect_control_channel: could not find hid device instace");
628         return;
629     }
630     log_info("Disconnect from control channel HID Host");
631     if (hid_device->control_cid){
632         l2cap_disconnect(hid_device->control_cid, 0);  // reason isn't used
633     }
634 }
635 
636 void hid_device_disconnect(uint16_t hid_cid){
637     hid_device_t * hid_device = hid_device_get_instance_for_cid(hid_cid);
638     if (!hid_device){
639         log_error("hid_device_disconnect: could not find hid device instace");
640         return;
641     }
642     log_info("Disconnect from HID Host");
643     if (hid_device->interrupt_cid){
644         l2cap_disconnect(hid_device->interrupt_cid, 0);  // reason isn't used
645     }
646     if (hid_device->control_cid){
647         l2cap_disconnect(hid_device->control_cid, 0); // reason isn't used
648     }
649 }
650