Merge "Specify the sender(org.bluez or org.bluez.obex) on subscribe to receive only...
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-gatt-service.c
index 1d30065..2bcbb9f 100644 (file)
@@ -155,15 +155,15 @@ int bluetooth_gatt_convert_perm2string(
 
 #define NUMBER_OF_FLAGS        10
 
-GDBusConnection *g_conn;
-guint owner_id;
-guint manager_id;
+static GDBusConnection *g_conn;
+static guint owner_id;
+static guint manager_id;
 static gboolean new_service = FALSE;
 static gboolean new_char = FALSE;
 static int serv_id = 1;
 static bool is_server_started = false;
 
-GCancellable *register_cancel;
+static GCancellable *register_cancel;
 
 /* Introspection data for the service we are exporting */
 static const gchar service_introspection_xml[] =
@@ -391,19 +391,31 @@ static void bluetooth_characteristic_info_free(bluetooth_gatt_acquire_notify_inf
 static gboolean bluetooth_gatt_write_channel_watch_cb(GIOChannel *gio,
                                        GIOCondition cond, gpointer data)
 {
+       BT_INFO("+");
+
        bluetooth_gatt_acquire_notify_info_t *chr_info = (bluetooth_gatt_acquire_notify_info_t *)data;
 
-       if (!chr_info)
+       if (!chr_info) {
+               BT_INFO("chr_info is NULL");
                return FALSE;
+       }
 
        if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
                BT_ERR("Error : GIOCondition %d, []", cond);;
                g_io_channel_shutdown(gio, TRUE, NULL);
                g_io_channel_unref(gio);
 
-               gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
-               bluetooth_characteristic_info_free(chr_info);
+               if (g_slist_find(gatt_characteristic_server_notify_list, chr_info)) {
+                       BT_INFO("found char_info in the list");
+                       gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
+                       bluetooth_characteristic_info_free(chr_info);
+               }
+
+               return FALSE;
+       }
 
+       if (g_slist_find(gatt_characteristic_server_notify_list, chr_info) == NULL) {
+               BT_INFO("chr_info is not in the list");
                return FALSE;
        }
 
@@ -430,34 +442,6 @@ static int bluetooth_gatt_write_characteristics_value_to_fd_(
                return att_result;
 }
 
-static void __bt_gatt_close_gdbus_connection(void)
-{
-       GError *err = NULL;
-
-       BT_DBG("+");
-
-       ret_if(g_conn == NULL);
-
-       if (!g_dbus_connection_flush_sync(g_conn, NULL, &err)) {
-               BT_ERR("Fail to flush the connection: %s", err->message);
-               g_error_free(err);
-               err = NULL;
-       }
-
-       if (!g_dbus_connection_close_sync(g_conn, NULL, &err)) {
-               if (err) {
-                       BT_ERR("Fail to close the dbus connection: %s", err->message);
-                       g_error_free(err);
-               }
-       }
-
-       g_object_unref(g_conn);
-
-       g_conn = NULL;
-
-       BT_DBG("-");
-}
-
 #ifdef TIZEN_FEATURE_BT_HPS
 static int __bt_send_event_to_hps(int event, GVariant *var)
 {
@@ -1427,15 +1411,9 @@ static GDBusProxy *__bt_gatt_gdbus_init_manager_proxy(const gchar *service,
        GDBusProxy *proxy;
        GError *err = NULL;
 
-       if (g_conn == NULL)
-               g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM,
-                                                       NULL, &err);
-
+       g_conn = _bt_get_system_shared_conn();
        if (!g_conn) {
-               if (err) {
-                       BT_ERR("Unable to connect to gdbus: %s", err->message);
-                       g_clear_error(&err);
-               }
+               BT_ERR("Unable to get connection");
                return NULL;
        }
 
@@ -1588,12 +1566,18 @@ BT_EXPORT_API int bluetooth_gatt_unregister_application(void)
                        if (err != NULL) {
                                BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
                                                err->code, err->message);
+                               if (err->code == G_DBUS_ERROR_SERVICE_UNKNOWN ||
+                                       g_strrstr(err->message, BT_ERROR_DOES_NOT_EXIST)) {
+                                       g_clear_error(&err);
+                                       goto done;
+                               }
                                g_clear_error(&err);
                        }
                        return BLUETOOTH_ERROR_INTERNAL;
                }
                g_variant_unref(ret);
 
+done:
                is_server_started = false;
 
                BT_INFO("UnregisterApplication is completed");
@@ -1605,67 +1589,8 @@ BT_EXPORT_API int bluetooth_gatt_unregister_application(void)
        return BLUETOOTH_ERROR_NONE;
 }
 
