From ae70b89347f47e6123a186f5d3a14d5858c6024c Mon Sep 17 00:00:00 2001 From: Wootak Jung Date: Thu, 6 Feb 2020 15:21:06 +0900 Subject: [PATCH] Add service removed event handling logic Remove removed service in list Change-Id: Ib6aab419ef4bd26a52a377a51b527852c8986e82 --- bt-oal/bluez_hal/inc/bt-hal-msg.h | 1 + bt-oal/bluez_hal/src/bt-hal-gatt-client.c | 34 +++++-- bt-oal/bluez_hal/src/bt-hal-gatt.c | 2 +- bt-oal/hardware/bt_gatt_client.h | 2 +- bt-oal/include/oal-event.h | 1 + bt-oal/oal-gatt.c | 5 +- .../services/gatt/bt-service-gatt.c | 111 +++++++++++++-------- 7 files changed, 101 insertions(+), 55 deletions(-) diff --git a/bt-oal/bluez_hal/inc/bt-hal-msg.h b/bt-oal/bluez_hal/inc/bt-hal-msg.h index 89302c5..1990673 100644 --- a/bt-oal/bluez_hal/inc/bt-hal-msg.h +++ b/bt-oal/bluez_hal/inc/bt-hal-msg.h @@ -804,6 +804,7 @@ struct hal_ev_dbfw_plus_info_recieved { #define HAL_EV_GATT_CLIENT_SERVICE_CHANGED 0xCF struct hal_ev_gatt_client_service_changed { + int32_t conn_id; uint8_t bdaddr[6]; uint8_t change_type; uint8_t uuid[16]; diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt-client.c b/bt-oal/bluez_hal/src/bt-hal-gatt-client.c index 4fced83..b3214ac 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-client.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-client.c @@ -123,6 +123,7 @@ typedef struct { typedef struct { bt_bdaddr_t bd_addr; /*remote server address*/ + int conn_id; int inst_id; /*server instance id*/ GSList *gatt_list_services; } hal_gattc_server_info_t; @@ -310,6 +311,7 @@ bt_status_t btif_gattc_add_connection_info(const bt_bdaddr_t *bd_addr, int conn_ if (server_info == NULL) { server_info = g_malloc0(sizeof(hal_gattc_server_info_t)); memcpy(server_info->bd_addr.address, bd_addr->address, BT_HAL_ADDRESS_LENGTH_MAX); + server_info->conn_id = conn_id; server_info->inst_id = server_inst_id; hal_gattc_server_info_list = g_slist_append(hal_gattc_server_info_list, server_info); DBG("Added server connection info in list"); @@ -775,6 +777,8 @@ static bt_status_t _gattc_client_search_service(int conn_id) return BT_STATUS_FAIL; } +#if 0 + // TODO: This logic is not able to handle in case service-added event is coming unexpectedly. /* Check the service info is stored */ if (g_slist_length(conn_info->gatt_list_services) > 0) { GSList *l = NULL; @@ -794,6 +798,7 @@ static bt_status_t _gattc_client_search_service(int conn_id) } else { DBG("No stored service, request to bluez"); } +#endif _bt_hal_convert_addr_type_to_string(device_address, (unsigned char *)conn_info->bd_addr.address); @@ -3487,6 +3492,7 @@ static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res, /*add gatt server connection info*/ gatt_conn_info = g_malloc0(sizeof(hal_gattc_server_info_t)); memcpy(gatt_conn_info->bd_addr.address, gattc_data->bd_addr.address, BT_HAL_ADDRESS_LENGTH_MAX); + gatt_conn_info->conn_id = gattc_data->conn_id; gatt_conn_info->inst_id = gattc_data->inst_id; hal_gattc_server_info_list = g_slist_append(hal_gattc_server_info_list, gatt_conn_info); @@ -3908,7 +3914,6 @@ void _bt_hal_handle_gattc_service_changed_event(gboolean is_added, const char *p _bt_hal_convert_device_path_to_address(path, address); _bt_hal_convert_addr_string_to_type(ev.bdaddr, address); - ev.change_type = is_added; server_info = __bt_find_gatt_conn_info((bt_bdaddr_t *)ev.bdaddr); if (server_info == NULL) { ERR("service_info is NULL"); @@ -3916,11 +3921,16 @@ void _bt_hal_handle_gattc_service_changed_event(gboolean is_added, const char *p } if (is_added) { + /* Get service UUID from path */ __bt_hal_gattc_get_uuid_from_path(path, &uuid_str); - DBG("GATT Service(%s) Added", uuid_str); - /* Set UUID by using path */ - _bt_hal_convert_uuid_string_to_type(ev.uuid, uuid_str); - g_free(uuid_str); + if (uuid_str) { + DBG("conn_id(%d) GATT Service(%s) Added", server_info->conn_id, uuid_str); + _bt_hal_convert_uuid_string_to_type(ev.uuid, uuid_str); + g_free(uuid_str); + } else { + ERR("uuid_str is NULL"); + return; + } /* Create new service and append into the list */ __hal_gattc_get_service_info(server_info, path); @@ -3934,10 +3944,8 @@ void _bt_hal_handle_gattc_service_changed_event(gboolean is_added, const char *p if (g_strcmp0(service->svc_path, path) == 0) { memcpy(ev.uuid, service->svc_uuid.uu, sizeof(bt_uuid_t)); uuid_str = g_malloc0(BT_HAL_UUID_STRING_LEN); - /* Set UUID from stored service info */ _bt_hal_convert_uuid_type_to_string(uuid_str, ev.uuid); - DBG("GATT Service(%s) Removed", uuid_str); - g_free(uuid_str); + DBG("conn_id(%d) GATT Service(%s) Removed", server_info->conn_id, uuid_str); /* Remove service info in list */ server_info->gatt_list_services = g_slist_remove(server_info->gatt_list_services, service); @@ -3945,9 +3953,17 @@ void _bt_hal_handle_gattc_service_changed_event(gboolean is_added, const char *p break; } } + + if (uuid_str) { + g_free(uuid_str); + } else { + ERR("uuid_str is NULL"); + return; + } } /* Send GATT Client service changed event */ + ev.change_type = is_added; + ev.conn_id = server_info->conn_id; event_cb(HAL_EV_GATT_CLIENT_SERVICE_CHANGED, (void *)&ev, sizeof(ev)); } - diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt.c b/bt-oal/bluez_hal/src/bt-hal-gatt.c index e80c9d7..20d68bd 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt.c @@ -689,7 +689,7 @@ static void __bt_hal_handle_gatt_client_service_changed(void *buf, uint16_t len) DBG("GATT Client service changed event received"); if (bt_gatt_callbacks->client->service_changed_cb) - bt_gatt_callbacks->client->service_changed_cb((bt_bdaddr_t *)ev->bdaddr, ev->change_type, ev->uuid); + bt_gatt_callbacks->client->service_changed_cb((bt_bdaddr_t *)ev->bdaddr, ev->change_type, ev->uuid, ev->conn_id); } static bt_hal_le_adv_info_t *__bt_hal_get_adv_ind_info(char *addr) diff --git a/bt-oal/hardware/bt_gatt_client.h b/bt-oal/hardware/bt_gatt_client.h index e7ac6c3..55c99d7 100644 --- a/bt-oal/hardware/bt_gatt_client.h +++ b/bt-oal/hardware/bt_gatt_client.h @@ -133,7 +133,7 @@ typedef void (*register_for_notification_callback)(int conn_id, typedef void (*notify_callback)(int conn_id, btgatt_notify_params_t *p_data); /** Registers service changed callback operation */ -typedef void (*service_changed_callback)(bt_bdaddr_t *bd_addr, int change_type, uint8_t *path); +typedef void (*service_changed_callback)(bt_bdaddr_t *bd_addr, int change_type, uint8_t *uuid, int conn_id); /** Reports result of a GATT read operation */ typedef void (*read_characteristic_callback)(int conn_id, int status, diff --git a/bt-oal/include/oal-event.h b/bt-oal/include/oal-event.h index 6a31cfe..0cc17d9 100644 --- a/bt-oal/include/oal-event.h +++ b/bt-oal/include/oal-event.h @@ -495,6 +495,7 @@ typedef struct { bt_address_t address; uint8_t change_type; oal_uuid_t uuid; + int conn_id; } event_gattc_service_changed_data; typedef struct { diff --git a/bt-oal/oal-gatt.c b/bt-oal/oal-gatt.c index 761ad37..af15692 100644 --- a/bt-oal/oal-gatt.c +++ b/bt-oal/oal-gatt.c @@ -213,7 +213,7 @@ static void cb_gattc_write_descriptor(int conn_id, int status, btgatt_write_para static void cb_gattc_register_for_notification(int conn_id, int registered, int status, btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id); static void cb_gattc_notify(int conn_id, btgatt_notify_params_t *p_data); -static void cb_gattc_service_changed(bt_bdaddr_t *bd_addr, int change_type, uint8_t *uuid); +static void cb_gattc_service_changed(bt_bdaddr_t *bd_addr, int change_type, uint8_t *uuid, int conn_id); static void cb_gattc_configure_mtu_cmpl(int conn_id, int status, int mtu); /*TODO GATT CLient callbacks will be implemented in subsequent patches */ @@ -1606,13 +1606,14 @@ static void cb_gattc_notify(int conn_id, btgatt_notify_params_t *p_data) } } -static void cb_gattc_service_changed(bt_bdaddr_t *bd_addr, int change_type, uint8_t *uuid) +static void cb_gattc_service_changed(bt_bdaddr_t *bd_addr, int change_type, uint8_t *uuid, int conn_id) { event_gattc_service_changed_data *event = g_new0(event_gattc_service_changed_data, 1); memcpy(event->address.addr, bd_addr->address, 6); event->change_type = change_type; memcpy(event->uuid.uuid, uuid, sizeof(event->uuid.uuid)); + event->conn_id = conn_id; send_event_bda_trace(OAL_EVENT_GATTC_SERVICE_CHANGED_IND, event, sizeof(*event), (bt_address_t *)bd_addr); } diff --git a/bt-service-adaptation/services/gatt/bt-service-gatt.c b/bt-service-adaptation/services/gatt/bt-service-gatt.c index f2b577c..2305b5d 100644 --- a/bt-service-adaptation/services/gatt/bt-service-gatt.c +++ b/bt-service-adaptation/services/gatt/bt-service-gatt.c @@ -238,6 +238,7 @@ static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att bluetooth_gatt_server_indication_params_t *param); static void __bt_remove_all_service_handles(int instance_id); +static void __bt_free_service_info(bt_gatt_service_info_t *service_info); #ifdef TIZEN_GATT_CLIENT static void __bt_handle_client_instance_registered(event_gattc_register_t *data); @@ -2877,20 +2878,50 @@ static void __bt_build_descriptor_browse_info(int conn_id, BT_INFO("Total descriptors browsed [%d]", count); } - -static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info) +static void __bt_free_service_info(bt_gatt_service_info_t *svc) { - GSList *l; - GSList *ll; - GSList *lll; - GSList *llll; - - bt_gatt_service_info_list_t * svc_info_list = NULL; - bt_gatt_service_info_t *svc = NULL; + GSList *ll, *lll, *llll; bt_gatt_char_info_t *chr = NULL; bt_gatt_descriptor_info_t *desc = NULL; bt_gatt_included_service_info_t *incl_svc = NULL; + BT_DBG("Service info Is Prim[%d] Inst ID [%d]", svc->is_primary, svc->inst_id); + /* Delete all chars and its descriptors */ + for (ll = svc->chars; ll != NULL; ) { + chr = (bt_gatt_char_info_t *)ll->data; + ll = g_slist_next(ll); + if (chr == NULL) + continue; + + for (lll = chr->descs; lll != NULL; ) { + desc = (bt_gatt_descriptor_info_t *)lll->data; + lll = g_slist_next(lll); + if (desc == NULL) + continue; + chr->descs = g_slist_remove(chr->descs, desc); + g_free(desc); + } + svc->chars = g_slist_remove(svc->chars, chr); + g_free(chr); + } + + /* Delete all included services */ + for (llll = svc->included_svcs; llll != NULL; ) { + incl_svc = (bt_gatt_included_service_info_t *)llll->data; + llll = g_slist_next(llll); + if (incl_svc == NULL) + continue; + svc->included_svcs = g_slist_remove(svc->included_svcs, incl_svc); + g_free(incl_svc); + } +} + +static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info) +{ + bt_gatt_service_info_list_t *svc_info_list = NULL; + bt_gatt_service_info_t *svc = NULL; + GSList *l; + svc_info_list = __bt_get_service_info_list(conn_info->connection_id); if (!svc_info_list) { BT_INFO("Could not find Svc Info list for the connection ID [%d]", @@ -2899,43 +2930,13 @@ static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info) } BT_INFO("Start Cleanup of all services. Num Services [%d]", g_slist_length(svc_info_list->services)); - for (l = svc_info_list->services; l;) { - svc = (bt_gatt_service_info_t*)l->data; + for (l = svc_info_list->services; l != NULL; ) { + svc = (bt_gatt_service_info_t *)l->data; l = g_slist_next(l); if (svc == NULL) continue; - BT_DBG("Service info Is Prim[%d] Inst ID [%d]", - svc->is_primary, svc->inst_id); - /* Delete all chars and its descriptors */ - for (ll = svc->chars; ll;) { - chr = (bt_gatt_char_info_t*)ll->data; - ll = g_slist_next(ll); - if (chr == NULL) - continue; - - for (lll = chr->descs; lll;) { - desc = (bt_gatt_descriptor_info_t *)lll->data; - lll = g_slist_next(lll); - if (desc == NULL) - continue; - chr->descs = g_slist_remove(chr->descs, desc); - g_free(desc); - } - svc->chars = g_slist_remove(svc->chars, chr); - g_free(chr); - } - - /* Delete all included services */ - for (llll = svc->included_svcs; llll;) { - incl_svc = (bt_gatt_included_service_info_t*)llll->data; - llll = g_slist_next(llll); - if (incl_svc == NULL) - continue; - - svc->included_svcs = g_slist_remove(svc->included_svcs, incl_svc); - g_free(incl_svc); - } + __bt_free_service_info(svc); svc_info_list->services = g_slist_remove(svc_info_list->services, svc); g_free(svc); } @@ -4074,10 +4075,34 @@ static void __bt_handle_client_notification_data(event_gattc_notify_data *event_ static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data) { + bt_gatt_service_info_list_t *svc_info_list; + GSList *l; + bt_gatt_service_info_t *svc_info; GVariant *param = NULL; char *address_str = NULL; char *uuid_str = NULL; + if (event_data->change_type == 0) { + svc_info_list = __bt_get_service_info_list(event_data->conn_id); + if (svc_info_list == NULL) { + BT_ERR("svc_info_list is NULL"); + return; + } + + /* Remove service UUID in list */ + for (l = svc_info_list->services; l != NULL; l = g_slist_next(l)) { + svc_info = (bt_gatt_service_info_t *)l->data; + if (svc_info == NULL) + continue; + + if (!memcmp(svc_info->uuid, event_data->uuid.uuid, BLUETOOTH_UUID_HEX_MAX_LEN)) { + svc_info_list->services = g_slist_remove(svc_info_list->services, svc_info); + __bt_free_service_info(svc_info); + break; + } + } + } + address_str = g_malloc0(BT_ADDRESS_STRING_SIZE); uuid_str = g_malloc0(BT_UUID_STRING_MAX); _bt_convert_addr_type_to_string(address_str, event_data->address.addr); @@ -4088,6 +4113,8 @@ static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_d _bt_send_event(BT_GATT_CLIENT_EVENT, BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED, param); + g_free(address_str); + g_free(uuid_str); } gboolean _bt_is_remote_gatt_device_connected(bluetooth_device_address_t *address) -- 2.7.4