hid_host.c (483beab4346dd9a2f52baea618d4ec818b0635b9) hid_host.c (1744e196a49a984d365d175820c0dfc1b19ce6c7)
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

--- 374 unchanged lines hidden (view full) ---

383 l2cap_disconnect(interrupt_cid);
384 }
385 if (control_cid != 0){
386 l2cap_disconnect(control_cid);
387 }
388 btstack_linked_list_remove(&hid_host_connections, (btstack_linked_item_t*) connection);
389 btstack_memory_hid_host_connection_free(connection);
390}
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

--- 374 unchanged lines hidden (view full) ---

383 l2cap_disconnect(interrupt_cid);
384 }
385 if (control_cid != 0){
386 l2cap_disconnect(control_cid);
387 }
388 btstack_linked_list_remove(&hid_host_connections, (btstack_linked_item_t*) connection);
389 btstack_memory_hid_host_connection_free(connection);
390}
391
391
392static void hid_host_handle_sdp_hid_descriptor_list(hid_host_connection_t * connection, uint16_t attribute_offset, uint8_t data){
393 // state machine
394 static uint16_t bytes_needed = 0;
395 static uint16_t bytes_received = 0;
396 static enum {
397 HID_DESCRIPTOR_LIST_ERROR,
398 HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_START,
399 HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_HEADER,
400 HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_START,
401 HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_HEADER,
402 HID_DESCRIPTOR_LIST_W4_ITEM_START,
403 HID_DESCRIPTOR_LIST_W4_ITEM_HEADER,
404 HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE,
405 HID_DESCRIPTOR_LIST_W4_STRING_HEADER,
406 HID_DESCRIPTOR_LIST_W4_STRING_COMPLETE,
407 HID_DESCRIPTOR_LIST_COMPLETE,
408 } state = HID_DESCRIPTOR_LIST_ERROR;
409
410 // init state machine
411 if (attribute_offset == 0){
412 state = HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_START;
413 bytes_received = 0;
414 }
415
416 // next step
417 bool stored;
418 bool error = false;
419 switch (state){
420 case HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_START:
421 hid_host_sdp_attribute_value[bytes_received++] = data;
422 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_DES){
423 bytes_needed = de_get_header_size(hid_host_sdp_attribute_value);
424 state = HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_HEADER;
425 } else {
426 error = true;
427 }
428 break;
429 case HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_LIST_HEADER:
430 hid_host_sdp_attribute_value[bytes_received++] = data;
431 if (bytes_received == bytes_needed) {
432 bytes_received = 0;
433 state = HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_START;
434 }
435 break;
436 case HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_START:
437 hid_host_sdp_attribute_value[bytes_received++] = data;
438 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_DES){
439 bytes_needed = de_get_header_size(hid_host_sdp_attribute_value);
440 state = HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_HEADER;
441 } else {
442 error = true;
443 }
444 break;
445 case HID_DESCRIPTOR_LIST_W4_DES_DESCRIPTOR_HEADER:
446 hid_host_sdp_attribute_value[bytes_received++] = data;
447 if (bytes_received == bytes_needed) {
448 bytes_received = 0;
449 state = HID_DESCRIPTOR_LIST_W4_ITEM_START;
450 }
451 break;
452 case HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE:
453 // ignore data for non-string item
454 bytes_received++;
455 if (bytes_received == bytes_needed) {
456 bytes_received = 0;
457 state = HID_DESCRIPTOR_LIST_W4_ITEM_START;
458 }
459 break;
460 case HID_DESCRIPTOR_LIST_W4_ITEM_START:
461 hid_host_sdp_attribute_value[bytes_received++] = data;
462 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_STRING){
463 bytes_needed = de_get_header_size(hid_host_sdp_attribute_value);
464 state = HID_DESCRIPTOR_LIST_W4_STRING_HEADER;
465 } else {
466 bytes_needed = de_get_header_size(hid_host_sdp_attribute_value);
467 if (bytes_needed > 1){
468 state = HID_DESCRIPTOR_LIST_W4_ITEM_HEADER;
469 } else {
470 bytes_needed = de_get_len(hid_host_sdp_attribute_value);
471 state = HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE;
472 }
473 }
474 break;
475 case HID_DESCRIPTOR_LIST_W4_ITEM_HEADER:
476 hid_host_sdp_attribute_value[bytes_received++] = data;
477 if (bytes_received == bytes_needed) {
478 bytes_needed = de_get_len(hid_host_sdp_attribute_value);
479 state = HID_DESCRIPTOR_LIST_W4_ITEM_COMPLETE;
480 }
481 break;
482 case HID_DESCRIPTOR_LIST_W4_STRING_HEADER:
483 hid_host_sdp_attribute_value[bytes_received++] = data;
484 if (bytes_received == bytes_needed) {
485 bytes_received = 0;
486 bytes_needed = de_get_data_size(hid_host_sdp_attribute_value);
487 state = HID_DESCRIPTOR_LIST_W4_STRING_COMPLETE;
488 }
489 break;
490 case HID_DESCRIPTOR_LIST_W4_STRING_COMPLETE:
491 stored = hid_descriptor_storage_store(connection, data);
492 if (stored) {
493 bytes_received++;
494 if (bytes_received == bytes_needed) {
495 connection->hid_descriptor_status = ERROR_CODE_SUCCESS;
496 log_info_hexdump(&hid_host_descriptor_storage[connection->hid_descriptor_offset],
497 connection->hid_descriptor_len);
498 state = HID_DESCRIPTOR_LIST_COMPLETE;
499 }
500 } else {
501 error = true;
502 }
503 break;
504 case HID_DESCRIPTOR_LIST_ERROR:
505 case HID_DESCRIPTOR_LIST_COMPLETE:
506 // ignore data
507 break;
508 default:
509 btstack_unreachable();
510 break;
511 }
512
513 if (error){
514 log_info("Descriptor List invalid, state %u", (int) state);
515 bytes_received = 0;
516 bytes_needed = 0;
517 state = HID_DESCRIPTOR_LIST_ERROR;
518 connection->hid_descriptor_status = ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
519 }
520}
521
392static void hid_host_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
393 UNUSED(packet_type);
394 UNUSED(channel);
395 UNUSED(size);
396
397 des_iterator_t attribute_list_it;
398 des_iterator_t additional_des_it;
399 des_iterator_t prot_it;

