diff --git a/src/ble/gatt-service/hids_client.c b/src/ble/gatt-service/hids_client.c index 312732ac8..c080c7b44 100644 --- a/src/ble/gatt-service/hids_client.c +++ b/src/ble/gatt-service/hids_client.c @@ -891,12 +891,6 @@ static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint client = hids_get_client_for_con_handle(gatt_event_service_query_result_get_handle(packet)); btstack_assert(client != NULL); - if (client->state != HIDS_CLIENT_STATE_W4_SERVICE_RESULT) { - hids_emit_connection_established(client, GATT_CLIENT_IN_WRONG_STATE); - hids_finalize_client(client); - break; - } - if (client->num_instances < MAX_NUM_HID_SERVICES){ uint8_t index = client->num_instances; gatt_event_service_query_result_get_service(packet, &service); @@ -1503,7 +1497,7 @@ uint8_t hids_client_get_protocol_mode(uint16_t hids_cid, uint8_t service_index){ return ERROR_CODE_SUCCESS; } -uint8_t hids_client_send_set_protocol_mode(uint16_t hids_cid, hid_protocol_mode_t protocol_mode, uint8_t service_index){ +uint8_t hids_client_send_set_protocol_mode(uint16_t hids_cid, uint8_t service_index, hid_protocol_mode_t protocol_mode){ hids_client_t * client = hids_get_client_for_cid(hids_cid); if (client == NULL){ return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; @@ -1558,7 +1552,7 @@ uint8_t hids_client_send_exit_suspend(uint16_t hids_cid, uint8_t service_index){ return hids_client_send_control_point_cmd(hids_cid, service_index, 1); } -uint8_t hids_client_send_enable_notifications(uint16_t hids_cid){ +uint8_t hids_client_enable_notifications(uint16_t hids_cid){ hids_client_t * client = hids_get_client_for_cid(hids_cid); if (client == NULL){ return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; @@ -1576,7 +1570,7 @@ uint8_t hids_client_send_enable_notifications(uint16_t hids_cid){ return ERROR_CODE_SUCCESS; } -uint8_t hids_client_send_disable_notifications(uint16_t hids_cid){ +uint8_t hids_client_disable_notifications(uint16_t hids_cid){ hids_client_t * client = hids_get_client_for_cid(hids_cid); if (client == NULL){ return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; diff --git a/src/ble/gatt-service/hids_client.h b/src/ble/gatt-service/hids_client.h index 6945f8d4c..cb80a375c 100644 --- a/src/ble/gatt-service/hids_client.h +++ b/src/ble/gatt-service/hids_client.h @@ -201,71 +201,157 @@ typedef struct { /* API_START */ /** - * @brief Initialize Battery Service. + * @brief Initialize HID Service Client. The HID Descriptor storage is shared between all connections. + * * @param hid_descriptor_storage * @param hid_descriptor_storage_len */ void hids_client_init(uint8_t * hid_descriptor_storage, uint16_t hid_descriptor_storage_len); -/* @brief Connect to HID Services of remote device. +/* @brief Connect to HID Services of remote device. Event GATTSERVICE_SUBEVENT_HID_SERVICE_CONNECTED will be emitted + * after all remote HID services and characteristics are found, and notifications for all input reports are enabled. + * Status code can be ERROR_CODE_SUCCES if at least one HID service is found, otherwise either ATT errors or + * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if no service or report map or report are found. + * It also contains the number of individual HIDS Services. * * @param con_handle * @param packet_handler * @param protocol_mode see hid_protocol_mode_t in btstack_hid.h - * @param hids_cid - * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_COMMAND_DISALLOWED if there is already a client associated with con_handle, or BTSTACK_MEMORY_ALLOC_FAILED + * @param hids_cid (out) to use for other functions + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_COMMAND_DISALLOWED if there is already a client + * associated with con_handle, or BTSTACK_MEMORY_ALLOC_FAILED. */ uint8_t hids_client_connect(hci_con_handle_t con_handle, btstack_packet_handler_t packet_handler, hid_protocol_mode_t protocol_mode, uint16_t * hids_cid); /** - * @brief Send HID output report. + * @brief Send HID report. + * * @param hids_cid * @param report_id + * @param report_type * @param report * @param report_len - * @result status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, ERROR_CODE_COMMAND_DISALLOWED + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, + * ERROR_CODE_COMMAND_DISALLOWED if client is in wrong state, + * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if no report with given type and ID is found, or + * ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE if report length exceeds MTU. */ uint8_t hids_client_send_write_report(uint16_t hids_cid, uint8_t report_id, hid_report_type_t report_type, const uint8_t * report, uint8_t report_len); +/** + * @brief Get HID report. Event GATTSERVICE_SUBEVENT_HID_REPORT is emitted. + * + * @param hids_cid + * @param report_id + * @param report_type + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, + * ERROR_CODE_COMMAND_DISALLOWED if client is in wrong state, + * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if no report with given type and ID is found, or + * ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE if report length exceeds MTU. + */ uint8_t hids_client_send_get_report(uint16_t hids_cid, uint8_t report_id, hid_report_type_t report_type); +/** + * @brief Get HID Information. Event GATTSERVICE_SUBEVENT_HID_INFORMATION is emitted. + * + * @param hids_cid + * @param service_index + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, + * ERROR_CODE_COMMAND_DISALLOWED if client is in wrong state, or + * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if no report with given type and ID is found. + */ uint8_t hids_client_get_hid_information(uint16_t hids_cid, uint8_t service_index); +/** + * @brief Get Protocol Mode. Event GATTSERVICE_SUBEVENT_HID_PROTOCOL_MODE is emitted. + * + * @param hids_cid + * @param service_index + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, + * ERROR_CODE_COMMAND_DISALLOWED if client is in wrong state, or + * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if no report with given type and ID is found. + */ uint8_t hids_client_get_protocol_mode(uint16_t hids_cid, uint8_t service_index); -uint8_t hids_client_send_set_protocol_mode(uint16_t hids_cid, hid_protocol_mode_t protocol_mode, uint8_t service_index); - -uint8_t hids_client_send_suspend(uint16_t hids_cid, uint8_t service_index); - -uint8_t hids_client_send_exit_suspend(uint16_t hids_cid, uint8_t service_index); - -uint8_t hids_client_send_enable_notifications(uint16_t hids_cid); - -uint8_t hids_client_send_disable_notifications(uint16_t hids_cid); +/** + * @brief Set Protocol Mode. + * + * @param hids_cid + * @param service_index + * @param protocol_mode + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, + * ERROR_CODE_COMMAND_DISALLOWED if client is in wrong state, or + * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if no report with given type and ID is found. + */ +uint8_t hids_client_send_set_protocol_mode(uint16_t hids_cid, uint8_t service_index, hid_protocol_mode_t protocol_mode); /** - * @brief Disconnect from Battery Service. + * @brief Send Suspend to remote HID service. + * * @param hids_cid - * @return status + * @param service_index + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, + * ERROR_CODE_COMMAND_DISALLOWED if client is in wrong state, or + * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if no report with given type and ID is found. + */ +uint8_t hids_client_send_suspend(uint16_t hids_cid, uint8_t service_index); + +/** + * @brief Send Exit Suspend to remote HID service. + * + * @param hids_cid + * @param service_index + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, + * ERROR_CODE_COMMAND_DISALLOWED if client is in wrong state, or + * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if no report with given type and ID is found. + */ +uint8_t hids_client_send_exit_suspend(uint16_t hids_cid, uint8_t service_index); + +/** + * @brief Enable all notifications. Event GATTSERVICE_SUBEVENT_HID_SERVICE_REPORTS_NOTIFICATION reports current configuration. + * + * @param hids_cid + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, or + * ERROR_CODE_COMMAND_DISALLOWED if client is in wrong state. + */ +uint8_t hids_client_enable_notifications(uint16_t hids_cid); + +/** + * @brief Disable all notifications. Event GATTSERVICE_SUBEVENT_HID_SERVICE_REPORTS_NOTIFICATION reports current configuration. + * + * @param hids_cid + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, or + * ERROR_CODE_COMMAND_DISALLOWED if client is in wrong state. + */ +uint8_t hids_client_disable_notifications(uint16_t hids_cid); + +/** + * @brief Disconnect from HID Service. + * + * @param hids_cid + * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER */ uint8_t hids_client_disconnect(uint16_t hids_cid); /* - * @brief Get descriptor data + * @brief Get descriptor data. For services in boot mode without a Report Map, a default HID Descriptor for Keyboard/Mouse is provided. + * * @param hid_cid - * @result data + * @return data */ const uint8_t * hids_client_descriptor_storage_get_descriptor_data(uint16_t hids_cid, uint8_t service_index); /* * @brief Get descriptor length + * * @param hid_cid - * @result length + * @return length */ uint16_t hids_client_descriptor_storage_get_descriptor_len(uint16_t hids_cid, uint8_t service_index); /** - * @brief De-initialize Battery Service. + * @brief De-initialize HID Service Client. + * */ void hids_client_deinit(void); diff --git a/test/pts/hog_host_test.c b/test/pts/hog_host_test.c index 2ac2e49ec..9df3db7d8 100644 --- a/test/pts/hog_host_test.c +++ b/test/pts/hog_host_test.c @@ -856,22 +856,22 @@ static void stdin_process(char character){ } case 'p':{ printf("Set Report protocol mode for service 0\n"); - hids_client_send_set_protocol_mode(hids_cid, protocol_mode, 0); + hids_client_send_set_protocol_mode(hids_cid, 0, protocol_mode); break; } case 'P':{ printf("Set Report protocol mode for service 0\n"); - hids_client_send_set_protocol_mode(hids_cid, protocol_mode, 1); + hids_client_send_set_protocol_mode(hids_cid, 1, protocol_mode); break; } case 'n':{ printf("Enable all notifications\n"); - hids_client_send_enable_notifications(hids_cid); + hids_client_enable_notifications(hids_cid); break; } case 'N':{ printf("Disable all notifications\n"); - hids_client_send_disable_notifications(hids_cid); + hids_client_disable_notifications(hids_cid); break; } case '\n':