-static GDBusConnection *__bt_gatt_get_gdbus_connection(void)
-{
-       GDBusConnection *local_system_gconn = NULL;
-       char *address;
-       GError *err = NULL;
-
-       if (g_conn == NULL) {
-               address = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
-               if (address == NULL) {
-                       if (err) {
-                               BT_ERR("Failed to get bus address: %s", err->message);
-                               g_clear_error(&err);
-                       }
-                       return NULL;
-               }
-
-               g_conn = g_dbus_connection_new_for_address_sync(address,
-                                       G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
-                                       G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
-                                       NULL, /* GDBusAuthObserver */
-                                       NULL,
-                                       &err);
-               g_free(address);
-               if (!g_conn) {
-                       if (err) {
-                               BT_ERR("Unable to connect to dbus: %s", err->message);
-                               g_clear_error(&err);
-                       }
-                       return NULL;
-               }
-       } else if (g_dbus_connection_is_closed(g_conn)) {
-               address = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
-               if (address == NULL) {
-                       if (err) {
-                               BT_ERR("Failed to get bus address: %s", err->message);
-                               g_clear_error(&err);
-                       }
-                       return NULL;
-               }
-
-               local_system_gconn = g_dbus_connection_new_for_address_sync(address,
-                                       G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
-                                       G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
-                                       NULL, /* GDBusAuthObserver */
-                                       NULL,
-                                       &err);
-               g_free(address);
-               if (!local_system_gconn) {
-                       BT_ERR("Unable to connect to dbus: %s", err->message);
-                       g_clear_error(&err);
-               }
-
-               g_conn = local_system_gconn;
-       }
-
-       return g_conn;
-}
-
 BT_EXPORT_API int bluetooth_gatt_init(void)
 {
-       GDBusConnection *conn;
        GError *error = NULL;
        GDBusNodeInfo *node_info = NULL;
 
@@ -1674,24 +1599,27 @@ BT_EXPORT_API int bluetooth_gatt_init(void)
                return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
        }
 
+       g_conn = _bt_get_system_shared_conn();
+       if (!g_conn) {
+               BT_ERR("Unable to get connection");
+               goto failed;
+       }
+
        if (owner_id == 0) {
-               owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
-                                       BT_GATT_SERVICE_NAME,
+               gchar *name = g_strdup_printf("%s.p%d", BT_GATT_SERVICE_NAME, getpid());
+               BT_DBG("well-known name: %s", name);
+
+               owner_id = g_bus_own_name_on_connection(g_conn, name,
                                        G_BUS_NAME_OWNER_FLAGS_NONE,
-                                       NULL, NULL, NULL, NULL, NULL);
+                                       NULL, NULL, NULL, NULL);
+               g_free(name);
        }
-
        BT_DBG("owner_id is [%d]", owner_id);
+
        app_path = g_strdup_printf("/com/%d", getpid());
 
        serv_id = 1;
 
-       conn = __bt_gatt_get_gdbus_connection();
-       if (!conn) {
-               BT_ERR("Unable to get connection");
-               goto failed;
-       }
-
        /* Register ObjectManager interface */
        node_info = __bt_gatt_create_method_node_info(
                                        manager_introspection_xml);
@@ -1726,8 +1654,6 @@ failed:
        app_path = NULL;
        owner_id = 0;
 
-       __bt_gatt_close_gdbus_connection();
-
        return BLUETOOTH_ERROR_INTERNAL;
 }
 
@@ -1743,7 +1669,6 @@ BT_EXPORT_API int bluetooth_gatt_deinit()
 
        if (owner_id == 0) {
                BT_ERR("owner_id is zero");
-               __bt_gatt_close_gdbus_connection();
                return BLUETOOTH_ERROR_NOT_FOUND;
        }
 
