From d00f7817f1482294cbf28f64ba6e9e26041ef7eb Mon Sep 17 00:00:00 2001 From: Wootak Jung Date: Thu, 23 Jan 2020 17:18:32 +0900 Subject: [PATCH] Implement GATT Service changed event handling logic Add InterfacesRemoved event handling logic Add GattServiceAdded event handling logic Change-Id: If2eb2d582b00873a92f41f15266c78da311852ad --- bt-api/bt-event-handler.c | 22 +- bt-oal/bluez_hal/inc/bt-hal-msg.h | 9 +- bt-oal/bluez_hal/src/bt-hal-event-receiver.c | 43 +++- bt-oal/bluez_hal/src/bt-hal-gatt-client.c | 191 +++++++++++++++++- bt-oal/bluez_hal/src/bt-hal-gatt-client.h | 1 + bt-oal/bluez_hal/src/bt-hal-gatt.c | 15 ++ bt-oal/hardware/bt_gatt_client.h | 4 + bt-oal/include/oal-event.h | 6 + bt-oal/include/oal-gatt.h | 4 + bt-oal/oal-gatt.c | 12 ++ .../services/gatt/bt-service-gatt.c | 24 +++ include/bluetooth-api.h | 3 + include/bt-internal-types.h | 1 + 13 files changed, 321 insertions(+), 14 deletions(-) diff --git a/bt-api/bt-event-handler.c b/bt-api/bt-event-handler.c index 7223b57b..3342aed7 100644 --- a/bt-api/bt-event-handler.c +++ b/bt-api/bt-event-handler.c @@ -3823,8 +3823,28 @@ static void __bt_gatt_client_event_filter(GDBusConnection *connection, _bt_gatt_client_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC, result, &desc_prop, event_info->cb, event_info->user_data); - } + } else if (strcasecmp(signal_name, BT_GATT_CLIENT_SERVICE_CHANGED) == 0) { + BT_DBG("GATT Client event[BT_GATT_CLIENT_SERVICE_CHANGED]"); + bt_gatt_service_change_t change = {0, }; + char *address_str = NULL; + char *name = NULL; + + g_variant_get(parameters, "(i&s&s)", &change.change_type, &address_str, &change.uuid); + _bt_convert_addr_string_to_type(change.device_addr.addr, address_str); + bluetooth_get_uuid_name(change.uuid, &name); + BT_INFO(" ### GATT Service %s [%s]", change.change_type ? "Added" : "Removed", name); + g_free(name); + + if (_bluetooth_gatt_check_service_change_watcher_address(&change.device_addr) == FALSE) { + BT_INFO("No watcher for %s", address_str); + return; + } + + _bt_gatt_client_event_cb(BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED, + BLUETOOTH_ERROR_NONE, &change, + event_info->cb, event_info->user_data); + } } #endif diff --git a/bt-oal/bluez_hal/inc/bt-hal-msg.h b/bt-oal/bluez_hal/inc/bt-hal-msg.h index e7485d05..89302c59 100644 --- a/bt-oal/bluez_hal/inc/bt-hal-msg.h +++ b/bt-oal/bluez_hal/inc/bt-hal-msg.h @@ -802,7 +802,14 @@ struct hal_ev_dbfw_plus_info_recieved { uint32_t data_len; } __attribute__((packed)); -#define HAL_EV_GATT_CLIENT_MTU_EXCHANGE_COMPLETED 0xCF +#define HAL_EV_GATT_CLIENT_SERVICE_CHANGED 0xCF +struct hal_ev_gatt_client_service_changed { + uint8_t bdaddr[6]; + uint8_t change_type; + uint8_t uuid[16]; +} __attribute__((packed)); + +#define HAL_EV_GATT_CLIENT_MTU_EXCHANGE_COMPLETED 0xD0 struct hal_ev_gatt_client_mtu_exchange_completed { int32_t conn_id; int32_t mtu; diff --git a/bt-oal/bluez_hal/src/bt-hal-event-receiver.c b/bt-oal/bluez_hal/src/bt-hal-event-receiver.c index 492d5ac7..824a7ab6 100644 --- a/bt-oal/bluez_hal/src/bt-hal-event-receiver.c +++ b/bt-oal/bluez_hal/src/bt-hal-event-receiver.c @@ -1049,6 +1049,17 @@ void __bt_hal_handle_gatt_char_event(GVariant *parameters, const char *signal_na } } +static void __bt_hal_handle_gatt_service_event(GVariant *parameters, const char *signal_name) +{ + if (signal_name == NULL) + return; + + if (strcasecmp(signal_name, "GattServiceAdded") == 0) { + char *path = NULL; + g_variant_get(parameters, "(&s)", &path); + _bt_hal_handle_gattc_service_changed_event(TRUE, path); + } +} static gboolean __bt_hal_event_manager(gpointer data) { @@ -1092,6 +1103,8 @@ static gboolean __bt_hal_event_manager(gpointer data) while (g_variant_iter_loop(iter, "s", &str)) { if (g_strcmp0(str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) _bt_hal_remove_control_device_path(obj_path); + else if (g_strcmp0(str, BT_HAL_GATT_SERVICE_INTERFACE) == 0) + _bt_hal_handle_gattc_service_changed_event(FALSE, obj_path); } g_variant_iter_free(iter); } else if (strcasecmp(param->signal_name, "NameOwnerChanged") == 0) { @@ -1159,6 +1172,9 @@ static gboolean __bt_hal_event_manager(gpointer data) __bt_hal_handle_avrcp_transport_events(param->parameters, param->signal_name, param->object_path); } else if (g_strcmp0(param->interface_name, BT_HAL_GATT_CHAR_INTERFACE) == 0) { __bt_hal_handle_gatt_char_event(param->parameters, param->signal_name); + } else if (g_strcmp0(param->interface_name, BT_HAL_GATT_SERVICE_INTERFACE) == 0) { + DBG("Manager Event: Interface Name: BT_HAL_GATT_SERVICE_INTERFACE"); + __bt_hal_handle_gatt_service_event(param->parameters, param->signal_name); } /* Free data */ @@ -1409,23 +1425,34 @@ static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int s static int __bt_hal_register_gatt_subscribe_signal(GDBusConnection *conn, int subscribe) { - static int subs_gatt_id = -1; - - DBG("+"); + static int subs_gatt_char_id = -1; + static int subs_gatt_service_id = -1; if (subscribe) { - if (subs_gatt_id == -1) { - subs_gatt_id = g_dbus_connection_signal_subscribe(conn, + if (subs_gatt_char_id == -1) { + subs_gatt_char_id = g_dbus_connection_signal_subscribe(conn, NULL, BT_HAL_GATT_CHAR_INTERFACE, NULL, NULL, NULL, 0, __bt_hal_manager_event_filter, NULL, NULL); } + if (subs_gatt_service_id == -1) { + subs_gatt_service_id = g_dbus_connection_signal_subscribe(conn, + NULL, BT_HAL_GATT_SERVICE_INTERFACE, + NULL, NULL, NULL, 0, + __bt_hal_manager_event_filter, + NULL, NULL); + } } else { - if (subs_gatt_id == -1) { + if (subs_gatt_char_id == -1) { + g_dbus_connection_signal_unsubscribe(conn, + subs_gatt_char_id); + subs_gatt_char_id = -1; + } + if (subs_gatt_service_id == -1) { g_dbus_connection_signal_unsubscribe(conn, - subs_gatt_id); - subs_gatt_id = -1; + subs_gatt_service_id); + subs_gatt_service_id = -1; } } 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 f78b9751..88e27efc 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-client.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-client.c @@ -180,7 +180,7 @@ static hal_gattc_server_info_t *__bt_find_gatt_conn_info_from_conn_id(int conn_ static void _bt_hal_send_search_service_result_event(int conn_id, int is_primary, const char* uuid_str, int inst_id); static void _bt_hal_send_search_service_complete_event(int conn_id, int status); -static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr); +static hal_gattc_server_info_t *__bt_find_gatt_conn_info(const bt_bdaddr_t *serv_addr); static hal_gattc_client_info_t *__bt_find_gatt_client_info(bt_bdaddr_t *serv_addr); static hal_gattc_client_info_t *__bt_find_gatt_client_info_from_conn_id(int conn_id); @@ -615,7 +615,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, int is_primary) + const char *uuid_str, const char *object_path, int is_primary) { DBG("+"); hal_gattc_service_t *gattc_service = NULL; @@ -649,7 +649,7 @@ static void _hal_gattc_add_characteristic(hal_gattc_service_t *gatt_svc, char *c } static void _gattc_create_new_service(hal_gattc_server_info_t *conn_info, gboolean is_primary, - const char* uuid_str, char *object_path, GPtrArray *gp_char_array) + const char* uuid_str, const char *object_path, GPtrArray *gp_char_array) { hal_gattc_service_t* gatt_svc = NULL; int i; @@ -3295,7 +3295,7 @@ const btgatt_client_interface_t btgatt_client_interface = { .add_connection_info = btif_gattc_add_connection_info }; -static hal_gattc_server_info_t *__bt_find_gatt_conn_info(bt_bdaddr_t *serv_addr) +static hal_gattc_server_info_t *__bt_find_gatt_conn_info(const bt_bdaddr_t *serv_addr) { DBG("+"); @@ -3839,3 +3839,186 @@ void _bt_hal_handle_gattc_value_changed_event(int result, const char *char_handl } } } + +static bt_status_t __hal_gattc_get_service_info(hal_gattc_server_info_t *server_info, const char *service_path) +{ + GDBusConnection *g_conn = NULL; + GDBusProxy *properties_proxy = NULL; + GVariant *result = NULL; + GError *error = NULL; + GVariantIter *property_iter = NULL; + const gchar *key = NULL; + GVariant *value = NULL; + const char *uuid_str = NULL; + gsize len = 0; + gboolean is_primary = FALSE; + GVariantIter *char_iter = NULL; + const char *char_handle = NULL; + GPtrArray *gp_char_array = NULL; + + if (service_path == NULL) { + ERR("service_path is NULL"); + return BT_STATUS_FAIL; + } + + DBG("service_path: %s", service_path); + + g_conn = _bt_hal_get_system_gconn(); + if (g_conn == NULL) { + ERR("g_conn is NULL"); + return BT_STATUS_FAIL; + } + + properties_proxy = g_dbus_proxy_new_sync(g_conn, + G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_HAL_BLUEZ_NAME, + service_path, + BT_HAL_PROPERTIES_INTERFACE, + NULL, &error); + if (properties_proxy == NULL) { + ERR("properties_proxy is NULL"); + return BT_STATUS_FAIL; + } + + result = g_dbus_proxy_call_sync(properties_proxy, + "GetAll", + g_variant_new("(s)", BT_HAL_GATT_SERVICE_INTERFACE), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (result == NULL) { + if (error != NULL) { + ERR("Fail to get properties (Error: %s)", error->message); + g_clear_error(&error); + } else { + ERR("Fail to get properties"); + } + g_object_unref(properties_proxy); + return BT_STATUS_FAIL; + } + + g_variant_get(result, "(a{sv})", &property_iter); + + while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) { + if (g_strcmp0(key, "UUID") == 0) { + uuid_str = g_variant_get_string(value, &len); + DBG("UUID: %s", uuid_str); + } else if (g_strcmp0(key, "Primary") == 0) { + is_primary = g_variant_get_boolean(value); + DBG("is_primary: %s", is_primary ? "TRUE" : "FALSE"); + } else if (g_strcmp0(key, "Characteristics") == 0) { + g_variant_get(value, "ao", &char_iter); + if (char_iter != NULL) { + gp_char_array = g_ptr_array_new(); + while (g_variant_iter_loop(char_iter, "&o", &char_handle)) { + DBG("char_handle: %s", char_handle); + g_ptr_array_add(gp_char_array, (gpointer)char_handle); + } + } + } + } + + /* Create new service */ + _gattc_create_new_service(server_info, is_primary, uuid_str, service_path, gp_char_array); + + g_variant_iter_free(property_iter); + g_variant_unref(result); + g_object_unref(properties_proxy); + DBG("-"); + return BT_STATUS_SUCCESS; +} + +static void __bt_hal_gattc_get_uuid_from_path(const char *path, char **service_uuid) +{ + GDBusConnection *conn = NULL; + GDBusProxy *proxy = NULL; + GError *err = NULL; + GVariant *ret = NULL; + GVariant *value = NULL; + + conn = _bt_hal_get_system_gconn(); + if (conn == NULL) { + ERR("_bt_gdbus_get_system_gconn returned NULL"); + return; + } + + proxy = g_dbus_proxy_new_sync(conn, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, + BT_HAL_BLUEZ_NAME, path, BT_HAL_PROPERTIES_INTERFACE, NULL, &err); + if (proxy == NULL) { + ERR("device_proxy returned NULL"); + return; + } + + ret = g_dbus_proxy_call_sync(proxy, "Get", + g_variant_new("(ss)", BT_HAL_GATT_SERVICE_INTERFACE, "UUID"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + if (err) { + ERR("DBus Error : %s", err->message); + g_clear_error(&err); + } else { + g_variant_get(ret, "(v)", &value); + *service_uuid = g_variant_dup_string(value, NULL); + g_variant_unref(value); + g_variant_unref(ret); + } + + if (proxy) + g_object_unref(proxy); + + return; +} + +void _bt_hal_handle_gattc_service_changed_event(gboolean is_added, const char *path) +{ + struct hal_ev_gatt_client_service_changed ev = {0, }; + char address[BT_HAL_ADDRESS_STRING_SIZE]; + hal_gattc_server_info_t *server_info = NULL; + hal_gattc_service_t *service = NULL; + GSList *list = NULL; + char *uuid_str = NULL; + + _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"); + return; + } + + if (is_added) { + __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); + + /* Create new service and append into the list */ + __hal_gattc_get_service_info(server_info, path); + } else { + /* Find service UUID from path */ + for (list = server_info->gatt_list_services; list; list = g_slist_next(list)) { + service = (hal_gattc_service_t *)list->data; + if (service == NULL) + continue; + + 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); + + /* Remove service info in list */ + server_info->gatt_list_services = g_slist_remove(server_info->gatt_list_services, service); + __hal_gattc_free_svc_info(service); + break; + } + } + } + + /* Send GATT Client service changed event */ + event_cb(HAL_EV_GATT_CLIENT_SERVICE_CHANGED, (void *)&ev, sizeof(ev)); +} + diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt-client.h b/bt-oal/bluez_hal/src/bt-hal-gatt-client.h index e9ebf603..09b78ecb 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt-client.h +++ b/bt-oal/bluez_hal/src/bt-hal-gatt-client.h @@ -43,6 +43,7 @@ gboolean _bt_hal_check_gattc_is_existing(const char *address); void _bt_hal_handle_gattc_connected_event(char* address, gboolean connected); void _bt_hal_handle_gattc_value_changed_event(int result, const char *char_handle, char *char_value, int len); +void _bt_hal_handle_gattc_service_changed_event(gboolean is_added, const char *path); #ifdef TIZEN_BT_HAL int _bt_hal_gatt_client_get_le_scan_type(void); diff --git a/bt-oal/bluez_hal/src/bt-hal-gatt.c b/bt-oal/bluez_hal/src/bt-hal-gatt.c index f7316f91..af388a70 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gatt.c +++ b/bt-oal/bluez_hal/src/bt-hal-gatt.c @@ -85,6 +85,7 @@ static void __bt_handle_gatt_client_write_char(void *buf, uint16_t len); static void __bt_handle_gatt_client_write_desc(void *buf, uint16_t len); static void __bt_handle_gatt_client_watch_notification(void *buf, uint16_t len); static void __bt_handle_gatt_client_changed_value(void *buf, uint16_t len); +static void __bt_hal_handle_gatt_client_service_changed(void *buf, uint16_t len); static void __bt_hal_handle_gatt_client_mtu_exchange_completed(void *buf, uint16_t len); /*****************************************************************************************************/ @@ -415,6 +416,10 @@ static void __bt_hal_gatt_events(int message, void *buf, uint16_t len) __bt_handle_gatt_client_changed_value(buf, len); break; } + case HAL_EV_GATT_CLIENT_SERVICE_CHANGED: { + __bt_hal_handle_gatt_client_service_changed(buf, len); + break; + } case HAL_EV_GATT_SERVER_ACQUIRE_WRITE_RES:{ __bt_hal_handle_gatt_server_acquire_write_requested(buf, len); break; @@ -678,6 +683,16 @@ static void __bt_handle_gatt_client_changed_value(void *buf, uint16_t len) bt_gatt_callbacks->client->notify_cb(ev->conn_id, &changd_value_parm); } +static void __bt_hal_handle_gatt_client_service_changed(void *buf, uint16_t len) +{ + struct hal_ev_gatt_client_service_changed *ev = buf; + + 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); +} + static bt_hal_le_adv_info_t *__bt_hal_get_adv_ind_info(char *addr) { GSList *l; diff --git a/bt-oal/hardware/bt_gatt_client.h b/bt-oal/hardware/bt_gatt_client.h index 3c2ceb5f..e7ac6c3b 100644 --- a/bt-oal/hardware/bt_gatt_client.h +++ b/bt-oal/hardware/bt_gatt_client.h @@ -132,6 +132,9 @@ 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); + /** Reports result of a GATT read operation */ typedef void (*read_characteristic_callback)(int conn_id, int status, btgatt_read_params_t *p_data); @@ -203,6 +206,7 @@ typedef struct { get_included_service_callback get_included_service_cb; register_for_notification_callback register_for_notification_cb; notify_callback notify_cb; + service_changed_callback service_changed_cb; read_characteristic_callback read_characteristic_cb; write_characteristic_callback write_characteristic_cb; read_descriptor_callback read_descriptor_cb; diff --git a/bt-oal/include/oal-event.h b/bt-oal/include/oal-event.h index ca6bec55..6a31cfe0 100644 --- a/bt-oal/include/oal-event.h +++ b/bt-oal/include/oal-event.h @@ -491,6 +491,12 @@ typedef struct { oal_gatt_srvc_id_t srvc_id; } event_gattc_notify_data; +typedef struct { + bt_address_t address; + uint8_t change_type; + oal_uuid_t uuid; +} event_gattc_service_changed_data; + typedef struct { uint16_t value_type; uint16_t data_len; diff --git a/bt-oal/include/oal-gatt.h b/bt-oal/include/oal-gatt.h index 547ed1d2..06c4a8ee 100644 --- a/bt-oal/include/oal-gatt.h +++ b/bt-oal/include/oal-gatt.h @@ -510,6 +510,10 @@ oal_status_t gattc_register_scan_filter(oal_ble_scan_filter_t* filter_data); oal_status_t gattc_add_connection_info(bt_address_t *device_address, int conn_id, int server_inst_id); +oal_status_t gattc_register_service_changed_cb(bt_address_t *device_address); + +oal_status_t gattc_unregister_service_changed_cb(bt_address_t *device_address); + oal_status_t gattc_register_for_notification(int client_id, bt_address_t * address, oal_gatt_srvc_id_t *srvc_id, oal_gatt_id_t *char_id); diff --git a/bt-oal/oal-gatt.c b/bt-oal/oal-gatt.c index a6d14fe6..400f6623 100644 --- a/bt-oal/oal-gatt.c +++ b/bt-oal/oal-gatt.c @@ -213,6 +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_configure_mtu_cmpl(int conn_id, int status, int mtu); /*TODO GATT CLient callbacks will be implemented in subsequent patches */ @@ -228,6 +229,7 @@ static const btgatt_client_callbacks_t btgatt_client_callbacks = { .get_included_service_cb = NULL, .register_for_notification_cb = cb_gattc_register_for_notification, .notify_cb = cb_gattc_notify, + .service_changed_cb = cb_gattc_service_changed, .read_characteristic_cb = cb_gattc_read_characteristic, .write_characteristic_cb = cb_gattc_write_characteristic, .read_descriptor_cb = cb_gattc_read_descriptor, @@ -1617,6 +1619,16 @@ 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) +{ + 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)); + + send_event_bda_trace(OAL_EVENT_GATTC_SERVICE_CHANGED_IND, event, sizeof(*event), (bt_address_t *)bd_addr); +} static void cb_gattc_read_characteristic(int conn_id, int status, btgatt_read_params_t *p_data) { diff --git a/bt-service-adaptation/services/gatt/bt-service-gatt.c b/bt-service-adaptation/services/gatt/bt-service-gatt.c index ab061607..9cba6a0f 100644 --- a/bt-service-adaptation/services/gatt/bt-service-gatt.c +++ b/bt-service-adaptation/services/gatt/bt-service-gatt.c @@ -256,6 +256,7 @@ static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_d static void __bt_handle_client_notification_registered(event_gattc_regdereg_notify_t *event_data, gboolean is_registered); static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data); +static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data); static void __bt_handle_client_mtu_exchange_completed(event_gattc_mtu_configured_t *event_data); #endif @@ -2152,6 +2153,11 @@ static void __bt_gatt_event_handler(int event_type, gpointer event_data) __bt_handle_client_notification_data((event_gattc_notify_data *) event_data); break; } + case OAL_EVENT_GATTC_SERVICE_CHANGED_IND: { + BT_INFO("OAL Event: GATT Client service changed indication"); + __bt_handle_client_service_changed_ind((event_gattc_service_changed_data *)event_data); + break; + } case OAL_EVENT_GATTC_MTU_EXCHANGE_COMPLETED: { BT_INFO("OAL Event: GATT Client MTU Exchange Complete"); __bt_handle_client_mtu_exchange_completed((event_gattc_mtu_configured_t *) event_data); @@ -4060,6 +4066,24 @@ static void __bt_handle_client_notification_data(event_gattc_notify_data *event_ g_free(addr); } +static void __bt_handle_client_service_changed_ind(event_gattc_service_changed_data *event_data) +{ + GVariant *param = NULL; + char *address_str = NULL; + char *uuid_str = NULL; + + 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_uuid_to_string(&event_data->uuid, uuid_str); + + param = g_variant_new("(iss)", event_data->change_type, address_str, uuid_str); + + _bt_send_event(BT_GATT_CLIENT_EVENT, + BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED, + param); +} + gboolean _bt_is_remote_gatt_device_connected(bluetooth_device_address_t *address) { char *addr; diff --git a/include/bluetooth-api.h b/include/bluetooth-api.h index 774a4b85..5ce249fd 100644 --- a/include/bluetooth-api.h +++ b/include/bluetooth-api.h @@ -1715,6 +1715,9 @@ typedef struct { bluetooth_device_address_t device_addr; char *svc_path; bluetooth_gatt_service_change_type_t change_type; +#ifdef TIZEN_GATT_CLIENT + char *uuid; +#endif } bt_gatt_service_change_t; /** diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h index 1ad6d009..c055ded8 100644 --- a/include/bt-internal-types.h +++ b/include/bt-internal-types.h @@ -647,6 +647,7 @@ typedef struct { #define BT_GATT_CLIENT_WRITE_CHAR "GattWriteCharValue" #define BT_GATT_CLIENT_READ_DESC "GattReadDescriptor" #define BT_GATT_CLIENT_WRITE_DESC "GattWriteDescriptor" +#define BT_GATT_CLIENT_SERVICE_CHANGED "GattServiceChanged" #endif #define BT_GATT_REQ_ATT_MTU_CHANGED "GattReqAttMtuChanged" -- 2.34.1