aboutsummaryrefslogtreecommitdiff
path: root/src/ble/profile/client/dis_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ble/profile/client/dis_client.c')
-rw-r--r--src/ble/profile/client/dis_client.c825
1 files changed, 825 insertions, 0 deletions
diff --git a/src/ble/profile/client/dis_client.c b/src/ble/profile/client/dis_client.c
new file mode 100644
index 0000000..32d30a5
--- /dev/null
+++ b/src/ble/profile/client/dis_client.c
@@ -0,0 +1,825 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file dis_client.c
+ * @brief Dis BLE client source file.
+ * @details
+ * @author ken
+ * @date 2017-12-05
+ * @version v1.0
+ ******************************************************************************
+ */
+
+/** Add Includes here **/
+#include <trace.h>
+#include <string.h>
+#include <dis_client.h>
+#include <os_mem.h>
+
+/********************************************************************************************************
+* local static variables defined here, only used in this source file.
+********************************************************************************************************/
+
+typedef struct
+{
+ T_DIS_DISC_STATE disc_state;
+ uint16_t hdl_cache[HDL_DIS_CACHE_LEN];
+} T_DIS_LINK, *P_DIS_LINK;
+
+static P_DIS_LINK dis_table;
+static uint8_t dis_link_num;
+
+/**< dis client ID. */
+static T_CLIENT_ID dis_client = CLIENT_PROFILE_GENERAL_ID;
+/**< Callback used to send data to app from dis client layer. */
+static P_FUN_GENERAL_APP_CB dis_client_cb = NULL;
+
+/**
+ * @brief Used by application, to start the discovery procedure of lls server.
+ * @param[in] conn_id connection ID.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool dis_client_start_discovery(uint8_t conn_id)
+{
+ PROFILE_PRINT_INFO0("dis_client_start_discovery");
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_start_discovery: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ /* First clear handle cache. */
+ memset(&dis_table[conn_id], 0, sizeof(T_DIS_LINK));
+ dis_table[conn_id].disc_state = DISC_DIS_START;
+ if (client_by_uuid_srv_discovery(conn_id, dis_client,
+ GATT_UUID_DEVICE_INFORMATION_SERVICE) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using handles.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool dis_client_read_by_handle(uint8_t conn_id, T_DIS_READ_TYPE read_type)
+{
+ bool hdl_valid = false;
+ uint16_t handle;
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_read_by_handle: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case DIS_READ_SYSTEM_ID:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_SYSTEM_ID])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_SYSTEM_ID];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_MODEL_NUMBER:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_MODEL_NUMBER])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_MODEL_NUMBER];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_SERIAL_NUMBER:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_SERIAL_NUMBER])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_SERIAL_NUMBER];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_FIRMWARE_REVISION:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_FIRMWARE_REVISION])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_FIRMWARE_REVISION];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_HARDWARE_REVISION:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_HARDWARE_REVISION])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_HARDWARE_REVISION];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_SOFTWARE_REVISION:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_SOFTWARE_REVISION])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_SOFTWARE_REVISION];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_MANUFACTURER_NAME:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_MANUFACTURER_NAME])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_MANUFACTURER_NAME];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_IEEE_CERTIF_DATA_LIST:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST];
+ hdl_valid = true;
+ }
+ break;
+ case DIS_READ_PNP_ID:
+ if (dis_table[conn_id].hdl_cache[HDL_DIS_PNP_ID])
+ {
+ handle = dis_table[conn_id].hdl_cache[HDL_DIS_PNP_ID];
+ hdl_valid = true;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ if (hdl_valid)
+ {
+ if (client_attr_read(conn_id, dis_client, handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ }
+
+ APP_PRINT_WARN0("dis_client_read_by_handle: Request fail! Please check!");
+ return false;
+}
+
+/**
+ * @brief Used by application, to read data from server by using UUIDs.
+ * @param[in] conn_id connection ID.
+ * @param[in] read_type one of characteristic that has the readable property.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+bool dis_client_read_by_uuid(uint8_t conn_id,
+ T_DIS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint16_t uuid16;
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_read_by_uuid: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+
+ switch (read_type)
+ {
+ case DIS_READ_SYSTEM_ID:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_SYSTEM_ID;
+ break;
+ case DIS_READ_MODEL_NUMBER:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_MODEL_NUMBER;
+ break;
+ case DIS_READ_SERIAL_NUMBER:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_SERIAL_NUMBER;
+ break;
+ case DIS_READ_FIRMWARE_REVISION:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_FIRMWARE_REVISION;
+ break;
+ case DIS_READ_HARDWARE_REVISION:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_HARDWARE_REVISION;
+ break;
+ case DIS_READ_SOFTWARE_REVISION:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_SOFTWARE_REVISION;
+ break;
+ case DIS_READ_MANUFACTURER_NAME:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_MANUFACTURER_NAME;
+ break;
+ case DIS_READ_IEEE_CERTIF_DATA_LIST:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST;
+ break;
+ case DIS_READ_PNP_ID:
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ uuid16 = GATT_UUID_CHAR_PNP_ID;
+ break;
+
+ default:
+ return false;
+ }
+
+ if (client_attr_read_using_uuid(conn_id, dis_client, start_handle, end_handle,
+ uuid16, NULL) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+///**
+// * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic.
+// * @param[in] conn_id connection ID.
+// * @param[in] notify 0--disable the notification, 1--enable the notification.
+// * @retval true send request to upper stack success.
+// * @retval false send request to upper stack failed.
+// */
+//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify)
+//{
+// if (conn_id >= kns_link_num)
+// {
+// PROFILE_PRINT_ERROR1("kns_client_set_v3_notify: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD])
+// {
+// uint16_t handle = kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD];
+// uint16_t length = sizeof(uint16_t);
+// uint16_t cccd_bits = notify ? 1 : 0;
+// if (client_attr_write(conn_id, kns_client, GATT_WRITE_TYPE_REQ, handle,
+// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("kns_client_set_v3_notify: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] ind 0--disable the indication, 1--enable the indication.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind)
+//{
+// if (conn_id >= simp_link_num)
+// {
+// PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD])
+// {
+// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD];
+// uint16_t length = sizeof(uint16_t);
+// uint16_t cccd_bits = ind ? 2 : 0;
+// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle,
+// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to write data of write Characteristic.
+ * @param[in] conn_id connection ID.
+ * @param[in] length write data length
+ * @param[in] p_value point the value to write
+ * @param[in] type write type.
+ * @retval true send request to upper stack success.
+ * @retval false send request to upper stack failed.
+ */
+//bool lls_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value,
+// T_GATT_WRITE_TYPE type)
+//{
+// if (conn_id >= lls_link_num)
+// {
+// PROFILE_PRINT_ERROR1("lls_client_write_char: failed invalid conn_id %d", conn_id);
+// return false;
+// }
+
+// if (lls_table[conn_id].hdl_cache[HDL_LLS_PARA])
+// {
+// uint16_t handle = lls_table[conn_id].hdl_cache[HDL_LLS_PARA];
+// if (client_attr_write(conn_id, lls_client, type, handle,
+// length, p_value) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// }
+
+// APP_PRINT_WARN0("lls_ble_client_write_char: Request fail! Please check!");
+// return false;
+//}
+
+/**
+ * @brief Used by application, to get handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool dis_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_get_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (dis_table[conn_id].disc_state != DISC_DIS_DONE)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_get_hdl_cache: failed invalid state %d",
+ dis_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_DIS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_get_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(p_hdl_cache, dis_table[conn_id].hdl_cache, len);
+ return true;
+}
+
+/**
+ * @brief Used by application, to set handle cache.
+ * @param[in] conn_id connection ID.
+ * @param[in] p_hdl_cache pointer of the handle cache table
+ * @param[in] len the length of handle cache table
+ * @retval true success.
+ * @retval false failed.
+ */
+bool dis_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len)
+{
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_set_hdl_cache: failed invalid conn_id %d", conn_id);
+ return false;
+ }
+ if (dis_table[conn_id].disc_state != DISC_DIS_IDLE)
+ {
+ PROFILE_PRINT_ERROR1("lls_client_set_hdl_cache: failed invalid state %d",
+ dis_table[conn_id].disc_state);
+ return false;
+ }
+ if (len != sizeof(uint16_t) * HDL_DIS_CACHE_LEN)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_set_hdl_cache: failed invalid len %d", len);
+ return false;
+ }
+ memcpy(dis_table[conn_id].hdl_cache, p_hdl_cache, len);
+ dis_table[conn_id].disc_state = DISC_DIS_DONE;
+ return true;
+}
+
+static bool dis_client_start_char_discovery(uint8_t conn_id)
+{
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ APP_PRINT_INFO0("dis_client_start_ias_char_discovery");
+ start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START];
+ end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END];
+ if (client_all_char_discovery(conn_id, dis_client, start_handle,
+ end_handle) == GAP_CAUSE_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+
+//static bool lls_client_start_char_descriptor_discovery(uint8_t conn_id)
+//{
+// uint16_t start_handle;
+// uint16_t end_handle;
+
+// PROFILE_PRINT_INFO0("lls_client_start_char_descriptor_discovery");
+// start_handle = lls_table[conn_id].hdl_cache[HDL_LLS_NOTIFY_KEY];
+// end_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_END];
+// if (client_all_char_descriptor_discovery(conn_id, lls_client, start_handle,
+// end_handle) == GAP_CAUSE_SUCCESS)
+// {
+// return true;
+// }
+// return false;
+//}
+static void dis_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state)
+{
+ bool cb_flag = false;
+ T_DIS_CLIENT_CB_DATA cb_data;
+ cb_data.cb_type = DIS_CLIENT_CB_TYPE_DISC_STATE;
+
+ APP_PRINT_INFO1("dis_client_discover_state_cb: discovery_state %d", discovery_state);
+ if (dis_table[conn_id].disc_state == DISC_DIS_START)
+ {
+ uint16_t *hdl_cache;
+ hdl_cache = dis_table[conn_id].hdl_cache;
+
+ switch (discovery_state)
+ {
+ case DISC_STATE_SRV_DONE:
+ /* Indicate that service handle found. Start discover characteristic. */
+ if ((hdl_cache[HDL_DIS_SRV_START] != 0)
+ || (hdl_cache[HDL_DIS_SRV_END] != 0))
+ {
+ if (dis_client_start_char_discovery(conn_id) == false)
+ {
+ dis_table[conn_id].disc_state = DISC_DIS_FAILED;
+ cb_flag = true;
+ }
+ }
+ /* No Ias BLE service handle found. Discover procedure complete. */
+ else
+ {
+ dis_table[conn_id].disc_state = DISC_DIS_FAILED;
+ cb_flag = true;
+ }
+ break;
+ case DISC_STATE_CHAR_DONE:
+ dis_table[conn_id].disc_state = DISC_DIS_DONE;
+ cb_flag = true;
+ break;
+ case DISC_STATE_FAILED:
+ dis_table[conn_id].disc_state = DISC_DIS_FAILED;
+ cb_flag = true;
+ break;
+ default:
+ APP_PRINT_ERROR0("dis_handle_discover_state: Invalid Discovery State!");
+ break;
+ }
+ }
+
+ /* Send discover state to application if needed. */
+ if (cb_flag && dis_client_cb)
+ {
+ cb_data.cb_content.disc_state = dis_table[conn_id].disc_state;
+ (*dis_client_cb)(dis_client, conn_id, &cb_data);
+ }
+ return;
+}
+
+/**
+ * @brief Called by profile client layer, when discover result fetched.
+ * @param conn_id: connection ID.
+ * @param result_type: indicate which type of value discovered in service discovery procedure.
+ * @param result_data: value discovered.
+ * @retval None
+ */
+static void dis_client_discover_result_cb(uint8_t conn_id,
+ T_DISCOVERY_RESULT_TYPE result_type,
+ T_DISCOVERY_RESULT_DATA result_data)
+{
+ APP_PRINT_INFO1("dis_client_discover_result_cb: result_type %d", result_type);
+ if (dis_table[conn_id].disc_state == DISC_DIS_START)
+ {
+ uint16_t handle;
+ uint16_t *hdl_cache;
+ hdl_cache = dis_table[conn_id].hdl_cache;
+
+ switch (result_type)
+ {
+ case DISC_RESULT_SRV_DATA:
+ hdl_cache[HDL_DIS_SRV_START] = result_data.p_srv_disc_data->att_handle;
+ hdl_cache[HDL_DIS_SRV_END] = result_data.p_srv_disc_data->end_group_handle;
+ break;
+ case DISC_RESULT_CHAR_UUID128:
+ break;
+
+ case DISC_RESULT_CHAR_UUID16:
+ handle = result_data.p_char_uuid16_disc_data->value_handle;
+ switch (result_data.p_char_uuid16_disc_data->uuid16)
+ {
+ case GATT_UUID_CHAR_SYSTEM_ID:
+ hdl_cache[HDL_DIS_SYSTEM_ID] = handle;
+ break;
+ case GATT_UUID_CHAR_MODEL_NUMBER:
+ hdl_cache[HDL_DIS_MODEL_NUMBER] = handle;
+ break;
+ case GATT_UUID_CHAR_SERIAL_NUMBER:
+ hdl_cache[HDL_DIS_SERIAL_NUMBER] = handle;
+ break;
+ case GATT_UUID_CHAR_FIRMWARE_REVISION:
+ hdl_cache[HDL_DIS_FIRMWARE_REVISION] = handle;
+ break;
+ case GATT_UUID_CHAR_HARDWARE_REVISION:
+ hdl_cache[HDL_DIS_HARDWARE_REVISION] = handle;
+ break;
+ case GATT_UUID_CHAR_SOFTWARE_REVISION:
+ hdl_cache[HDL_DIS_SOFTWARE_REVISION] = handle;
+ break;
+ case GATT_UUID_CHAR_MANUFACTURER_NAME:
+ hdl_cache[HDL_DIS_MANUFACTURER_NAME] = handle;
+ break;
+ case GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST:
+ hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST] = handle;
+ break;
+ case GATT_UUID_CHAR_PNP_ID:
+ hdl_cache[HDL_DIS_PNP_ID] = handle;
+ break;
+ default:
+ /* have no interest on this handle. */
+ break;
+ }
+ break;
+
+ case DISC_RESULT_CHAR_DESC_UUID16:
+ /* When use client_all_char_descriptor_discovery. */
+ break;
+
+ default:
+ APP_PRINT_ERROR0("lls_handle_discover_result: Invalid Discovery Result Type!");
+ break;
+ }
+ }
+
+ return;
+}
+
+static void dis_client_read_result_cb(uint8_t conn_id, uint16_t cause,
+ uint16_t handle, uint16_t value_size, uint8_t *p_value)
+{
+ T_DIS_CLIENT_CB_DATA cb_data;
+ uint16_t *hdl_cache;
+ hdl_cache = dis_table[conn_id].hdl_cache;
+
+ cb_data.cb_type = DIS_CLIENT_CB_TYPE_READ_RESULT;
+
+ APP_PRINT_INFO2("dis_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+ cb_data.cb_content.read_result.cause = cause;
+
+ if (handle == hdl_cache[HDL_DIS_SYSTEM_ID])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_SYSTEM_ID;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_MODEL_NUMBER])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_MODEL_NUMBER;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_SERIAL_NUMBER])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_SERIAL_NUMBER;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_FIRMWARE_REVISION])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_FIRMWARE_REVISION;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_HARDWARE_REVISION])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_HARDWARE_REVISION;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_SOFTWARE_REVISION])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_SOFTWARE_REVISION;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_MANUFACTURER_NAME])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_MANUFACTURER_NAME;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_IEEE_CERTIF_DATA_LIST;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else if (handle == hdl_cache[HDL_DIS_PNP_ID])
+ {
+ cb_data.cb_content.read_result.type = DIS_READ_PNP_ID;
+ if (cause == GAP_SUCCESS)
+ {
+ cb_data.cb_content.read_result.data.v1_read.p_value = p_value;
+ cb_data.cb_content.read_result.data.v1_read.value_size = value_size;
+ }
+ else
+ {
+ cb_data.cb_content.read_result.data.v1_read.value_size = 0;
+ }
+ }
+ else
+ {
+ return;
+ }
+ /* Inform application the read result. */
+ if (dis_client_cb)
+ {
+ (*dis_client_cb)(dis_client, conn_id, &cb_data);
+ }
+
+ return;
+}
+
+//static void dis_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type,
+// uint16_t handle, uint16_t cause,
+// uint8_t credits)
+//{
+// T_LLS_CLIENT_CB_DATA cb_data;
+// uint16_t *hdl_cache;
+// hdl_cache = dis_table[conn_id].hdl_cache;
+// cb_data.cb_type = DIS_CLIENT_CB_TYPE_WRITE_RESULT;
+
+// PROFILE_PRINT_INFO2("dis_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause);
+// cb_data.cb_content.write_result.cause = cause;
+
+// if (handle == hdl_cache[HDL_DIS_PARA])
+// {
+// cb_data.cb_content.write_result.type = DIS_WRITE_PARA;
+// }
+// else
+// {
+// return;
+// }
+// /* Inform application the write result. */
+// if (dis_client_cb)
+// {
+// (*dis_client_cb)(lls_client, conn_id, &cb_data);
+// }
+
+// return;
+//}
+
+//static T_APP_RESULT lls_client_notif_ind_result_cb(uint8_t conn_id, bool notify,
+// uint16_t handle,
+// uint16_t value_size, uint8_t *p_value)
+//{
+// T_APP_RESULT app_result = APP_RESULT_SUCCESS;
+// T_KNS_CLIENT_CB_DATA cb_data;
+// uint16_t *hdl_cache;
+// hdl_cache = kns_table[conn_id].hdl_cache;
+
+// cb_data.cb_type = KNS_CLIENT_CB_TYPE_NOTIF_IND_RESULT;
+
+// if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY])
+// {
+// cb_data.cb_content.notif_ind_data.type = KNS_KEY_NOTIFY;
+// cb_data.cb_content.notif_ind_data.data.value_size = value_size;
+// cb_data.cb_content.notif_ind_data.data.p_value = p_value;
+// }
+// else
+// {
+// return app_result;
+// }
+// /* Inform application the notif/ind result. */
+// if (kns_client_cb)
+// {
+// app_result = (*kns_client_cb)(kns_client, conn_id, &cb_data);
+// }
+
+// return app_result;
+//}
+
+static void dis_client_disconnect_cb(uint8_t conn_id)
+{
+ APP_PRINT_INFO0("dis_client_disconnect_cb.");
+ if (conn_id >= dis_link_num)
+ {
+ PROFILE_PRINT_ERROR1("dis_client_disconnect_cb: failed invalid conn_id %d", conn_id);
+ return;
+ }
+ memset(&dis_table[conn_id], 0, sizeof(T_DIS_LINK));
+ return;
+}
+
+/**
+ * @brief Ias BLE Client Callbacks.
+*/
+const T_FUN_CLIENT_CBS dis_client_cbs =
+{
+ dis_client_discover_state_cb, //!< Discovery State callback function pointer
+ dis_client_discover_result_cb, //!< Discovery result callback function pointer
+ dis_client_read_result_cb, //!< Read response callback function pointer
+ NULL,//lls_client_write_result_cb, //!< Write result callback function pointer
+ NULL,//kns_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer
+ dis_client_disconnect_cb //!< Link disconnection callback function pointer
+};
+
+/**
+ * @brief Add dis service 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.
+ * @return Client ID of the specific client module.
+ * @retval 0xff failed.
+ * @retval other success.
+ *
+ * <b>Example usage</b>
+ * \code{.c}
+ void app_le_profile_init(void)
+ {
+ client_init(1);
+ dis_client_id = dis_ble_add_client(app_client_callback, APP_MAX_LINKS);
+ }
+ * \endcode
+ */
+T_CLIENT_ID dis_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num)
+{
+ uint16_t size;
+ if (link_num > DIS_MAX_LINKS)
+ {
+ PROFILE_PRINT_ERROR1("dis_add_client: invalid link_num %d", link_num);
+ return 0xff;
+ }
+ if (false == client_register_spec_client_cb(&dis_client, &dis_client_cbs))
+ {
+ dis_client = CLIENT_PROFILE_GENERAL_ID;
+ APP_PRINT_ERROR0("dis_add_client failed");
+ return dis_client;
+ }
+ APP_PRINT_INFO1("dis_add_client: dis_client %d", dis_client);
+
+ /* register callback for profile to inform application that some events happened. */
+ dis_client_cb = app_cb;
+ dis_link_num = link_num;
+ size = dis_link_num * sizeof(T_DIS_LINK);
+ dis_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size);
+
+ return dis_client;
+}
+