Apply tizen 3.0 based product patchsets
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-gatt-service.c
index 51e63b5..7eee5ba 100644 (file)
@@ -37,6 +37,8 @@ static int serv_id = 1;
 static int register_pending_cnt = 0;
 static bool is_server_started = false;
 
+GCancellable *register_cancel;
+
 /* Introspection data for the service we are exporting */
 static const gchar service_introspection_xml[] =
 "<node name='/'>"
@@ -268,7 +270,7 @@ static int __bt_send_event_to_hps(int event, GVariant *var)
                parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder);
                g_variant_builder_unref(invalidated_builder);
                g_variant_builder_unref(inner_builder);
-       } else if (BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED) {
+       } else if (event == BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED) {
                GVariantBuilder *inner_builder;
                GVariantBuilder *invalidated_builder;
 
@@ -282,6 +284,8 @@ static int __bt_send_event_to_hps(int event, GVariant *var)
                parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder);
                g_variant_builder_unref(invalidated_builder);
                g_variant_builder_unref(inner_builder);
+       } else {
+               g_varaiant_unref(var);
        }
 
        msg = g_dbus_message_new_signal(BT_HPS_OBJECT_PATH, BT_HPS_INTERFACE_NAME, PROPERTIES_CHANGED);
@@ -909,6 +913,8 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection,
 #endif
                        }
                }
+               g_object_unref(invocation);
+               return;
        } else if (g_strcmp0(method_name, "StopNotify") == 0) {
                bt_user_info_t *user_info = NULL;
                bt_gatt_char_notify_change_t notify_change = {0, };
@@ -937,6 +943,8 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection,
 #endif
                        }
                }
+               g_object_unref(invocation);
+               return;
        } else if (g_strcmp0(method_name, "IndicateConfirm") == 0) {
                gchar *addr = NULL;
                bt_gatt_indicate_confirm_t confirm = {0, };
@@ -1469,7 +1477,7 @@ void get_service_cb(GObject *object, GAsyncResult *res, gpointer user_data)
        int n_char = 1;
 
        BT_DBG(" ");
-       result = g_dbus_proxy_call_finish(manager_gproxy, res, &error);
+       result = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error);
 
        if (result == NULL) {
                /* dBUS-RPC is failed */
@@ -1519,41 +1527,21 @@ void register_application_cb(GObject *object, GAsyncResult *res, gpointer user_d
 
        register_pending_cnt = 0;
 
-       result = g_dbus_proxy_call_finish(manager_gproxy, res, &error);
-
-       if (result == NULL) {
-               /* dBUS-RPC is failed */
-               BT_ERR("Dbus-RPC is failed\n");
-
-               if (error != NULL) {
-               /* dBUS gives error cause */
-                       BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n",
-                                               error->code, error->message);
-                       g_clear_error(&error);
-               }
-       } else {
-               g_variant_unref(result);
+       if (register_cancel) {
+               g_object_unref(register_cancel);
+               register_cancel = NULL;
        }
-}
 
-void unregister_application_cb(GObject *object, GAsyncResult *res,
-               gpointer user_data)
-{
-       BT_INFO("UnregisterApplication is completed");
-
-       GError *error = NULL;
-       GVariant *result;
-
-       result = g_dbus_proxy_call_finish(manager_gproxy, res, &error);
+       result = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error);
 
        if (result == NULL) {
                /* dBUS-RPC is failed */
                BT_ERR("Dbus-RPC is failed\n");
 
                if (error != NULL) {
-                       /* dBUS gives error cause */
+               /* dBUS gives error cause */
                        BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n",
-                                       error->code, error->message);
+                                               error->code, error->message);
                        g_clear_error(&error);
                }
        } else {
@@ -1576,6 +1564,9 @@ BT_EXPORT_API int bluetooth_gatt_unregister_application(void)
        GDBusProxy *proxy = NULL;
 
        if (is_server_started) {
+               GVariant *ret;
+               GError *err = NULL;
+
                proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez",
                                "/org/bluez/hci0", GATT_MNGR_INTERFACE);
 
@@ -1584,17 +1575,32 @@ BT_EXPORT_API int bluetooth_gatt_unregister_application(void)
 
                BT_INFO("UnregisterApplication");
 
+               is_server_started = false;
+
                /* Async Call to Unregister Service */
-               g_dbus_proxy_call(proxy,
+               ret = g_dbus_proxy_call_sync(proxy,
                                "UnregisterApplication",
                                g_variant_new("(o)",
                                        app_path),
                                G_DBUS_CALL_FLAGS_NONE, -1,
-                               NULL,
-                               (GAsyncReadyCallback) unregister_application_cb,
-                               NULL);
+                               NULL, &err);
+
+               if (ret == NULL) {
+                       /* dBUS-RPC is failed */
+                       BT_ERR("dBUS-RPC is failed");
+                       if (err != NULL) {
+                               /* dBUS gives error cause */
+                               BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+                               err->code, err->message);
+
+                               g_clear_error(&err);
+                       }
+                       return BLUETOOTH_ERROR_INTERNAL;
+               }
+               g_variant_unref(ret);
+
+               BT_INFO("UnregisterApplication is completed");
 