--- 17 unchanged lines hidden (view full) ---

417 uint16_t attribute_offset;
418 uint8_t attribute_data;
419 switch (hci_event_packet_get_type(packet)){
420 case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
421
422 attribute_id = sdp_event_query_attribute_byte_get_attribute_id(packet);
423 attribute_offset = sdp_event_query_attribute_byte_get_data_offset(packet);
424 attribute_data = sdp_event_query_attribute_byte_get_data(packet);
522static void hid_host_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
523 UNUSED(packet_type);
524 UNUSED(channel);
525 UNUSED(size);
526
527 des_iterator_t attribute_list_it;
528 des_iterator_t additional_des_it;
529 des_iterator_t prot_it;

--- 17 unchanged lines hidden (view full) ---

547 uint16_t attribute_offset;
548 uint8_t attribute_data;
549 switch (hci_event_packet_get_type(packet)){
550 case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
551
552 attribute_id = sdp_event_query_attribute_byte_get_attribute_id(packet);
553 attribute_offset = sdp_event_query_attribute_byte_get_data_offset(packet);
554 attribute_data = sdp_event_query_attribute_byte_get_data(packet);
555
556 // process BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST with state machine
557 if (attribute_id == BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST){
558 hid_host_handle_sdp_hid_descriptor_list(connection, attribute_offset, attribute_data);
559 break;
560 }
561
425 if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= hid_host_sdp_attribute_value_buffer_size) {
426
427 hid_host_sdp_attribute_value[attribute_offset] = attribute_data;
428
429 if ((uint16_t)(attribute_offset + 1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) {
430 switch(attribute_id) {
431
432 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST:

--- 36 unchanged lines hidden (view full) ---

469 break;
470 default:
471 break;
472 }
473 }
474 }
475 break;
476
562 if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= hid_host_sdp_attribute_value_buffer_size) {
563
564 hid_host_sdp_attribute_value[attribute_offset] = attribute_data;
565
566 if ((uint16_t)(attribute_offset + 1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) {
567 switch(attribute_id) {
568
569 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST:

--- 36 unchanged lines hidden (view full) ---

606 break;
607 default:
608 break;
609 }
610 }
611 }
612 break;
613
477 case BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST:
478 for (des_iterator_init(&attribute_list_it, hid_host_sdp_attribute_value); des_iterator_has_more(&attribute_list_it); des_iterator_next(&attribute_list_it)) {
479 if (des_iterator_get_type(&attribute_list_it) != DE_DES) continue;
480 des_element = des_iterator_get_element(&attribute_list_it);
481 for (des_iterator_init(&additional_des_it, des_element); des_iterator_has_more(&additional_des_it); des_iterator_next(&additional_des_it)) {
482 if (des_iterator_get_type(&additional_des_it) != DE_STRING) continue;
483 element = des_iterator_get_element(&additional_des_it);
484
485 const uint8_t * descriptor = de_get_string(element);
486 uint16_t descriptor_len = de_get_data_size(element);
487
488 uint16_t i;
489 bool stored = false;
490
491 connection->hid_descriptor_status = ERROR_CODE_SUCCESS;
492 for (i = 0; i < descriptor_len; i++){
493 stored = hid_descriptor_storage_store(connection, descriptor[i]);
494 if (!stored){
495 connection->hid_descriptor_status = ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
496 break;
497 }
498 }
499 }
500 }
501 break;
502
503 case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MAX_LATENCY:
504 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_UINT) {
505 uint16_t host_max_latency;
506 if (de_element_get_uint16(hid_host_sdp_attribute_value, &host_max_latency) == 1){
507 connection->host_max_latency = host_max_latency;
508 } else {
509 connection->host_max_latency = 0xFFFF;
510 }

--- 809 unchanged lines hidden ---
614 case BLUETOOTH_ATTRIBUTE_HIDSSR_HOST_MAX_LATENCY:
615 if (de_get_element_type(hid_host_sdp_attribute_value) == DE_UINT) {
616 uint16_t host_max_latency;
617 if (de_element_get_uint16(hid_host_sdp_attribute_value, &host_max_latency) == 1){
618 connection->host_max_latency = host_max_latency;
619 } else {
620 connection->host_max_latency = 0xFFFF;
621 }

--- 809 unchanged lines hidden ---