/** ***************************************************************************************** * Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. ***************************************************************************************** * @file gcs_client.h * @brief Head file for using General Common Services client. * @details General common services client data structs and external functions declaration. * @author jane * @date 2018-12-13 * @version v1.0 * ************************************************************************************* */ /* Define to prevent recursive inclusion */ #ifndef _GCS_CLIENT_H_ #define _GCS_CLIENT_H_ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Add Includes here */ #include /** @defgroup GCS_Client General Common Services Client * @brief GCS service client * @details Application shall register gcs client when initialization through @ref gcs_add_client function. * \code{.c} T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) { T_APP_RESULT result = APP_RESULT_SUCCESS; APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", client_id, conn_id); if (client_id == gcs_client_id) { T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; switch (p_gcs_cb_data->cb_type) { case GCS_CLIENT_CB_TYPE_DISC_RESULT: ...... } } * \endcode * @{ */ /** @defgroup GCS_Client_Exported_Macros GCS Client Exported Macros * @brief * @{ */ /** @brief Define maximum links number. range: 0-4 */ #define GCS_MAX_LINKS 4 /** End of GCS_Client_Exported_Macros * @} */ /** @defgroup GCS_Client_Exported_Types GCS Client Exported Types * @brief * @{ */ /** @brief Discovery result type.*/ typedef enum { GCS_ALL_PRIMARY_SRV_DISCOV, //!Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_gsrvdis(T_USER_CMD_PARSED_VALUE *p_parse_value) { uint8_t conn_id = p_parse_value->dw_param[0]; T_GAP_CAUSE cause = gcs_all_primary_srv_discovery(conn_id); return (T_USER_CMD_PARSE_RESULT)cause; } void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) { uint16_t i; T_GCS_DISCOV_RESULT *p_result_table; uint16_t properties; switch (discov_result.discov_type) { case GCS_ALL_PRIMARY_SRV_DISCOV: ...... } } * \endcode */ T_GAP_CAUSE gcs_all_primary_srv_discovery(uint8_t conn_id); /** * @brief Send discovery services by 128 bit UUID request. * @param[in] conn_id Connection ID * @param[in] p_uuid128 128 bit UUID. * @retval GAP_CAUSE_SUCCESS Discovery request success. * @retval other Discovery request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_srvuuid(T_USER_CMD_PARSED_VALUE *p_parse_value) { ...... cause = gcs_by_uuid128_srv_discovery(conn_id, uuid128); return (T_USER_CMD_PARSE_RESULT)cause; } void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) { uint16_t i; T_GCS_DISCOV_RESULT *p_result_table; uint16_t properties; switch (discov_result.discov_type) { case GCS_BY_UUID128_SRV_DISCOV: ...... } } * \endcode */ T_GAP_CAUSE gcs_by_uuid128_srv_discovery(uint8_t conn_id, uint8_t *p_uuid128); /** * @brief Send discovery services by 16 bit UUID request. * @param[in] conn_id Connection ID * @param[in] uuid16 16 bit UUID. * @retval GAP_CAUSE_SUCCESS Discovery request success. * @retval other Discovery request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_srvuuid(T_USER_CMD_PARSED_VALUE *p_parse_value) { ...... cause = gcs_by_uuid_srv_discovery(conn_id, uuid16); return (T_USER_CMD_PARSE_RESULT)cause; } void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) { uint16_t i; T_GCS_DISCOV_RESULT *p_result_table; uint16_t properties; switch (discov_result.discov_type) { case GCS_BY_UUID_SRV_DISCOV: ...... } } * \endcode */ T_GAP_CAUSE gcs_by_uuid_srv_discovery(uint8_t conn_id, uint16_t uuid16); /** * @brief Send discovery characteristics request. * @param[in] conn_id Connection ID * @param[in] start_handle Start handle of range to be searched. * @param[in] end_handle End handle of range to be searched. * @retval GAP_CAUSE_SUCCESS Discovery request success. * @retval other Discovery request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_chardis(T_USER_CMD_PARSED_VALUE *p_parse_value) { uint8_t conn_id = p_parse_value->dw_param[0]; uint16_t start_handle = p_parse_value->dw_param[1]; uint16_t end_handle = p_parse_value->dw_param[2]; T_GAP_CAUSE cause = gcs_all_char_discovery(conn_id, start_handle, end_handle); return (T_USER_CMD_PARSE_RESULT)cause; } void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) { uint16_t i; T_GCS_DISCOV_RESULT *p_result_table; uint16_t properties; switch (discov_result.discov_type) { case GCS_ALL_CHAR_DISCOV: ...... } } * \endcode */ T_GAP_CAUSE gcs_all_char_discovery(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle); /** * @brief Send discovery characteristics request by caracteristic uuid. * @param[in] conn_id Connection ID * @param[in] start_handle Start handle of range to be searched. * @param[in] end_handle End handle of range to be searched. * @param[in] uuid16 16bit characteristic uuid to be searched. * @retval GAP_CAUSE_SUCCESS Discovery request success. * @retval other Discovery request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_charuuid(T_USER_CMD_PARSED_VALUE *p_parse_value) { ...... T_GAP_CAUSE cause = gcs_by_uuid_char_discovery(conn_id, start_handle, end_handle, uuid16); return (T_USER_CMD_PARSE_RESULT)cause; } void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) { uint16_t i; T_GCS_DISCOV_RESULT *p_result_table; uint16_t properties; switch (discov_result.discov_type) { case GCS_BY_UUID_CHAR_DISCOV: ...... } } * \endcode */ T_GAP_CAUSE gcs_by_uuid_char_discovery(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16); /** * @brief Send discovery characteristics request by caracteristic uuid. * @param[in] conn_id Connection ID * @param[in] start_handle Start handle of range to be searched. * @param[in] end_handle End handle of range to be searched. * @param[in] p_uuid128 128bit characteristic uuid to be searched. * @retval GAP_CAUSE_SUCCESS Discovery request success. * @retval other Discovery request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_charuuid(T_USER_CMD_PARSED_VALUE *p_parse_value) { ...... T_GAP_CAUSE cause = gcs_by_uuid128_char_discovery(conn_id, start_handle, end_handle, uuid128); return (T_USER_CMD_PARSE_RESULT)cause; } void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) { uint16_t i; T_GCS_DISCOV_RESULT *p_result_table; uint16_t properties; switch (discov_result.discov_type) { case GCS_BY_UUID128_CHAR_DISCOV: ...... } } * \endcode */ T_GAP_CAUSE gcs_by_uuid128_char_discovery(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle, uint8_t *p_uuid128); /** * @brief Send discovery characteristics descriptor request. * @param[in] conn_id Connection ID * @param[in] start_handle Start handle of range to be searched. * @param[in] end_handle End handle of range to be searched. * @retval GAP_CAUSE_SUCCESS Discovery request success. * @retval other Discovery request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_charddis(T_USER_CMD_PARSED_VALUE *p_parse_value) { uint8_t conn_id = p_parse_value->dw_param[0]; uint16_t start_handle = p_parse_value->dw_param[1]; uint16_t end_handle = p_parse_value->dw_param[2]; T_GAP_CAUSE cause = gcs_all_char_descriptor_discovery(conn_id, start_handle, end_handle); return (T_USER_CMD_PARSE_RESULT)cause; } void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) { uint16_t i; T_GCS_DISCOV_RESULT *p_result_table; uint16_t properties; switch (discov_result.discov_type) { case GCS_ALL_CHAR_DESC_DISCOV: ...... } } * \endcode */ T_GAP_CAUSE gcs_all_char_descriptor_discovery(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle); /** * @brief Read characteristic by handle request. * @param[in] conn_id Connection ID * @param[in] handle Request handle. * @retval GAP_CAUSE_SUCCESS Read request success. * @retval other Read request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_read(T_USER_CMD_PARSED_VALUE *p_parse_value) { uint8_t conn_id = p_parse_value->dw_param[0]; uint16_t handle = p_parse_value->dw_param[1]; T_GAP_CAUSE cause = GAP_CAUSE_SUCCESS; if (p_parse_value->param_count <= 2) { cause = gcs_attr_read(conn_id, handle); } return (T_USER_CMD_PARSE_RESULT)cause; } T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) { T_APP_RESULT result = APP_RESULT_SUCCESS; APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", client_id, conn_id); if (client_id == gcs_client_id) { T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; switch (p_gcs_cb_data->cb_type) { case GCS_CLIENT_CB_TYPE_READ_RESULT: APP_PRINT_INFO3("READ RESULT: cause 0x%4x, handle 0x%4x, value_len %d", p_gcs_cb_data->cb_content.read_result.cause, p_gcs_cb_data->cb_content.read_result.handle, p_gcs_cb_data->cb_content.read_result.value_size); APP_PRINT_INFO1("READ VALUE: %b", TRACE_BINARY(p_gcs_cb_data->cb_content.read_result.value_size, p_gcs_cb_data->cb_content.read_result.p_value)); break; ...... } } return result; } * \endcode */ T_GAP_CAUSE gcs_attr_read(uint8_t conn_id, uint16_t handle); /** * @brief Read characteristic by 16 bit UUID request. * @param[in] conn_id Connection ID * @param[in] start_handle Start handle of range to be searched. * @param[in] end_handle End handle of range to be searched. * @param[in] uuid16 Request 16 bit UUID. * @retval GAP_CAUSE_SUCCESS Read request success. * @retval other Read request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_readu(T_USER_CMD_PARSED_VALUE *p_parse_value) { ...... cause = gcs_attr_read_using_uuid16(conn_id, start_handle, end_handle, uuid16); return (T_USER_CMD_PARSE_RESULT)cause; } T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) { T_APP_RESULT result = APP_RESULT_SUCCESS; APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", client_id, conn_id); if (client_id == gcs_client_id) { T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; switch (p_gcs_cb_data->cb_type) { case GCS_CLIENT_CB_TYPE_READ_RESULT: APP_PRINT_INFO3("READ RESULT: cause 0x%4x, handle 0x%4x, value_len %d", p_gcs_cb_data->cb_content.read_result.cause, p_gcs_cb_data->cb_content.read_result.handle, p_gcs_cb_data->cb_content.read_result.value_size); APP_PRINT_INFO1("READ VALUE: %b", TRACE_BINARY(p_gcs_cb_data->cb_content.read_result.value_size, p_gcs_cb_data->cb_content.read_result.p_value)); break; ...... } } return result; } * \endcode */ T_GAP_CAUSE gcs_attr_read_using_uuid16(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16); /** * @brief Read characteristic by 128 bit UUID request. * @param[in] conn_id Connection ID * @param[in] start_handle Start handle of range to be searched. * @param[in] end_handle End handle of range to be searched. * @param[in] p_uuid128 Request 128 bit UUID. * @retval GAP_CAUSE_SUCCESS Read request success. * @retval other Read request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_readu(T_USER_CMD_PARSED_VALUE *p_parse_value) { ...... cause = gcs_attr_read_using_uuid128(conn_id, start_handle, end_handle, uuid128); return (T_USER_CMD_PARSE_RESULT)cause; } T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) { T_APP_RESULT result = APP_RESULT_SUCCESS; APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", client_id, conn_id); if (client_id == gcs_client_id) { T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; switch (p_gcs_cb_data->cb_type) { case GCS_CLIENT_CB_TYPE_READ_RESULT: APP_PRINT_INFO3("READ RESULT: cause 0x%4x, handle 0x%4x, value_len %d", p_gcs_cb_data->cb_content.read_result.cause, p_gcs_cb_data->cb_content.read_result.handle, p_gcs_cb_data->cb_content.read_result.value_size); APP_PRINT_INFO1("READ VALUE: %b", TRACE_BINARY(p_gcs_cb_data->cb_content.read_result.value_size, p_gcs_cb_data->cb_content.read_result.p_value)); break; ...... } } return result; } * \endcode */ T_GAP_CAUSE gcs_attr_read_using_uuid128(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle, uint8_t *p_uuid128); /** * @brief Confirm from application when receive indication from server. * @param[in] conn_id Connection ID indicate which link is. * @retval GAP_CAUSE_SUCCESS: Success. * @retval other: Failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_indconf(T_USER_CMD_PARSED_VALUE *p_parse_value) { T_GAP_CAUSE ret; uint8_t conn_id = p_parse_value->dw_param[0]; ret = gcs_attr_ind_confirm(conn_id); return (T_USER_CMD_PARSE_RESULT)ret; } * \endcode */ T_GAP_CAUSE gcs_attr_ind_confirm(uint8_t conn_id); /** * @brief Write characteristic request. * @param[in] conn_id Connection ID * @param[in] write_type Type of write. * @param[in] handle Attribute handle. * @param[in] length Length of data to be written. If write_type is GATT_WRITE_TYPE_REQ, range of length is from 0 to 512. If write_type is GATT_WRITE_TYPE_CMD, range of length is from 0 to (mtu_size - 3). uint16_t mtu_size is acquired by le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id). * @param[in] p_data Point to the data to be written. * @retval GAP_CAUSE_SUCCESS: Write request success. * @retval other: Write request failed. * * Example usage * \code{.c} T_USER_CMD_PARSE_RESULT cmd_write(T_USER_CMD_PARSED_VALUE *p_parse_value) { ...... T_GAP_CAUSE ret = gcs_attr_write(conn_id, (T_GATT_WRITE_TYPE)write_type, handle, length, data); return (T_USER_CMD_PARSE_RESULT)ret; } T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) { T_APP_RESULT result = APP_RESULT_SUCCESS; APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", client_id, conn_id); if (client_id == gcs_client_id) { T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; switch (p_gcs_cb_data->cb_type) { case GCS_CLIENT_CB_TYPE_WRITE_RESULT: APP_PRINT_INFO3("WRITE RESULT: cause 0x%4x ,handle 0x%4x, type %d", p_gcs_cb_data->cb_content.write_result.cause, p_gcs_cb_data->cb_content.write_result.handle, p_gcs_cb_data->cb_content.write_result.type); break; ...... } } return result; } * \endcode */ T_GAP_CAUSE gcs_attr_write(uint8_t conn_id, T_GATT_WRITE_TYPE write_type, uint16_t handle, uint16_t length, uint8_t *p_data); /** * @brief Add general services client to application. * @param[in] app_cb pointer of app callback function to handle specific client module data. * @param[in] link_num initialize link num. * @param[in] config the discovery table number per link. * @return Client ID of the specific client module. * @retval 0xff failed. * @retval other success. * * Example usage * \code{.c} void app_le_profile_init(void) { client_init(1); gcs_client_id = gcs_add_client(gcs_client_callback, APP_MAX_LINKS, APP_MAX_DISCOV_TABLE_NUM); } * \endcode */ T_CLIENT_ID gcs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num, uint16_t max_discov_table_size); /** @} End of GCS_Client_Exported_Functions */ /** @} End of GCS_Client */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _GCS_CLIENT_H_ */