-               is_server_started = false;
                return BLUETOOTH_ERROR_NONE;
        }
 
@@ -1624,6 +1630,7 @@ static GDBusConnection *__bt_gatt_get_gdbus_connection(void)
                                        NULL, /* GDBusAuthObserver */
                                        NULL,
                                        &err);
+               g_free(address);
                if (!g_conn) {
                        if (err) {
                                BT_ERR("Unable to connect to dbus: %s", err->message);
@@ -1647,7 +1654,7 @@ static GDBusConnection *__bt_gatt_get_gdbus_connection(void)
                                        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);
@@ -1691,7 +1698,6 @@ BT_EXPORT_API int bluetooth_gatt_init(void)
        /* Register ObjectManager interface */
        node_info = __bt_gatt_create_method_node_info(
                                        manager_introspection_xml);
-
        if (node_info == NULL) {
                BT_ERR("failed to get node info");
                goto failed;
@@ -1705,7 +1711,7 @@ BT_EXPORT_API int bluetooth_gatt_init(void)
                                                        &manager_interface_vtable,
                                                        NULL, NULL, &error);
        }
-
+       g_dbus_node_info_unref(node_info);
        if (manager_id == 0) {
                BT_ERR("failed to register: %s", error->message);
                g_error_free(error);
@@ -1731,6 +1737,13 @@ failed:
 BT_EXPORT_API int bluetooth_gatt_deinit()
 {
        int ret = BLUETOOTH_ERROR_NONE;
+
+       if (register_cancel) {
+               g_cancellable_cancel(register_cancel);
+               g_object_unref(register_cancel);
+               register_cancel = NULL;
+       }
+
        /* Unown gdbus bus */
        if (owner_id) {
                /* remove/unregister all services */
@@ -1786,7 +1799,6 @@ BT_EXPORT_API int bluetooth_gatt_add_service(const char *svc_uuid,
 
        node_info = __bt_gatt_create_method_node_info(
                                        service_introspection_xml);
-
        if (node_info == NULL)
                return BLUETOOTH_ERROR_INTERNAL;
 
@@ -1797,6 +1809,7 @@ BT_EXPORT_API int bluetooth_gatt_add_service(const char *svc_uuid,
                                        node_info->interfaces[0],
                                        &serv_interface_vtable,
                                        NULL, NULL, &error);
+       g_dbus_node_info_unref(node_info);
 
        if (object_id == 0) {
                BT_ERR("failed to register: %s", error->message);
@@ -1890,7 +1903,6 @@ BT_EXPORT_API int bluetooth_gatt_add_new_characteristic(
 
        node_info = __bt_gatt_create_method_node_info(
                                        characteristics_introspection_xml);
-
        if (node_info == NULL)
                return BLUETOOTH_ERROR_INTERNAL;
 
@@ -1901,6 +1913,7 @@ BT_EXPORT_API int bluetooth_gatt_add_new_characteristic(
                                        node_info->interfaces[0],
                                        &char_interface_vtable,
                                        NULL, NULL, &error);
+       g_dbus_node_info_unref(node_info);
 
        if (object_id == 0) {
                BT_ERR("failed to register: %s", error->message);
@@ -2091,7 +2104,6 @@ BT_EXPORT_API int bluetooth_gatt_add_descriptor(
 
        node_info = __bt_gatt_create_method_node_info(
                                        descriptor_introspection_xml);
-
        if (node_info == NULL) {
                g_strfreev(line_argv);
                g_free(serv_path);
@@ -2105,6 +2117,7 @@ BT_EXPORT_API int bluetooth_gatt_add_descriptor(
                                node_info->interfaces[0],
                                &desc_interface_vtable,
                                NULL, NULL, &error);
+       g_dbus_node_info_unref(node_info);
 
        if (object_id == 0) {
                BT_ERR("failed to register: %s", error->message);
@@ -2166,6 +2179,7 @@ BT_EXPORT_API int bluetooth_gatt_add_descriptor(
        g_strfreev(line_argv);
        g_variant_builder_unref(inner_builder);
        g_variant_builder_unref(builder);
+       g_variant_builder_unref(builder2);
 
        return BLUETOOTH_ERROR_NONE;
 }
@@ -2304,12 +2318,19 @@ BT_EXPORT_API int bluetooth_gatt_register_application(void)
 
                BT_INFO("RegisterApplication");
 
+               if (register_cancel) {
+                       g_cancellable_cancel(register_cancel);
+                       g_object_unref(register_cancel);
+               }
+
+               register_cancel = g_cancellable_new();
+
                g_dbus_proxy_call(proxy,
                                "RegisterApplication",
                                g_variant_new("(oa{sv})",
                                        app_path, NULL),
                                G_DBUS_CALL_FLAGS_NONE, -1,
-                               NULL,
+                               register_cancel,
                                (GAsyncReadyCallback) register_application_cb,
                                NULL);
 
@@ -2369,6 +2390,7 @@ BT_EXPORT_API int bluetooth_gatt_update_characteristic(
        int i = 0;
        gchar **line_argv = NULL;
        gchar *serv_path = NULL;
+       const char *value = NULL;
 
        line_argv = g_strsplit_set(char_path, "/", 0);
        serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);
@@ -2427,7 +2449,18 @@ BT_EXPORT_API int bluetooth_gatt_update_characteristic(
 
                char_info->value_length = value_length;
 
-               char_info->char_value = (char *)realloc(char_info->char_value, value_length);
+               value = (char *)realloc(char_info->char_value, value_length);
+               if (value == NULL) {
+                       g_free(serv_path);
+                       g_strfreev(line_argv);
+                       g_variant_builder_unref(inner_builder);
+                       g_variant_builder_unref(outer_builder);
+                       g_variant_builder_unref(invalidated_builder);
+
+                       return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
+               }
+
+               char_info->char_value = (char*)value;
                if (char_info->char_value) {
                        for (i = 0; i < value_length; i++)
                                char_info->char_value[i] = char_value[i];
@@ -2598,31 +2631,12 @@ BT_EXPORT_API int bluetooth_gatt_send_response(int request_id, guint req_type,
                return BLUETOOTH_ERROR_INTERNAL;
        }
 
-       if (resp_state != BLUETOOTH_ERROR_NONE) {
+       if (resp_state != BLUETOOTH_ATT_ERROR_NONE) {
                BT_ERR("resp_state is 0x%X", resp_state);
-
-               switch (resp_state) {
-               case BLUETOOTH_ERROR_WRITE_REQUEST_REJECTED:
-                       g_dbus_method_invocation_return_dbus_error(req_info->context,
-                       "org.bluez.Error.Failed", "Write Request Rejected");
-                       break;
-               case BLUETOOTH_ERROR_OBJECT_NOT_SELECTED:
-                       g_dbus_method_invocation_return_dbus_error(req_info->context,
-                       "org.bluez.Error.Failed", "Object Not Selected");
-                       break;
-               case BLUETOOTH_ERROR_CONCURRENCY_LIMIT_EXCEEDED:
-                       g_dbus_method_invocation_return_dbus_error(req_info->context,
-                       "org.bluez.Error.Failed", "Concurrency Limit Exceeded");
-                       break;
-               case BLUETOOTH_ERROR_OBJECT_NAME_EXISITS:
-                       g_dbus_method_invocation_return_dbus_error(req_info->context,
-                       "org.bluez.Error.Failed", "Object Name Already Exists");
-                       break;
-               default:
-                       g_dbus_method_invocation_return_dbus_error(req_info->context,
-                       "org.bluez.Error.Failed", "Application Error");
-                       break;
-               }
+               char err_msg[20] = { 0, };
+               g_snprintf(err_msg, sizeof(err_msg), "ATT error: 0x%02x", resp_state);
+               g_dbus_method_invocation_return_dbus_error(req_info->context,
+                                               "org.bluez.Error.Failed", err_msg);
 
                gatt_requests = g_slist_remove(gatt_requests, req_info);