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