#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];
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;
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");
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;
} 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);
/*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);
_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");
}
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);
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);
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));
}
-
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)
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,
bt_address_t address;
uint8_t change_type;
oal_uuid_t uuid;
+ int conn_id;
} event_gattc_service_changed_data;
typedef struct {
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 */
}
}
-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);
}
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);
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]",
}
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);
}
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);
_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)