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_host.c" 39 40 #include <string.h> 41 42 #include "bluetooth.h" 43 #include "bluetooth_psm.h" 44 #include "bluetooth_sdp.h" 45 #include "btstack_debug.h" 46 #include "btstack_event.h" 47 #include "btstack_hid_parser.h" 48 #include "btstack_memory.h" 49 #include "l2cap.h" 50 51 #include "classic/hid.h" 52 #include "classic/hid_host.h" 53 #include "classic/sdp_util.h" 54 #include "classic/sdp_client.h" 55 56 #define MAX_ATTRIBUTE_VALUE_SIZE 300 57 58 #define CONTROL_MESSAGE_BITMASK_SUSPEND 1 59 #define CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND 2 60 #define CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG 4 61 62 63 static uint8_t * hid_host_descriptor_storage; 64 static uint16_t hid_host_descriptor_storage_len; 65 66 // SDP 67 static uint8_t attribute_value[MAX_ATTRIBUTE_VALUE_SIZE]; 68 static const unsigned int attribute_value_buffer_size = MAX_ATTRIBUTE_VALUE_SIZE; 69 static uint16_t sdp_query_context_hid_host_control_cid = 0; 70 71 static btstack_linked_list_t connections; 72 static uint16_t hid_host_cid_counter = 0; 73 74 static btstack_packet_handler_t hid_callback; 75 static btstack_context_callback_registration_t hid_host_handle_sdp_client_query_request; 76 static void hid_host_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 77 static void hid_host_handle_start_sdp_client_query(void * context); 78 79 static uint16_t hid_descriptor_storage_get_available_space(void){ 80 // assumes all descriptors are back to back 81 uint16_t free_space = hid_host_descriptor_storage_len; 82 83 btstack_linked_list_iterator_t it; 84 btstack_linked_list_iterator_init(&it, &connections); 85 while (btstack_linked_list_iterator_has_next(&it)){ 86 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it); 87 free_space -= connection->hid_descriptor_len; 88 } 89 return free_space; 90 } 91 92 static hid_host_connection_t * hid_host_get_connection_for_hid_cid(uint16_t hid_cid){ 93 btstack_linked_list_iterator_t it; 94 btstack_linked_list_iterator_init(&it, &connections); 95 while (btstack_linked_list_iterator_has_next(&it)){ 96 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it); 97 if (connection->hid_cid != hid_cid) continue; 98 return connection; 99 } 100 return NULL; 101 } 102 103 static hid_host_connection_t * hid_host_get_connection_for_l2cap_cid(uint16_t l2cap_cid){ 104 btstack_linked_list_iterator_t it; 105 btstack_linked_list_iterator_init(&it, &connections); 106 while (btstack_linked_list_iterator_has_next(&it)){ 107 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it); 108 if ((connection->interrupt_cid != l2cap_cid) && (connection->control_cid != l2cap_cid)) continue; 109 return connection; 110 } 111 return NULL; 112 } 113 114 static void hid_descriptor_storage_init(hid_host_connection_t * connection){ 115 connection->hid_descriptor_len = 0; 116 connection->hid_descriptor_max_len = hid_descriptor_storage_get_available_space(); 117 connection->hid_descriptor_offset = hid_host_descriptor_storage_len - connection->hid_descriptor_max_len; 118 } 119 120 static bool hid_descriptor_storage_store(hid_host_connection_t * connection, uint8_t byte){ 121 if (connection->hid_descriptor_len >= connection->hid_descriptor_max_len) return false; 122 123 hid_host_descriptor_storage[connection->hid_descriptor_offset + connection->hid_descriptor_len] = byte; 124 connection->hid_descriptor_len++; 125 return true; 126 } 127 128 static void hid_descriptor_storage_delete(hid_host_connection_t * connection){ 129 uint16_t next_offset = connection->hid_descriptor_offset + connection->hid_descriptor_len; 130 131 memmove(&hid_host_descriptor_storage[connection->hid_descriptor_offset], 132 &hid_host_descriptor_storage[next_offset], 133 hid_host_descriptor_storage_len - next_offset); 134 135 connection->hid_descriptor_len = 0; 136 connection->hid_descriptor_offset = 0; 137 138 btstack_linked_list_iterator_t it; 139 btstack_linked_list_iterator_init(&it, &connections); 140 while (btstack_linked_list_iterator_has_next(&it)){ 141 hid_host_connection_t * conn = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it); 142 if (conn->hid_descriptor_offset >= next_offset){ 143 conn->hid_descriptor_offset = next_offset; 144 next_offset += conn->hid_descriptor_len; 145 } 146 } 147 } 148 149 const uint8_t * hid_descriptor_storage_get_descriptor_data(uint16_t hid_cid){ 150 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 151 if (!connection){ 152 return NULL; 153 } 154 return &hid_host_descriptor_storage[connection->hid_descriptor_offset]; 155 } 156 157 uint16_t hid_descriptor_storage_get_descriptor_len(uint16_t hid_cid){ 158 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 159 if (!connection){ 160 return 0; 161 } 162 return connection->hid_descriptor_len; 163 } 164 165 166 // HID Util 167 static void hid_emit_connected_event(hid_host_connection_t * connection, uint8_t status){ 168 uint8_t event[15]; 169 uint16_t pos = 0; 170 event[pos++] = HCI_EVENT_HID_META; 171 pos++; // skip len 172 event[pos++] = HID_SUBEVENT_CONNECTION_OPENED; 173 little_endian_store_16(event, pos, connection->hid_cid); 174 pos+=2; 175 event[pos++] = status; 176 reverse_bd_addr(connection->remote_addr, &event[pos]); 177 pos += 6; 178 little_endian_store_16(event,pos,connection->con_handle); 179 pos += 2; 180 event[pos++] = connection->incoming; 181 event[1] = pos - 2; 182 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos); 183 } 184 185 static void hid_emit_descriptor_available_event(hid_host_connection_t * connection){ 186 uint8_t event[6]; 187 uint16_t pos = 0; 188 event[pos++] = HCI_EVENT_HID_META; 189 pos++; // skip len 190 event[pos++] = HID_SUBEVENT_DESCRIPTOR_AVAILABLE; 191 little_endian_store_16(event,pos,connection->hid_cid); 192 pos += 2; 193 event[pos++] = connection->hid_descriptor_status; 194 event[1] = pos - 2; 195 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos); 196 } 197 198 static void hid_emit_event(hid_host_connection_t * connection, uint8_t subevent_type){ 199 uint8_t event[5]; 200 uint16_t pos = 0; 201 event[pos++] = HCI_EVENT_HID_META; 202 pos++; // skip len 203 event[pos++] = subevent_type; 204 little_endian_store_16(event,pos,connection->hid_cid); 205 pos += 2; 206 event[1] = pos - 2; 207 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos); 208 } 209 210 static void hid_emit_event_with_status(hid_host_connection_t * connection, uint8_t subevent_type, hid_handshake_param_type_t status){ 211 uint8_t event[6]; 212 uint16_t pos = 0; 213 event[pos++] = HCI_EVENT_HID_META; 214 pos++; // skip len 215 event[pos++] = subevent_type; 216 little_endian_store_16(event,pos,connection->hid_cid); 217 pos += 2; 218 event[pos++] = status; 219 event[1] = pos - 2; 220 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos); 221 } 222 223 static void hid_emit_set_protocol_response_event(hid_host_connection_t * connection, hid_handshake_param_type_t status){ 224 uint8_t event[7]; 225 uint16_t pos = 0; 226 event[pos++] = HCI_EVENT_HID_META; 227 pos++; // skip len 228 event[pos++] = HID_SUBEVENT_SET_PROTOCOL_RESPONSE; 229 little_endian_store_16(event,pos,connection->hid_cid); 230 pos += 2; 231 event[pos++] = status; 232 event[pos++] = connection->protocol_mode; 233 event[1] = pos - 2; 234 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos); 235 } 236 237 static void hid_emit_incoming_connection_event(hid_host_connection_t * connection){ 238 uint8_t event[13]; 239 uint16_t pos = 0; 240 event[pos++] = HCI_EVENT_HID_META; 241 pos++; // skip len 242 event[pos++] = HID_SUBEVENT_INCOMING_CONNECTION; 243 little_endian_store_16(event, pos, connection->hid_cid); 244 pos += 2; 245 reverse_bd_addr(connection->remote_addr, &event[pos]); 246 pos += 6; 247 little_endian_store_16(event,pos,connection->con_handle); 248 pos += 2; 249 event[1] = pos - 2; 250 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos); 251 } 252 253 // setup get report response event - potentially in-place of original l2cap packet 254 static void hid_setup_get_report_event(hid_host_connection_t * connection, hid_handshake_param_type_t status, uint8_t *buffer, uint16_t report_len){ 255 uint16_t pos = 0; 256 buffer[pos++] = HCI_EVENT_HID_META; 257 pos++; // skip len 258 buffer[pos++] = HID_SUBEVENT_GET_REPORT_RESPONSE; 259 little_endian_store_16(buffer, pos, connection->hid_cid); 260 pos += 2; 261 buffer[pos++] = (uint8_t) status; 262 little_endian_store_16(buffer, pos, report_len); 263 pos += 2; 264 buffer[1] = pos + report_len - 2; 265 } 266 267 // setup report event - potentially in-place of original l2cap packet 268 static void hid_setup_report_event(hid_host_connection_t * connection, uint8_t *buffer, uint16_t report_len){ 269 uint16_t pos = 0; 270 buffer[pos++] = HCI_EVENT_HID_META; 271 pos++; // skip len 272 buffer[pos++] = HID_SUBEVENT_REPORT; 273 little_endian_store_16(buffer, pos, connection->hid_cid); 274 pos += 2; 275 little_endian_store_16(buffer, pos, report_len); 276 pos += 2; 277 buffer[1] = pos + report_len - 2; 278 } 279 280 281 static void hid_emit_get_protocol_event(hid_host_connection_t * connection, hid_handshake_param_type_t status, hid_protocol_mode_t protocol_mode){ 282 uint8_t event[7]; 283 uint16_t pos = 0; 284 event[pos++] = HCI_EVENT_HID_META; 285 pos++; // skip len 286 event[pos++] = HID_SUBEVENT_GET_PROTOCOL_RESPONSE; 287 little_endian_store_16(event,pos,connection->hid_cid); 288 pos += 2; 289 event[pos++] = status; 290 event[pos++] = protocol_mode; 291 event[1] = pos - 2; 292 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, &event[0], pos); 293 } 294 295 // HID Host 296 297 static uint16_t hid_host_get_next_cid(void){ 298 if (hid_host_cid_counter == 0xffff) { 299 hid_host_cid_counter = 1; 300 } else { 301 hid_host_cid_counter++; 302 } 303 return hid_host_cid_counter; 304 } 305 306 static hid_host_connection_t * hid_host_create_connection(bd_addr_t remote_addr){ 307 hid_host_connection_t * connection = btstack_memory_hid_host_connection_get(); 308 if (!connection){ 309 log_error("Not enough memory to create connection"); 310 return NULL; 311 } 312 connection->state = HID_HOST_IDLE; 313 connection->hid_cid = hid_host_get_next_cid(); 314 connection->control_cid = 0; 315 connection->control_psm = 0; 316 connection->interrupt_cid = 0; 317 connection->interrupt_psm = 0; 318 connection->con_handle = HCI_CON_HANDLE_INVALID; 319 320 (void)memcpy(connection->remote_addr, remote_addr, 6); 321 btstack_linked_list_add(&connections, (btstack_linked_item_t *) connection); 322 return connection; 323 } 324 325 static hid_host_connection_t * hid_host_get_connection_for_bd_addr(bd_addr_t addr){ 326 btstack_linked_list_iterator_t it; 327 btstack_linked_list_iterator_init(&it, &connections); 328 while (btstack_linked_list_iterator_has_next(&it)){ 329 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it); 330 if (memcmp(addr, connection->remote_addr, 6) != 0) continue; 331 return connection; 332 } 333 return NULL; 334 } 335 336 337 static void hid_host_finalize_connection(hid_host_connection_t * connection){ 338 uint16_t interrupt_cid = connection->interrupt_cid; 339 uint16_t control_cid = connection->control_cid; 340 341 connection->interrupt_cid = 0; 342 connection->control_cid = 0; 343 344 if (interrupt_cid != 0){ 345 l2cap_disconnect(interrupt_cid, 0); 346 } 347 if (control_cid != 0){ 348 l2cap_disconnect(control_cid, 0); 349 } 350 btstack_linked_list_remove(&connections, (btstack_linked_item_t*) connection); 351 btstack_memory_hid_host_connection_free(connection); 352 } 353 354 static void hid_host_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { 355 UNUSED(packet_type); 356 UNUSED(channel); 357 UNUSED(size); 358 359 des_iterator_t attribute_list_it; 360 des_iterator_t additional_des_it; 361 des_iterator_t prot_it; 362 uint8_t *des_element; 363 uint8_t *element; 364 uint32_t uuid; 365 uint8_t status = ERROR_CODE_SUCCESS; 366 bool try_fallback_to_boot; 367 bool finalize_connection; 368 369 370 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(sdp_query_context_hid_host_control_cid); 371 if (!connection) { 372 log_error("SDP query, connection with 0x%02x cid not found", sdp_query_context_hid_host_control_cid); 373 return; 374 } 375 376 btstack_assert(connection->state == HID_HOST_W4_SDP_QUERY_RESULT); 377 378 switch (hci_event_packet_get_type(packet)){ 379 case SDP_EVENT_QUERY_ATTRIBUTE_VALUE: 380 381 if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= attribute_value_buffer_size) { 382 383 attribute_value[sdp_event_query_attribute_byte_get_data_offset(packet)] = sdp_event_query_attribute_byte_get_data(packet); 384 385 if ((uint16_t)(sdp_event_query_attribute_byte_get_data_offset(packet)+1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) { 386 switch(sdp_event_query_attribute_byte_get_attribute_id(packet)) { 387 388 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST: 389 for (des_iterator_init(&attribute_list_it, attribute_value); des_iterator_has_more(&attribute_list_it); des_iterator_next(&attribute_list_it)) { 390 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue; 391 des_element = des_iterator_get_element(&attribute_list_it); 392 des_iterator_init(&prot_it, des_element); 393 element = des_iterator_get_element(&prot_it); 394 if (de_get_element_type(element) != DE_UUID) continue; 395 uuid = de_get_uuid32(element); 396 switch (uuid){ 397 case BLUETOOTH_PROTOCOL_L2CAP: 398 if (!des_iterator_has_more(&prot_it)) continue; 399 des_iterator_next(&prot_it); 400 de_element_get_uint16(des_iterator_get_element(&prot_it), &connection->control_psm); 401 log_info("HID Control PSM: 0x%04x", connection->control_psm); 402 break; 403 default: 404 break; 405 } 406 } 407 break; 408 case BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS: 409 for (des_iterator_init(&attribute_list_it, attribute_value); des_iterator_has_more(&attribute_list_it); des_iterator_next(&attribute_list_it)) { 410 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue; 411 des_element = des_iterator_get_element(&attribute_list_it); 412 for (des_iterator_init(&additional_des_it, des_element); des_iterator_has_more(&additional_des_it); des_iterator_next(&additional_des_it)) { 413 if (des_iterator_get_type(&additional_des_it) != DE_DES) continue; 414 des_element = des_iterator_get_element(&additional_des_it); 415 des_iterator_init(&prot_it, des_element); 416 element = des_iterator_get_element(&prot_it); 417 if (de_get_element_type(element) != DE_UUID) continue; 418 uuid = de_get_uuid32(element); 419 switch (uuid){ 420 case BLUETOOTH_PROTOCOL_L2CAP: 421 if (!des_iterator_has_more(&prot_it)) continue; 422 des_iterator_next(&prot_it); 423 de_element_get_uint16(des_iterator_get_element(&prot_it), &connection->interrupt_psm); 424 log_info("HID Interrupt PSM: 0x%04x", connection->interrupt_psm); 425 break; 426 default: 427 break; 428 } 429 } 430 } 431 break; 432 433 case BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST: 434 for (des_iterator_init(&attribute_list_it, attribute_value); des_iterator_has_more(&attribute_list_it); des_iterator_next(&attribute_list_it)) { 435 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue; 436 des_element = des_iterator_get_element(&attribute_list_it); 437 for (des_iterator_init(&additional_des_it, des_element); des_iterator_has_more(&additional_des_it); des_iterator_next(&additional_des_it)) { 438 if (des_iterator_get_type(&additional_des_it) != DE_STRING) continue; 439 element = des_iterator_get_element(&additional_des_it); 440 441 const uint8_t * descriptor = de_get_string(element); 442 uint16_t descriptor_len = de_get_data_size(element); 443 444 uint16_t i; 445 bool stored = false; 446 447 connection->hid_descriptor_status = ERROR_CODE_SUCCESS; 448 for (i = 0; i < descriptor_len; i++){ 449 stored = hid_descriptor_storage_store(connection, descriptor[i]); 450 if (!stored){ 451 connection->hid_descriptor_status = ERROR_CODE_MEMORY_CAPACITY_EXCEEDED; 452 break; 453 } 454 } 455 } 456 } 457 break; 458 default: 459 break; 460 } 461 } 462 } else { 463 log_error("SDP attribute value buffer size exceeded: available %d, required %d", attribute_value_buffer_size, sdp_event_query_attribute_byte_get_attribute_length(packet)); 464 } 465 break; 466 467 case SDP_EVENT_QUERY_COMPLETE: 468 status = sdp_event_query_complete_get_status(packet); 469 try_fallback_to_boot = false; 470 finalize_connection = false; 471 472 switch (status){ 473 // remote has SDP server 474 case ERROR_CODE_SUCCESS: 475 // but no HID record 476 if (!connection->control_psm || !connection->interrupt_psm) { 477 status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 478 if (connection->requested_protocol_mode == HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT){ 479 try_fallback_to_boot = true; 480 } else { 481 finalize_connection = true; 482 } 483 break; 484 } 485 // report mode possible 486 break; 487 488 // SDP connection failed or remote does not have SDP server 489 default: 490 if (connection->requested_protocol_mode == HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT){ 491 try_fallback_to_boot = true; 492 } else { 493 finalize_connection = true; 494 } 495 break; 496 } 497 498 if (finalize_connection){ 499 sdp_query_context_hid_host_control_cid = 0; 500 hid_emit_connected_event(connection, status); 501 hid_host_finalize_connection(connection); 502 break; 503 } 504 505 if (try_fallback_to_boot){ 506 if (connection->incoming){ 507 connection->set_protocol = true; 508 connection->state = HID_HOST_CONNECTION_ESTABLISHED; 509 connection->requested_protocol_mode = HID_PROTOCOL_MODE_BOOT; 510 hid_emit_descriptor_available_event(connection); 511 l2cap_request_can_send_now_event(connection->control_cid); 512 } else { 513 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED; 514 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, BLUETOOTH_PSM_HID_CONTROL, 0xffff, &connection->control_cid); 515 if (status != ERROR_CODE_SUCCESS){ 516 sdp_query_context_hid_host_control_cid = 0; 517 hid_emit_connected_event(connection, status); 518 hid_host_finalize_connection(connection); 519 } 520 } 521 break; 522 } 523 524 // report mode possible 525 if (connection->incoming) { 526 connection->set_protocol = true; 527 connection->state = HID_HOST_CONNECTION_ESTABLISHED; 528 connection->requested_protocol_mode = HID_PROTOCOL_MODE_REPORT; 529 hid_emit_descriptor_available_event(connection); 530 l2cap_request_can_send_now_event(connection->control_cid); 531 } else { 532 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED; 533 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, connection->control_psm, 0xffff, &connection->control_cid); 534 if (status != ERROR_CODE_SUCCESS){ 535 hid_emit_connected_event(connection, status); 536 hid_host_finalize_connection(connection); 537 } 538 } 539 break; 540 541 default: 542 break; 543 } 544 545 } 546 547 548 static void hid_host_handle_control_packet(hid_host_connection_t * connection, uint8_t *packet, uint16_t size){ 549 UNUSED(size); 550 uint8_t param; 551 hid_message_type_t message_type; 552 hid_handshake_param_type_t message_status; 553 hid_protocol_mode_t protocol_mode; 554 555 uint8_t * in_place_event; 556 uint8_t status; 557 558 message_type = (hid_message_type_t)(packet[0] >> 4); 559 if (message_type == HID_MESSAGE_TYPE_HID_CONTROL){ 560 param = packet[0] & 0x0F; 561 switch ((hid_control_param_t)param){ 562 case HID_CONTROL_PARAM_VIRTUAL_CABLE_UNPLUG: 563 hid_emit_event(connection, HID_SUBEVENT_VIRTUAL_CABLE_UNPLUG); 564 hid_host_disconnect(connection->hid_cid); 565 return; 566 default: 567 break; 568 } 569 } 570 571 message_status = (hid_handshake_param_type_t)(packet[0] & 0x0F); 572 573 switch (connection->state){ 574 case HID_HOST_CONNECTION_ESTABLISHED: 575 if (!connection->w4_set_protocol_response) break; 576 connection->w4_set_protocol_response = false; 577 578 switch (message_status){ 579 case HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL: 580 connection->protocol_mode = connection->requested_protocol_mode; 581 break; 582 default: 583 break; 584 } 585 hid_emit_set_protocol_response_event(connection, message_status); 586 break; 587 588 case HID_HOST_CONTROL_CONNECTION_ESTABLISHED: // outgoing 589 case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED: // outgoing 590 if (!connection->w4_set_protocol_response) break; 591 connection->w4_set_protocol_response = false; 592 593 switch (message_status){ 594 case HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL: 595 // we are already connected, here it is only confirmed that we are in required protocol 596 btstack_assert(connection->incoming == false); 597 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, connection->interrupt_psm, 0xffff, &connection->interrupt_cid); 598 if (status != ERROR_CODE_SUCCESS){ 599 log_info("HID Interrupt Connection failed: 0x%02x\n", status); 600 hid_emit_connected_event(connection, status); 601 hid_host_finalize_connection(connection); 602 break; 603 } 604 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED; 605 break; 606 default: 607 hid_emit_connected_event(connection, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE); 608 hid_host_finalize_connection(connection); 609 break; 610 } 611 break; 612 613 case HID_HOST_W4_GET_REPORT_RESPONSE: 614 switch (message_type){ 615 case HID_MESSAGE_TYPE_HANDSHAKE:{ 616 uint8_t event[8]; 617 hid_setup_get_report_event(connection, message_status, event, 0); 618 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, event, sizeof(event)); 619 break; 620 } 621 case HID_MESSAGE_TYPE_DATA: 622 // reuse hci+l2cap header - max 8 byte (7 bytes + 1 bytes overwriting hid header) 623 in_place_event = packet - 7; 624 hid_setup_get_report_event(connection, HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL, in_place_event, size-1); 625 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, in_place_event, size + 7); 626 break; 627 default: 628 break; 629 } 630 connection->state = HID_HOST_CONNECTION_ESTABLISHED; 631 break; 632 633 case HID_HOST_W4_SET_REPORT_RESPONSE: 634 hid_emit_event_with_status(connection, HID_SUBEVENT_SET_REPORT_RESPONSE, message_status); 635 connection->state = HID_HOST_CONNECTION_ESTABLISHED; 636 break; 637 638 case HID_HOST_W4_GET_PROTOCOL_RESPONSE: 639 protocol_mode = connection->protocol_mode; 640 641 switch (message_type){ 642 case HID_MESSAGE_TYPE_DATA: 643 protocol_mode = (hid_protocol_mode_t)packet[1]; 644 switch (protocol_mode){ 645 case HID_PROTOCOL_MODE_BOOT: 646 case HID_PROTOCOL_MODE_REPORT: 647 message_status = HID_HANDSHAKE_PARAM_TYPE_SUCCESSFUL; 648 break; 649 default: 650 message_status = HID_HANDSHAKE_PARAM_TYPE_ERR_INVALID_PARAMETER; 651 break; 652 } 653 break; 654 default: 655 break; 656 } 657 hid_emit_get_protocol_event(connection, message_status, protocol_mode); 658 connection->state = HID_HOST_CONNECTION_ESTABLISHED; 659 break; 660 661 default: 662 log_info("ignore invalid HID Control message"); 663 connection->state = HID_HOST_CONNECTION_ESTABLISHED; 664 break; 665 } 666 667 } 668 669 static void hid_host_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 670 UNUSED(channel); 671 UNUSED(size); 672 673 uint8_t event; 674 bd_addr_t address; 675 uint8_t status; 676 uint16_t l2cap_cid; 677 hid_host_connection_t * connection; 678 679 switch (packet_type) { 680 681 case L2CAP_DATA_PACKET: 682 connection = hid_host_get_connection_for_l2cap_cid(channel); 683 if (!connection) break; 684 685 if (channel == connection->interrupt_cid){ 686 uint8_t * in_place_event = packet - 7; 687 hid_setup_report_event(connection, in_place_event, size-1); 688 hid_callback(HCI_EVENT_PACKET, connection->hid_cid, in_place_event, size + 7); 689 break; 690 } 691 692 if (channel == connection->control_cid){ 693 hid_host_handle_control_packet(connection, packet, size); 694 break; 695 } 696 break; 697 698 case HCI_EVENT_PACKET: 699 event = hci_event_packet_get_type(packet); 700 switch (event) { 701 case L2CAP_EVENT_INCOMING_CONNECTION: 702 l2cap_event_incoming_connection_get_address(packet, address); 703 // connection should exist if psm == PSM_HID_INTERRUPT 704 connection = hid_host_get_connection_for_bd_addr(address); 705 706 switch (l2cap_event_incoming_connection_get_psm(packet)){ 707 case PSM_HID_CONTROL: 708 if (connection){ 709 l2cap_decline_connection(channel); 710 break; 711 } 712 713 connection = hid_host_create_connection(address); 714 if (!connection){ 715 log_error("Cannot create connection for %s", bd_addr_to_str(address)); 716 l2cap_decline_connection(channel); 717 break; 718 } 719 720 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED; 721 connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 722 connection->con_handle = l2cap_event_incoming_connection_get_handle(packet); 723 connection->control_cid = l2cap_event_incoming_connection_get_local_cid(packet); 724 connection->incoming = true; 725 726 // emit connection request 727 // user calls either hid_host_accept_connection or hid_host_decline_connection 728 hid_emit_incoming_connection_event(connection); 729 break; 730 731 case PSM_HID_INTERRUPT: 732 if (!connection || (connection->state != HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED)){ 733 log_error("Decline connection for %s", bd_addr_to_str(address)); 734 l2cap_decline_connection(channel); 735 break; 736 } 737 738 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED; 739 connection->interrupt_cid = l2cap_event_incoming_connection_get_local_cid(packet); 740 log_info("Accept connection on Interrupt channel %s", bd_addr_to_str(address)); 741 l2cap_accept_connection(channel); 742 break; 743 744 default: 745 log_info("Decline connection for %s", bd_addr_to_str(address)); 746 l2cap_decline_connection(channel); 747 break; 748 } 749 break; 750 751 case L2CAP_EVENT_CHANNEL_OPENED: 752 l2cap_event_channel_opened_get_address(packet, address); 753 754 connection = hid_host_get_connection_for_bd_addr(address); 755 if (!connection){ 756 log_error("Connection does not exist %s", bd_addr_to_str(address)); 757 break; 758 } 759 760 status = l2cap_event_channel_opened_get_status(packet); 761 if (status != ERROR_CODE_SUCCESS){ 762 log_info("L2CAP connection %s failed: 0x%02xn", bd_addr_to_str(address), status); 763 hid_emit_connected_event(connection, status); 764 hid_host_finalize_connection(connection); 765 break; 766 } 767 768 // handle incoming connection: 769 if (connection->incoming){ 770 switch (connection->state){ 771 case HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED: 772 // A Bluetooth HID Host or Bluetooth HID device shall always open both the control and Interrupt channels. (HID_v1.1.1, Chapter 5.2.2) 773 // We expect incomming interrupt connection from remote HID device 774 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED; 775 log_info("Incoming control connection opened: w4 interrupt"); 776 break; 777 778 case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED: 779 hid_emit_connected_event(connection, ERROR_CODE_SUCCESS); 780 connection->state = HID_HOST_CONNECTION_ESTABLISHED; 781 782 switch (connection->requested_protocol_mode){ 783 case HID_PROTOCOL_MODE_BOOT: 784 hid_emit_descriptor_available_event(connection); 785 connection->set_protocol = true; 786 l2cap_request_can_send_now_event(connection->control_cid); 787 log_info("Incoming interrupt connection opened: set boot mode"); 788 break; 789 default: 790 // SDP query 791 log_info("Incoming interrupt connection opened: start SDP query"); 792 connection->state = HID_HOST_W2_SEND_SDP_QUERY; 793 hid_host_handle_sdp_client_query_request.callback = &hid_host_handle_start_sdp_client_query; 794 (void) sdp_client_register_query_callback(&hid_host_handle_sdp_client_query_request); 795 break; 796 } 797 break; 798 799 default: 800 btstack_assert(false); 801 break; 802 } 803 break; 804 } 805 806 // handle outgoing connection 807 switch (connection->state){ 808 case HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED: 809 log_info("Opened control connection, requested protocol mode %d\n", connection->requested_protocol_mode); 810 connection->con_handle = l2cap_event_channel_opened_get_handle(packet); 811 connection->state = HID_HOST_CONTROL_CONNECTION_ESTABLISHED; 812 813 switch (connection->requested_protocol_mode){ 814 case HID_PROTOCOL_MODE_BOOT: 815 case HID_PROTOCOL_MODE_REPORT_WITH_FALLBACK_TO_BOOT: 816 connection->set_protocol = true; 817 connection->interrupt_psm = BLUETOOTH_PSM_HID_INTERRUPT; 818 l2cap_request_can_send_now_event(connection->control_cid); 819 break; 820 default: 821 status = l2cap_create_channel(hid_host_packet_handler, address, connection->interrupt_psm, 0xffff, &connection->interrupt_cid); 822 if (status){ 823 log_info("Connecting to HID Interrupt failed: 0x%02x", status); 824 hid_emit_connected_event(connection, status); 825 break; 826 } 827 connection->protocol_mode = connection->requested_protocol_mode; 828 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED; 829 break; 830 } 831 break; 832 833 case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED: 834 connection->state = HID_HOST_CONNECTION_ESTABLISHED; 835 log_info("HID host connection established, cids: control 0x%02x, interrupt 0x%02x interrupt, hid 0x%02x", 836 connection->control_cid, connection->interrupt_cid, connection->hid_cid); 837 hid_emit_connected_event(connection, ERROR_CODE_SUCCESS); 838 hid_emit_descriptor_available_event(connection); 839 break; 840 841 default: 842 btstack_assert(false); 843 break; 844 } 845 break; 846 847 case L2CAP_EVENT_CHANNEL_CLOSED: 848 l2cap_cid = l2cap_event_channel_closed_get_local_cid(packet); 849 connection = hid_host_get_connection_for_l2cap_cid(l2cap_cid); 850 if (!connection) return; 851 852 if (l2cap_cid == connection->interrupt_cid){ 853 connection->interrupt_cid = 0; 854 if (connection->state == HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){ 855 connection->state = HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED; 856 l2cap_disconnect(connection->control_cid, 0); 857 } 858 break; 859 } 860 861 if (l2cap_cid == connection->control_cid){ 862 connection->control_cid = 0; 863 hid_emit_event(connection, HID_SUBEVENT_CONNECTION_CLOSED); 864 hid_descriptor_storage_delete(connection); 865 hid_host_finalize_connection(connection); 866 break; 867 } 868 break; 869 870 case L2CAP_EVENT_CAN_SEND_NOW: 871 l2cap_cid = l2cap_event_can_send_now_get_local_cid(packet); 872 connection = hid_host_get_connection_for_l2cap_cid(l2cap_cid); 873 if (!connection) return; 874 875 876 877 if (connection->control_cid == l2cap_cid){ 878 switch(connection->state){ 879 case HID_HOST_CONTROL_CONNECTION_ESTABLISHED: 880 case HID_HOST_W4_INTERRUPT_CONNECTION_ESTABLISHED: 881 if (connection->set_protocol){ 882 connection->set_protocol = false; 883 uint8_t header = (HID_MESSAGE_TYPE_SET_PROTOCOL << 4) | connection->requested_protocol_mode; 884 uint8_t report[] = {header}; 885 connection->w4_set_protocol_response = true; 886 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report)); 887 break; 888 } 889 break; 890 891 case HID_HOST_CONNECTION_ESTABLISHED: 892 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_SUSPEND) != 0){ 893 connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_SUSPEND; 894 uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_SUSPEND }; 895 l2cap_send(connection->control_cid, (uint8_t*) report, 1); 896 break; 897 } 898 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND) != 0){ 899 connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND; 900 uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_EXIT_SUSPEND }; 901 l2cap_send(connection->control_cid, (uint8_t*) report, 1); 902 break; 903 } 904 if ((connection->control_tasks & CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG) != 0){ 905 connection->control_tasks &= ~CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG; 906 uint8_t report[] = { (HID_MESSAGE_TYPE_HID_CONTROL << 4) | HID_CONTROL_PARAM_VIRTUAL_CABLE_UNPLUG }; 907 l2cap_send(connection->control_cid, (uint8_t*) report, 1); 908 break; 909 } 910 911 if (connection->set_protocol){ 912 connection->set_protocol = false; 913 uint8_t header = (HID_MESSAGE_TYPE_SET_PROTOCOL << 4) | connection->requested_protocol_mode; 914 uint8_t report[] = {header}; 915 916 connection->w4_set_protocol_response = true; 917 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report)); 918 break; 919 } 920 break; 921 922 case HID_HOST_W2_SEND_GET_REPORT:{ 923 uint8_t header = (HID_MESSAGE_TYPE_GET_REPORT << 4) | connection->report_type; 924 uint8_t report[] = {header, connection->report_id}; 925 926 connection->state = HID_HOST_W4_GET_REPORT_RESPONSE; 927 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report)); 928 break; 929 } 930 931 case HID_HOST_W2_SEND_SET_REPORT:{ 932 uint8_t header = (HID_MESSAGE_TYPE_SET_REPORT << 4) | connection->report_type; 933 connection->state = HID_HOST_W4_SET_REPORT_RESPONSE; 934 935 l2cap_reserve_packet_buffer(); 936 uint8_t * out_buffer = l2cap_get_outgoing_buffer(); 937 out_buffer[0] = header; 938 out_buffer[1] = connection->report_id; 939 (void)memcpy(out_buffer + 2, connection->report, connection->report_len); 940 l2cap_send_prepared(connection->control_cid, connection->report_len + 2); 941 break; 942 } 943 944 case HID_HOST_W2_SEND_GET_PROTOCOL:{ 945 uint8_t header = (HID_MESSAGE_TYPE_GET_PROTOCOL << 4); 946 uint8_t report[] = {header}; 947 connection->state = HID_HOST_W4_GET_PROTOCOL_RESPONSE; 948 l2cap_send(connection->control_cid, (uint8_t*) report, sizeof(report)); 949 break; 950 } 951 952 default: 953 break; 954 } 955 } 956 957 if (connection->interrupt_cid == l2cap_cid && connection->state == HID_HOST_W2_SEND_REPORT){ 958 connection->state = HID_HOST_CONNECTION_ESTABLISHED; 959 // there is no response for this type of message 960 uint8_t header = (HID_MESSAGE_TYPE_DATA << 4) | connection->report_type; 961 962 l2cap_reserve_packet_buffer(); 963 uint8_t * out_buffer = l2cap_get_outgoing_buffer(); 964 out_buffer[0] = header; 965 out_buffer[1] = connection->report_id; 966 (void)memcpy(out_buffer + 2, connection->report, connection->report_len); 967 l2cap_send_prepared(connection->interrupt_cid, connection->report_len + 2); 968 break; 969 } 970 971 if (connection->control_tasks != 0){ 972 l2cap_request_can_send_now_event(connection->control_cid); 973 } 974 break; 975 default: 976 break; 977 } 978 default: 979 break; 980 } 981 } 982 983 984 void hid_host_init(uint8_t * hid_descriptor_storage, uint16_t hid_descriptor_storage_len){ 985 hid_host_descriptor_storage = hid_descriptor_storage; 986 hid_host_descriptor_storage_len = hid_descriptor_storage_len; 987 988 // register L2CAP Services for reconnections 989 l2cap_register_service(hid_host_packet_handler, PSM_HID_INTERRUPT, 0xffff, gap_get_security_level()); 990 l2cap_register_service(hid_host_packet_handler, PSM_HID_CONTROL, 0xffff, gap_get_security_level()); 991 } 992 993 void hid_host_register_packet_handler(btstack_packet_handler_t callback){ 994 hid_callback = callback; 995 } 996 997 998 static void hid_host_handle_start_sdp_client_query(void * context){ 999 UNUSED(context); 1000 btstack_linked_list_iterator_t it; 1001 btstack_linked_list_iterator_init(&it, &connections); 1002 1003 while (btstack_linked_list_iterator_has_next(&it)){ 1004 hid_host_connection_t * connection = (hid_host_connection_t *)btstack_linked_list_iterator_next(&it); 1005 1006 switch (connection->state){ 1007 case HID_HOST_W2_SEND_SDP_QUERY: 1008 connection->state = HID_HOST_W4_SDP_QUERY_RESULT; 1009 connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1010 break; 1011 default: 1012 continue; 1013 } 1014 1015 hid_descriptor_storage_init(connection); 1016 sdp_query_context_hid_host_control_cid = connection->hid_cid; 1017 sdp_client_query_uuid16(&hid_host_handle_sdp_client_query_result, (uint8_t *) connection->remote_addr, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE); 1018 return; 1019 } 1020 } 1021 1022 uint8_t hid_host_accept_connection(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){ 1023 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 1024 if (!connection){ 1025 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1026 } 1027 if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){ 1028 return ERROR_CODE_COMMAND_DISALLOWED; 1029 } 1030 1031 connection->requested_protocol_mode = protocol_mode; 1032 l2cap_accept_connection(connection->control_cid); 1033 return ERROR_CODE_SUCCESS; 1034 } 1035 1036 uint8_t hid_host_decline_connection(uint16_t hid_cid){ 1037 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 1038 if (!connection){ 1039 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1040 } 1041 if (connection->state != HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED){ 1042 return ERROR_CODE_COMMAND_DISALLOWED; 1043 } 1044 1045 l2cap_decline_connection(connection->control_cid); 1046 hid_host_finalize_connection(connection); 1047 return ERROR_CODE_SUCCESS; 1048 } 1049 1050 uint8_t hid_host_connect(bd_addr_t remote_addr, hid_protocol_mode_t protocol_mode, uint16_t * hid_cid){ 1051 if (hid_cid == NULL) { 1052 return ERROR_CODE_COMMAND_DISALLOWED; 1053 } 1054 1055 hid_host_connection_t * connection = hid_host_get_connection_for_bd_addr(remote_addr); 1056 if (connection){ 1057 return ERROR_CODE_COMMAND_DISALLOWED; 1058 } 1059 1060 connection = hid_host_create_connection(remote_addr); 1061 if (!connection) return BTSTACK_MEMORY_ALLOC_FAILED; 1062 1063 *hid_cid = connection->hid_cid; 1064 1065 connection->state = HID_HOST_W2_SEND_SDP_QUERY; 1066 connection->incoming = false; 1067 connection->requested_protocol_mode = protocol_mode; 1068 connection->hid_descriptor_status = ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; 1069 1070 uint8_t status = ERROR_CODE_SUCCESS; 1071 1072 switch (connection->requested_protocol_mode){ 1073 case HID_PROTOCOL_MODE_BOOT: 1074 connection->state = HID_HOST_W4_CONTROL_CONNECTION_ESTABLISHED; 1075 status = l2cap_create_channel(hid_host_packet_handler, connection->remote_addr, BLUETOOTH_PSM_HID_CONTROL, 0xffff, &connection->control_cid); 1076 break; 1077 default: 1078 hid_host_handle_sdp_client_query_request.callback = &hid_host_handle_start_sdp_client_query; 1079 // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback 1080 (void) sdp_client_register_query_callback(&hid_host_handle_sdp_client_query_request); 1081 break; 1082 } 1083 return status; 1084 } 1085 1086 1087 void hid_host_disconnect(uint16_t hid_cid){ 1088 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 1089 if (!connection) return; 1090 1091 switch (connection->state){ 1092 case HID_HOST_IDLE: 1093 case HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED: 1094 case HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED: 1095 return; 1096 default: 1097 break; 1098 } 1099 1100 if (connection->interrupt_cid){ 1101 connection->state = HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED; 1102 l2cap_disconnect(connection->interrupt_cid, 0); // reason isn't used 1103 return; 1104 } 1105 1106 if (connection->control_cid){ 1107 connection->state = HID_HOST_W4_CONTROL_CONNECTION_DISCONNECTED; 1108 l2cap_disconnect(connection->control_cid, 0); // reason isn't used 1109 return; 1110 } 1111 } 1112 1113 1114 static inline uint8_t hid_host_send_control_message(uint16_t hid_cid, uint8_t control_message_bitmask){ 1115 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 1116 if (!connection || !connection->control_cid) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1117 1118 if (connection->state < HID_HOST_CONTROL_CONNECTION_ESTABLISHED) { 1119 return ERROR_CODE_COMMAND_DISALLOWED; 1120 } 1121 if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){ 1122 return ERROR_CODE_COMMAND_DISALLOWED; 1123 } 1124 1125 connection->control_tasks |= control_message_bitmask; 1126 l2cap_request_can_send_now_event(connection->control_cid); 1127 return ERROR_CODE_SUCCESS; 1128 } 1129 1130 uint8_t hid_host_send_suspend(uint16_t hid_cid){ 1131 return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_SUSPEND); 1132 } 1133 1134 uint8_t hid_host_send_exit_suspend(uint16_t hid_cid){ 1135 return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_EXIT_SUSPEND); 1136 } 1137 1138 uint8_t hid_host_send_virtual_cable_unplug(uint16_t hid_cid){ 1139 return hid_host_send_control_message(hid_cid, CONTROL_MESSAGE_BITMASK_VIRTUAL_CABLE_UNPLUG); 1140 } 1141 1142 uint8_t hid_host_send_get_report(uint16_t hid_cid, hid_report_type_t report_type, uint8_t report_id){ 1143 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 1144 1145 if (!connection || !connection->control_cid){ 1146 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1147 } 1148 if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){ 1149 return ERROR_CODE_COMMAND_DISALLOWED; 1150 } 1151 1152 connection->state = HID_HOST_W2_SEND_GET_REPORT; 1153 connection->report_type = report_type; 1154 connection->report_id = report_id; 1155 1156 l2cap_request_can_send_now_event(connection->control_cid); 1157 return ERROR_CODE_SUCCESS; 1158 } 1159 1160 uint8_t hid_host_send_set_report(uint16_t hid_cid, hid_report_type_t report_type, uint8_t report_id, const uint8_t * report, uint8_t report_len){ 1161 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 1162 1163 if (!connection || !connection->control_cid){ 1164 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1165 } 1166 1167 if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){ 1168 return ERROR_CODE_COMMAND_DISALLOWED; 1169 } 1170 1171 if ((l2cap_max_mtu() - 2) < report_len ){ 1172 return ERROR_CODE_COMMAND_DISALLOWED; 1173 } 1174 1175 connection->state = HID_HOST_W2_SEND_SET_REPORT; 1176 connection->report_type = report_type; 1177 connection->report_id = report_id; 1178 connection->report = report; 1179 connection->report_len = report_len; 1180 1181 l2cap_request_can_send_now_event(connection->control_cid); 1182 return ERROR_CODE_SUCCESS; 1183 } 1184 1185 uint8_t hid_host_send_get_protocol(uint16_t hid_cid){ 1186 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 1187 if (!connection || !connection->control_cid){ 1188 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1189 } 1190 if (connection->state != HID_HOST_CONNECTION_ESTABLISHED){ 1191 return ERROR_CODE_COMMAND_DISALLOWED; 1192 } 1193 1194 connection->state = HID_HOST_W2_SEND_GET_PROTOCOL; 1195 l2cap_request_can_send_now_event(connection->control_cid); 1196 return ERROR_CODE_SUCCESS; 1197 } 1198 1199 uint8_t hid_host_send_set_protocol_mode(uint16_t hid_cid, hid_protocol_mode_t protocol_mode){ 1200 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 1201 if (!connection || !connection->control_cid){ 1202 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1203 } 1204 if (connection->state != HID_HOST_CONNECTION_ESTABLISHED || connection->set_protocol || connection->w4_set_protocol_response){ 1205 return ERROR_CODE_COMMAND_DISALLOWED; 1206 } 1207 1208 connection->set_protocol = true; 1209 connection->requested_protocol_mode = protocol_mode; 1210 1211 l2cap_request_can_send_now_event(connection->control_cid); 1212 return ERROR_CODE_SUCCESS; 1213 } 1214 1215 1216 uint8_t hid_host_send_report(uint16_t hid_cid, uint8_t report_id, const uint8_t * report, uint8_t report_len){ 1217 hid_host_connection_t * connection = hid_host_get_connection_for_hid_cid(hid_cid); 1218 if (!connection || !connection->control_cid || !connection->interrupt_cid) { 1219 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 1220 } 1221 1222 if (connection->state < HID_HOST_CONNECTION_ESTABLISHED) { 1223 return ERROR_CODE_COMMAND_DISALLOWED; 1224 } 1225 if (connection->state >= HID_HOST_W4_INTERRUPT_CONNECTION_DISCONNECTED){ 1226 return ERROR_CODE_COMMAND_DISALLOWED; 1227 } 1228 1229 if ((l2cap_max_mtu() - 2) < report_len ){ 1230 return ERROR_CODE_COMMAND_DISALLOWED; 1231 } 1232 1233 connection->state = HID_HOST_W2_SEND_REPORT; 1234 connection->report_type = HID_REPORT_TYPE_OUTPUT; 1235 connection->report_id = report_id; 1236 connection->report = report; 1237 connection->report_len = report_len; 1238 1239 l2cap_request_can_send_now_event(connection->interrupt_cid); 1240 return ERROR_CODE_SUCCESS; 1241 } 1242