From 2901a9b7af2a81f193187d7d58a554b5f7f1928c Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 12 Mar 2021 10:03:30 +0100 Subject: [PATCH] hids_client: fix enable mouse and keyboard --- example/hog_boot_host_demo.c | 2 + example/hog_host_demo.c | 9 ++- src/ble/gatt-service/hids_client.c | 107 +++++++++++++++-------------- src/ble/gatt-service/hids_client.h | 5 ++ 4 files changed, 67 insertions(+), 56 deletions(-) diff --git a/example/hog_boot_host_demo.c b/example/hog_boot_host_demo.c index cc20ed9ee..80c54250d 100644 --- a/example/hog_boot_host_demo.c +++ b/example/hog_boot_host_demo.c @@ -485,6 +485,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack hog_connect(); break; case HCI_EVENT_DISCONNECTION_COMPLETE: + if (app_state != READY) break; + connection_handle = HCI_CON_HANDLE_INVALID; switch (app_state){ case READY: diff --git a/example/hog_host_demo.c b/example/hog_host_demo.c index 04ec70e3e..ae27ead7c 100644 --- a/example/hog_host_demo.c +++ b/example/hog_host_demo.c @@ -68,10 +68,7 @@ static enum { W4_HID_DEVICE_FOUND, W4_CONNECTED, W4_ENCRYPTED, - W4_HID_SERVICE_FOUND, - W4_HID_CHARACTERISTICS_FOUND, - W4_BOOT_KEYBOARD_ENABLED, - W4_BOOT_MOUSE_ENABLED, + W4_HID_CLIENT_CONNECTED, READY, W4_TIMEOUT_THEN_SCAN, W4_TIMEOUT_THEN_RECONNECT, @@ -390,6 +387,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break; btstack_assert(app_state == W4_WORKING); + hog_start_connect(); break; case GAP_EVENT_ADVERTISING_REPORT: @@ -405,6 +403,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack hog_connect(); break; case HCI_EVENT_DISCONNECTION_COMPLETE: + if (app_state != READY) break; connection_handle = HCI_CON_HANDLE_INVALID; switch (app_state){ case READY: @@ -441,7 +440,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack } // continue - query primary services printf("Search for HID service.\n"); - app_state = W4_HID_SERVICE_FOUND; + app_state = W4_HID_CLIENT_CONNECTED; status = hids_client_connect(connection_handle, handle_gatt_client_event, HID_PROTOCOL_MODE_BOOT, &hids_cid); if (status != ERROR_CODE_SUCCESS){ diff --git a/src/ble/gatt-service/hids_client.c b/src/ble/gatt-service/hids_client.c index 96713c7ac..a8bc70b55 100644 --- a/src/ble/gatt-service/hids_client.c +++ b/src/ble/gatt-service/hids_client.c @@ -148,64 +148,45 @@ static void hids_run_for_client(hids_client_t * client){ UNUSED(att_status); break; - case HIDS_CLIENT_STATE_W4_KEYBOARD_ENABLED: + case HIDS_CLIENT_STATE_W2_ENABLE_KEYBOARD: + client->state = HIDS_CLIENT_STATE_W4_KEYBOARD_ENABLED; characteristic.value_handle = client->boot_keyboard_input_value_handle; characteristic.end_handle = client->boot_keyboard_input_end_handle; + characteristic.properties = client->boot_keyboard_input_properties; att_status = gatt_client_write_client_characteristic_configuration(&handle_gatt_client_event, client->con_handle, &characteristic, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); - UNUSED(att_status); + + if (att_status != ERROR_CODE_SUCCESS){ + client->boot_keyboard_input_value_handle = 0; + } break; - case HIDS_CLIENT_STATE_W4_MOUSE_ENABLED: + case HIDS_CLIENT_STATE_W2_ENABLE_MOUSE: + client->state = HIDS_CLIENT_STATE_W4_MOUSE_ENABLED; characteristic.value_handle = client->boot_mouse_input_value_handle; characteristic.end_handle = client->boot_mouse_input_end_handle; + characteristic.properties = client->boot_mouse_input_properties; att_status = gatt_client_write_client_characteristic_configuration(&handle_gatt_client_event, client->con_handle, &characteristic, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); - UNUSED(att_status); + + if (att_status != ERROR_CODE_SUCCESS){ + client->boot_mouse_input_value_handle = 0; + } break; - case HIDS_CLIENT_STATE_W4_SET_PROTOCOL_MODE: - client->protocol_mode = client->required_protocol_mode; - att_status = gatt_client_write_value_of_characteristic_without_response(client->con_handle, client->protocol_mode_value_handle, 1, (uint8_t *)&client->protocol_mode); + case HIDS_CLIENT_STATE_W2_SET_PROTOCOL_MODE: + client->state = HIDS_CLIENT_STATE_W4_SET_PROTOCOL_MODE; + att_status = gatt_client_write_value_of_characteristic_without_response(client->con_handle, client->protocol_mode_value_handle, 1, (uint8_t *)&client->required_protocol_mode); UNUSED(att_status); + + client->protocol_mode = client->required_protocol_mode; client->state = HIDS_CLIENT_STATE_CONNECTED; hids_emit_connection_established(client, ERROR_CODE_SUCCESS); break; - case HIDS_CLIENT_STATE_CONNECTED: - - break; - default: break; } } -static hid_service_client_state_t boot_protocol_mode_setup_next_state(hids_client_t * client){ - hid_service_client_state_t state = HIDS_CLIENT_STATE_IDLE; - - switch (client->state){ - case HIDS_CLIENT_STATE_W4_CHARACTERISTIC_RESULT: - // set protocol mode - if (client->boot_keyboard_input_value_handle != 0){ - state = HIDS_CLIENT_STATE_W4_KEYBOARD_ENABLED; - break; - } - if (client->boot_mouse_input_value_handle != 0){ - state = HIDS_CLIENT_STATE_W4_MOUSE_ENABLED; - break; - } - break; - case HIDS_CLIENT_STATE_W4_KEYBOARD_ENABLED: - if (client->boot_mouse_input_value_handle != 0){ - state = HIDS_CLIENT_STATE_W4_MOUSE_ENABLED; - break; - } - break; - default: - break; - } - return state; -} - static void hids_client_setup_report_event(hids_client_t * client, uint8_t report_id, uint8_t *buffer, uint16_t report_len){ uint16_t pos = 0; buffer[pos++] = HCI_EVENT_GATTSERVICE_META; @@ -286,9 +267,13 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint switch (characteristic.uuid16){ case ORG_BLUETOOTH_CHARACTERISTIC_BOOT_KEYBOARD_INPUT_REPORT: client->boot_keyboard_input_value_handle = characteristic.value_handle; + client->boot_keyboard_input_end_handle = characteristic.end_handle; + client->boot_keyboard_input_properties = characteristic.properties; break; case ORG_BLUETOOTH_CHARACTERISTIC_BOOT_MOUSE_INPUT_REPORT: client->boot_mouse_input_value_handle = characteristic.value_handle; + client->boot_mouse_input_end_handle = characteristic.end_handle; + client->boot_mouse_input_properties = characteristic.properties; break; case ORG_BLUETOOTH_CHARACTERISTIC_PROTOCOL_MODE: client->protocol_mode_value_handle = characteristic.value_handle; @@ -333,15 +318,15 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint hids_finalize_client(client); break; } - + switch (client->required_protocol_mode){ case HID_PROTOCOL_MODE_BOOT: if (client->boot_keyboard_input_value_handle != 0){ - client->state = HIDS_CLIENT_STATE_W4_KEYBOARD_ENABLED; + client->state = HIDS_CLIENT_STATE_W2_ENABLE_KEYBOARD; break; } if (client->boot_mouse_input_value_handle != 0){ - client->state = HIDS_CLIENT_STATE_W4_MOUSE_ENABLED; + client->state = HIDS_CLIENT_STATE_W2_ENABLE_MOUSE; break; } hids_emit_connection_established(client, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE); @@ -353,31 +338,51 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint break; case HIDS_CLIENT_STATE_W4_KEYBOARD_ENABLED: - // setup listener - characteristic.value_handle = client->boot_keyboard_input_value_handle; - gatt_client_listen_for_characteristic_value_updates(&client->boot_keyboard_notifications, &handle_boot_keyboard_hid_event, client->con_handle, &characteristic); + if (client->boot_keyboard_input_value_handle != 0){ + // setup listener + characteristic.value_handle = client->boot_keyboard_input_value_handle; + gatt_client_listen_for_characteristic_value_updates(&client->boot_keyboard_notifications, &handle_boot_keyboard_hid_event, client->con_handle, &characteristic); + } else { + if (client->boot_mouse_input_value_handle == 0){ + hids_emit_connection_established(client, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE); + hids_finalize_client(client); + break; + } + } if (client->boot_mouse_input_value_handle != 0){ - client->state = HIDS_CLIENT_STATE_W4_MOUSE_ENABLED; + client->state = HIDS_CLIENT_STATE_W2_ENABLE_MOUSE; break; - } + } + // set protocol if (client->protocol_mode_value_handle != 0){ - client->state = HIDS_CLIENT_STATE_W4_SET_PROTOCOL_MODE; + client->state = HIDS_CLIENT_STATE_W2_SET_PROTOCOL_MODE; } else { + client->protocol_mode = HID_PROTOCOL_MODE_BOOT; client->state = HIDS_CLIENT_STATE_CONNECTED; hids_emit_connection_established(client, ERROR_CODE_SUCCESS); } + hids_run_for_client(client); break; case HIDS_CLIENT_STATE_W4_MOUSE_ENABLED: - // setup listener - characteristic.value_handle = client->boot_mouse_input_value_handle; - gatt_client_listen_for_characteristic_value_updates(&client->boot_mouse_notifications, &handle_boot_mouse_hid_event, client->con_handle, &characteristic); + if (client->boot_mouse_input_value_handle != 0){ + // setup listener + characteristic.value_handle = client->boot_mouse_input_value_handle; + gatt_client_listen_for_characteristic_value_updates(&client->boot_mouse_notifications, &handle_boot_mouse_hid_event, client->con_handle, &characteristic); + } else { + if (client->boot_keyboard_input_value_handle == 0){ + hids_emit_connection_established(client, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE); + hids_finalize_client(client); + break; + } + } if (client->protocol_mode_value_handle != 0){ - client->state = HIDS_CLIENT_STATE_W4_SET_PROTOCOL_MODE; + client->state = HIDS_CLIENT_STATE_W2_SET_PROTOCOL_MODE; } else { + client->protocol_mode = HID_PROTOCOL_MODE_BOOT; client->state = HIDS_CLIENT_STATE_CONNECTED; hids_emit_connection_established(client, ERROR_CODE_SUCCESS); } diff --git a/src/ble/gatt-service/hids_client.h b/src/ble/gatt-service/hids_client.h index 213c85e3a..4847d6989 100644 --- a/src/ble/gatt-service/hids_client.h +++ b/src/ble/gatt-service/hids_client.h @@ -59,8 +59,11 @@ typedef enum { HIDS_CLIENT_STATE_W4_SERVICE_RESULT, HIDS_CLIENT_STATE_W2_QUERY_CHARACTERISTIC, HIDS_CLIENT_STATE_W4_CHARACTERISTIC_RESULT, + HIDS_CLIENT_STATE_W2_ENABLE_KEYBOARD, HIDS_CLIENT_STATE_W4_KEYBOARD_ENABLED, + HIDS_CLIENT_STATE_W2_ENABLE_MOUSE, HIDS_CLIENT_STATE_W4_MOUSE_ENABLED, + HIDS_CLIENT_STATE_W2_SET_PROTOCOL_MODE, HIDS_CLIENT_STATE_W4_SET_PROTOCOL_MODE, HIDS_CLIENT_STATE_CONNECTED } hid_service_client_state_t; @@ -94,10 +97,12 @@ typedef struct { uint16_t boot_keyboard_input_value_handle; uint16_t boot_keyboard_input_end_handle; + uint16_t boot_keyboard_input_properties; gatt_client_notification_t boot_keyboard_notifications; uint16_t boot_mouse_input_value_handle; uint16_t boot_mouse_input_end_handle; + uint16_t boot_mouse_input_properties; gatt_client_notification_t boot_mouse_notifications; } hids_client_t;