@@ -1772,8 +1697,6 @@ BT_EXPORT_API int bluetooth_gatt_deinit()
                manager_gproxy = NULL;
        }
 
-       __bt_gatt_close_gdbus_connection();
-
        BT_DBG("-");
        return ret;
 }
@@ -2906,12 +2829,8 @@ BT_EXPORT_API int bluetooth_gatt_server_add_new_characteristic(const char *char_
 
        int result;
        char uuid[BT_GATT_ATT_UUID_LEN_MAX + 1];
-       int flag_count = 0;
-       char *char_flags[NUMBER_OF_FLAGS];
 
        g_strlcpy(uuid, char_uuid, sizeof(uuid));
-       flag_count = bluetooth_gatt_convert_prop2string(param->properties, char_flags);
-       BT_INFO("Flag count [%d]", flag_count);
 
        BT_INIT_PARAMS();
        BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
@@ -3302,7 +3221,7 @@ void  bluetooth_gatt_server_send_acquire_write_response(GVariant * parameters)
 
 
 
-void  bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters)
+void  bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters, bt_event_info_t *event_info)
 {
                        int con_id  =  -1;
                        int tran_id  =  -1;
@@ -3315,18 +3234,21 @@ void  bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters)
                        int result =  -1;
                        int fd = -1;
                        bluetooth_gatt_acquire_notify_info_t *chr_info;
+                       const char *address = NULL;
 
-                       g_variant_get(parameters, "(iiiiii)",
+                       g_variant_get(parameters, "(iiiiiis)",
                                                        &result,
                                                        &con_id,
                                                        &tran_id,
                                                        &att_han,
                                                        &mtu,
-                                                       &offset);
+                                                       &offset,
+                                                       &address);
 
                                BT_DBG("GATT ServerAcquire  Conn ID:   [%d]", con_id);
                                BT_DBG("GATT Server Acquire notify  att handle:[%d]", att_han);
                                BT_DBG("GATT Server Acquire Notify Offset:    [%d]", offset);
+                               BT_DBG("GATT Server Acquire Notify address:    [%s]", address);
 
 
                        if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd) < 0) {
@@ -3360,6 +3282,7 @@ void  bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters)
                                        chr_info->write_fd = fd;
 
 
+                               BT_INFO("setting up g_io channel");
                                channel = g_io_channel_unix_new(fd);
                                g_io_channel_set_encoding(channel, NULL, NULL);
                                g_io_channel_set_buffered(channel, FALSE);
@@ -3387,4 +3310,47 @@ void  bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters)
 
                                BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
 
+
+                               //send
+                               if (result == BLUETOOTH_ERROR_NONE) {
+
+                                       BT_INFO("sending gatt server notification state changed event");
+                                       bluetooth_gatt_server_notification_changed_t info;
+                                       bluetooth_device_address_t dev_address = { {0} };
+                                       memset(&info, 0x00, sizeof(bluetooth_gatt_server_notification_changed_t));
+
+                                       _bt_convert_addr_string_to_type(dev_address.addr, address);
+                                       memcpy(info.device_address.addr,
+                                                       dev_address.addr,
+                                                       BLUETOOTH_ADDRESS_LENGTH);
+                                       info.handle = att_han;
+                                       info.notification = TRUE;
+
+                                       _bt_gatt_server_event_cb(BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
+                                                       result, &info,
+                                                       event_info->cb, event_info->user_data);
+
+                               }
+}
+
+void cleanup_gatt_acquire_fd(int handle)
+{
+       bluetooth_gatt_acquire_notify_info_t *chr_info = NULL;
+
+       BT_INFO("+");
+
+       chr_info = bluetooth_get_characteristic_info_from_path(handle);
+
+       if (chr_info != NULL) {
+               BT_INFO("GATT Server: acquire notification char info found");
+
+               if (chr_info->write_fd >= 0) {
+                       BT_INFO("closing fd");
+                       close(chr_info->write_fd);
+               }
+
+               BT_INFO("Removing char_info from the list");
+               gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
+               bluetooth_characteristic_info_free(chr_info);
+       }
 }