Prevent Issue fixes
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-gatt-client.c
index 0bfd12d..cc5b5b8 100644 (file)
@@ -117,6 +117,7 @@ typedef struct {
 typedef struct {
        gchar *svc_path;
        bt_uuid_t svc_uuid;
+       int is_primary;
        GSList *gatt_list_chars;
 } hal_gattc_service_t;
 
@@ -565,6 +566,28 @@ static hal_gattc_char_t* _gattc_find_char_from_uuid(hal_gattc_service_t *gattc_s
        return NULL;
 }
 
+static hal_gattc_char_t* _gattc_find_char_from_uuid_for_notify(hal_gattc_service_t *gattc_svc, bt_uuid_t *char_uuid)
+{
+       DBG("+");
+
+       GSList *l;
+       hal_gattc_char_t *info = NULL;
+
+       for (l = gattc_svc->gatt_list_chars; l != NULL; l = g_slist_next(l)) {
+               info = (hal_gattc_char_t*)l->data;
+               if (info == NULL)
+                       continue;
+
+               if (!memcmp(&info->chr_uuid, char_uuid, sizeof(bt_uuid_t)) &&
+                       ((info->permission & HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) ||
+                               (info->permission & HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE))) {
+                       INFO("Found GATT char uuid");
+                       return info;
+               }
+       }
+       return NULL;
+}
+
 static hal_gattc_desc_t* _gattc_find_desc_from_uuid(hal_gattc_char_t *gattc_char, bt_uuid_t *desc_uuid)
 {
        DBG("+");
@@ -587,7 +610,7 @@ static hal_gattc_desc_t* _gattc_find_desc_from_uuid(hal_gattc_char_t *gattc_char
 
 
 static hal_gattc_service_t* _hal_gatt_client_add_service(hal_gattc_server_info_t *conn_info,
-               const char *uuid_str, char *object_path)
+               const char *uuid_str, char *object_path, int is_primary)
 {
        DBG("+");
        hal_gattc_service_t *gattc_service = NULL;
@@ -595,6 +618,7 @@ static hal_gattc_service_t* _hal_gatt_client_add_service(hal_gattc_server_info_t
        gattc_service = g_malloc0(sizeof(hal_gattc_service_t));
        gattc_service->svc_path = g_strdup(object_path);
        _bt_hal_convert_uuid_string_to_type(gattc_service->svc_uuid.uu, uuid_str);
+       gattc_service->is_primary = is_primary;
 
        DBG("service count[%d]", g_slist_length(conn_info->gatt_list_services));
 
@@ -629,7 +653,7 @@ static void _gattc_create_new_service(hal_gattc_server_info_t *conn_info, gboole
        DBG("+");
 
        /* add the service */
-       gatt_svc = _hal_gatt_client_add_service(conn_info, uuid_str, object_path);
+       gatt_svc = _hal_gatt_client_add_service(conn_info, uuid_str, object_path, is_primary);
        if (gatt_svc == NULL) {
                ERR("Failed to add service");
                return;
@@ -2406,8 +2430,7 @@ static bt_status_t _hal_register_for_notification(int client_if,
 
 
        /* find characteristic */
-       gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid,
-                       HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY);
+       gattc_char = _gattc_find_char_from_uuid_for_notify(gattc_service, &char_id->uuid);
        if (NULL == gattc_char) {
                DBG("Failed to get the gatt char");
                return BT_STATUS_FAIL;
@@ -2572,8 +2595,7 @@ static bt_status_t _hal_deregister_for_notification(int client_if,
 
 
        /* find characteristic */
-       gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid,
-                       HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY);
+       gattc_char = _gattc_find_char_from_uuid_for_notify(gattc_service, &char_id->uuid);
        if (NULL == gattc_char) {
                DBG("Failed to get the gatt char");
                return BT_STATUS_FAIL;
@@ -2832,40 +2854,40 @@ bt_status_t batchscan_read_reports(int client_if, int scan_mode)
 }
 
 const btgatt_client_interface_t btgatt_client_interface = {
-       btif_gattc_register_client,
-       btif_gattc_unregister_client,
-       scan,
-       btif_gattc_client_connect,
-       btif_gattc_client_disconnect,
-       refresh,
-       btif_gattc_client_search_service,
-       get_included_service,
-       btif_gattc_get_characteristic,
-       btif_gattc_get_descriptor,
-       btif_read_characteristic,
-       btif_write_characteristic,
-       btif_get_acquire_write_fd,
-       btif_get_acquire_notify_fd,
-       btif_read_descriptor,
-       btif_write_descriptor,
-       execute_write,
-       btif_register_for_notification,
-       btif_deregister_for_notification,
-       read_remote_rssi,
-       ota_fw_update,
-       get_device_type,
-       btif_gattc_conn_parameter_update,
-       test_command,
-       configure_mtu,
-       scan_filter_param_setup,
-       scan_filter_add_remove,
-       scan_filter_clear,
-       scan_filter_enable,
-       set_scan_parameters,
-       batchscan_cfg_storage,
-       batchscan_enb_batch_scan,
-       batchscan_dis_batch_scan,
-       batchscan_read_reports
+       .register_client = btif_gattc_register_client,
+       .unregister_client = btif_gattc_unregister_client,
+       .scan = scan,
+       .connect = btif_gattc_client_connect,
+       .disconnect = btif_gattc_client_disconnect,
+       .refresh = refresh,
+       .search_service = btif_gattc_client_search_service,
+       .get_included_service = get_included_service,
+       .get_characteristic = btif_gattc_get_characteristic,
+       .get_descriptor = btif_gattc_get_descriptor,
+       .read_characteristic = btif_read_characteristic,
+       .write_characteristic = btif_write_characteristic,
+       .acquire_write = btif_get_acquire_write_fd,
+       .acquire_notify = btif_get_acquire_notify_fd,
+       .read_descriptor = btif_read_descriptor,
+       .write_descriptor = btif_write_descriptor,
+       .execute_write = execute_write,
+       .register_for_notification = btif_register_for_notification,
+       .deregister_for_notification = btif_deregister_for_notification,
+       .read_remote_rssi = read_remote_rssi,
+       .ota_fw_update = ota_fw_update,
+       .get_device_type = get_device_type,
+       .conn_parameter_update = btif_gattc_conn_parameter_update,
+       .test_command = test_command,
+       .configure_mtu = configure_mtu,
+       .scan_filter_param_setup = scan_filter_param_setup,
+       .scan_filter_add_remove = scan_filter_add_remove,
+       .scan_filter_clear = scan_filter_clear,
+       .scan_filter_enable = scan_filter_enable,
+       .set_scan_parameters = set_scan_parameters,
+       .batchscan_cfg_storage = batchscan_cfg_storage,
+       .batchscan_enb_batch_scan = batchscan_enb_batch_scan,
+       .batchscan_dis_batch_scan = batchscan_dis_batch_scan,
+       .batchscan_read_reports = batchscan_read_reports
 };
 
 static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr)
@@ -3339,3 +3361,88 @@ static void _bt_hal_send_search_service_complete_event(int conn_id, int status)
 
        event_cb(HAL_EV_GATT_CLIENT_SEARCH_COMPLETE, (void *)&ev, sizeof(ev));
 }
+
+static void _bt_hal_send_value_changed_event(hal_gattc_server_info_t *conn_info,
+               hal_gattc_service_t *svc_info, hal_gattc_char_t *char_info,
+               char *char_value, int len)
+{
+       struct hal_ev_gatt_client_notify_changed_value ev;
+       hal_gattc_client_info_t *gattc_client = NULL;
+
+       if (!event_cb) {
+               ERR("gatt client callback not registered");
+               return;
+       }
+
+       gattc_client = __bt_find_gatt_client_info(&conn_info->bd_addr);
+       if (NULL == gattc_client) {
+               ERR("failed to get the gatt client info");
+               return ;
+       }
+
+       //send event
+       DBG("sending gatt client connected status  event");
+       memset(&ev, 0, sizeof(ev));
+
+       ev.conn_id = gattc_client->conn_id;
+       ev.inst_id = conn_info->inst_id;
+       ev.is_primary = svc_info->is_primary;
+       memcpy(ev.svc_uuid, svc_info->svc_uuid.uu, sizeof(ev.svc_uuid));
+       memcpy(ev.char_uuid, char_info->chr_uuid.uu, sizeof(ev.char_uuid));
+
+       memcpy(ev.bdaddr, conn_info->bd_addr.address, BT_HAL_ADDRESS_LENGTH_MAX);
+
+       if (len > 0 && (char_value != NULL)) {
+               memcpy(ev.value, char_value, len);
+               ev.len = len;
+       }
+
+       event_cb(HAL_EV_GATT_CLIENT_NOTIFY_CHANGED_VALUE, (void *)&ev, sizeof(ev));
+}
+
+void _bt_hal_handle_gattc_value_changed_event(int result, const char *char_handle,
+                                               char *char_value, int len)
+{
+       char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
+       hal_gattc_server_info_t *conn_info = NULL;
+       bt_bdaddr_t bd_addr;
+       GSList *l;
+       GSList *k;
+       hal_gattc_service_t *svc_info = NULL;
+       hal_gattc_char_t *char_info = NULL;
+
+       DBG("+");
+
+       _bt_hal_convert_device_path_to_address(char_handle, device_address);
+       device_address[BT_HAL_ADDRESS_STRING_SIZE - 1] = '\0';
+       DBG("device address:[%s]", device_address);
+       DBG("char handle:[%s]", char_handle);
+
+       _bt_hal_convert_addr_string_to_type(bd_addr.address, device_address);
+       conn_info =  __bt_find_gatt_conn_info(&bd_addr);
+
+       if (conn_info != NULL) {
+               //find service for notified char path
+               for (l = conn_info->gatt_list_services; l != NULL; l = g_slist_next(l)) {
+                       svc_info = (hal_gattc_service_t*)l->data;
+                       if (svc_info == NULL)
+                               continue;
+
+                       /* find characteristic object path */
+                       for (k = svc_info->gatt_list_chars; k != NULL; k = g_slist_next(k)) {
+                               char_info = (hal_gattc_char_t *)k->data;
+                               if (char_info == NULL)
+                                       continue;
+
+                               if (g_strcmp0(char_info->chr_path, char_handle) == 0) {
+                                       DBG("Found char handle[%s]", char_info->chr_path);
+
+                                       //send event
+                                       _bt_hal_send_value_changed_event(conn_info, svc_info,
+                                                       char_info, char_value, len);
+                                       return;
+                               }
+                       }
+               }
+       }
+}