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