Use gdbus library instead of dbus-glib library for client library 51/31951/8
authorBaptiste DURAND <baptiste.durand@gmail.com>
Fri, 12 Dec 2014 11:38:11 +0000 (12:38 +0100)
committerBaptiste DURAND <baptiste.durand@open.eurogiciel.org>
Fri, 12 Dec 2014 17:14:35 +0000 (18:14 +0100)
gdbus has creedential features.
This ones will be used to identify user for the resquest management
Permits to fix
Based on Tizen 2.3 version from slp-pkgmgr package
BUG-Tizen=TC-1808
BUG-Tizen=TC-2222

Change-Id: I51dbbd994804b41f1f4332f07824879df2605150
Signed-off-by: Baptiste DURAND <baptiste.durand@open.eurogiciel.org>
comm/CMakeLists.txt
comm/comm_client_dbus.c [deleted file]
comm/comm_client_gdbus.c [new file with mode: 0755]

index 7378df5..ba3d115 100644 (file)
@@ -25,7 +25,7 @@ message(STATUS "version/major : ${VERSION} / ${VERSION_MAJOR}")
 ### Get required CFLAGS, LDFLAGS from pkg-config
 
 include(FindPkgConfig)
-pkg_check_modules(comm_pkgs REQUIRED dbus-1 dbus-glib-1 dlog pkgmgr-info)
+pkg_check_modules(comm_pkgs REQUIRED dbus-1 glib-2.0 dbus-glib-1 gio-2.0 gio-unix-2.0 dlog pkgmgr-info)
 
 foreach(flag ${comm_pkgs_CFLAGS})
        set(comm_pkgs_CFLAGS_str "${comm_pkgs_CFLAGS_str} ${flag}")
@@ -49,6 +49,12 @@ add_custom_target(comm_pkg_mgr_server_dbus_bindings.h
                        --output=${CMAKE_CURRENT_BINARY_DIR}/comm_pkg_mgr_server_dbus_bindings.h
        )
 
+#GDBUS specific code
+add_custom_command(OUTPUT comm_pkg_mgr_client_gdbus_generated.c comm_pkg_mgr_client_gdbus_generated.h
+       COMMAND gdbus-codegen --generate-c-code comm_pkg_mgr_client_gdbus_generated
+                       --interface-prefix pkgmgr ${CMAKE_CURRENT_SOURCE_DIR}/comm_pkg_mgr.xml
+       )
+
 # comm_status_broadcast : status broadcast interface (client - backend process)
 add_custom_target(comm_status_broadcast_client_dbus_bindings.h
        COMMAND dbus-binding-tool --prefix=status_broadcast --mode=glib-client 
@@ -79,14 +85,16 @@ set_source_files_properties(comm_status_broadcast_signal_marshaller.c PROPERTIES
 ## client for apps
 # Send request, get status signal
 add_library(pkgmgr_installer_client SHARED
-               comm_client_dbus.c
+               comm_client_gdbus.c
+               comm_pkg_mgr_client_gdbus_generated.c
                #${CMAKE_CURRENT_BINARY_DIR}/comm_status_broadcast_signal_marshaller.c
                )
 set_target_properties(pkgmgr_installer_client PROPERTIES SOVERSION ${VERSION_MAJOR})
 set_target_properties(pkgmgr_installer_client PROPERTIES VERSION ${VERSION})
 set_target_properties(pkgmgr_installer_client PROPERTIES COMPILE_FLAGS "${comm_pkgs_CFLAGS_str}")
 target_link_libraries(pkgmgr_installer_client ${comm_pkgs_LDFLAGS})
-add_dependencies(pkgmgr_installer_client comm_pkg_mgr_client_dbus_bindings.h comm_status_broadcast_client_dbus_bindings.h comm_status_broadcast_signal_marshaller.h comm_status_broadcast_signal_marshaller.c)
+#add_dependencies(pkgmgr_installer_client comm_pkg_mgr_client_dbus_bindings.h comm_status_broadcast_client_dbus_bindings.h comm_status_broadcast_signal_marshaller.h comm_status_broadcast_signal_marshaller.c)
+add_dependencies(pkgmgr_installer_client comm_pkg_mgr_client_gdbus_generated.h comm_pkg_mgr_client_gdbus_generated.c)
 
 ## pkg-mgr server for PMS
 # Get request
diff --git a/comm/comm_client_dbus.c b/comm/comm_client_dbus.c
deleted file mode 100644 (file)
index 1518bde..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * slp-pkgmgr
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
- * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-
-
-
-/*
- * comm_client_dbus.c
- * comm_client library using pure dbus 
- * (dbus-glib is used only to register into g_main_loop)
- */
-
-#include "comm_config.h"
-#include "comm_client.h"
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <fcntl.h>
-
-/*******************
- * ADT description
- */
-
-/* Storing status_cb */
-struct signal_callback_data {
-       status_cb cb;
-       void *cb_data;
-};
-
-/* comm_client ADT */
-struct comm_client {
-       DBusConnection *conn;
-       struct signal_callback_data *sig_cb_data;
-};
-
-/*********************************
- * Internal function description
- */
-
-static inline int __comm_read_proc(const char *path, char *buf, int size)
-{
-       int fd;
-       int ret;
-
-       if (buf == NULL || path == NULL)
-               return -1;
-
-       fd = open(path, O_RDONLY);
-       if (fd < 0)
-               return -1;
-
-       ret = read(fd, buf, size - 1);
-       if (ret <= 0) {
-               close(fd);
-               return -1;
-       } else
-               buf[ret] = 0;
-
-       close(fd);
-
-       return ret;
-}
-static inline int __comm_find_pid_by_cmdline(const char *dname,
-                                     const char *cmdline, const char *apppath)
-{
-       int pid = 0;
-
-       if (strncmp(cmdline, apppath, 1024-1) == 0) {
-               pid = atoi(dname);
-               if (pid != getpgid(pid))
-                       pid = 0;
-       }
-
-       return pid;
-}
-
-static int __comm_proc_iter_kill_cmdline(const char *apppath)
-{
-       DIR *dp;
-       struct dirent *dentry;
-       int pid;
-       int ret;
-       char buf[1024];
-
-       dp = opendir("/proc");
-       if (dp == NULL) {
-               return -1;
-       }
-
-       while ((dentry = readdir(dp)) != NULL) {
-               if (!isdigit(dentry->d_name[0]))
-                       continue;
-
-               snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
-               ret = __comm_read_proc(buf, buf, sizeof(buf));
-               if (ret <= 0)
-                       continue;
-
-               pid = __comm_find_pid_by_cmdline(dentry->d_name, buf, apppath);
-               if (pid > 0) {
-                       int pgid;
-
-                       pgid = getpgid(pid);
-                       if (pgid <= 1) {
-                               closedir(dp);
-                               return -1;
-                       }
-
-                       if (killpg(pgid, SIGKILL) < 0) {
-                               closedir(dp);
-                               return -1;
-                       }
-               }
-       }
-
-       closedir(dp);
-       return 0;
-}
-static char *__get_interface(int status_type)
-{
-       char *interface = NULL;
-
-       switch (status_type) {
-               case COMM_STATUS_BROADCAST_ALL:
-                       interface = COMM_STATUS_BROADCAST_DBUS_INTERFACE;
-                       break;
-
-               case COMM_STATUS_BROADCAST_INSTALL:
-                       interface = COMM_STATUS_BROADCAST_DBUS_INSTALL_INTERFACE;
-                       break;
-
-               case COMM_STATUS_BROADCAST_UNINSTALL:
-                       interface = COMM_STATUS_BROADCAST_DBUS_UNINSTALL_INTERFACE;
-                       break;
-
-               case COMM_STATUS_BROADCAST_MOVE:
-                       interface = COMM_STATUS_BROADCAST_DBUS_MOVE_INTERFACE;
-                       break;
-
-               case COMM_STATUS_BROADCAST_INSTALL_PROGRESS:
-                       interface = COMM_STATUS_BROADCAST_DBUS_INSTALL_PROGRESS_INTERFACE;
-                       break;
-
-               case COMM_STATUS_BROADCAST_UPGRADE:
-                       interface = COMM_STATUS_BROADCAST_DBUS_UPGRADE_INTERFACE;
-                       break;
-
-               default:
-                       interface = NULL;
-       }
-       return interface;
-}
-
-/**
- * signal handler filter
- * Filter signal, and run user callback
- */
-DBusHandlerResult
-_on_signal_handle_filter(DBusConnection *conn,
-                        DBusMessage *msg, void *user_data)
-{
-       DBusError err;
-
-       dbg("start function");
-
-       dbus_error_init(&err);
-
-       /* Values to be received by signal */
-       char *req_id = NULL;
-       char *pkg_type = NULL;
-       char *pkgid = NULL;
-       char *key = NULL;
-       char *val = NULL;
-
-       /* User's signal handler */
-       struct signal_callback_data *sig_cb_data;
-       sig_cb_data = (struct signal_callback_data *)user_data;
-
-       /* Signal check */
-       if ((dbus_message_is_signal(msg, COMM_STATUS_BROADCAST_DBUS_INTERFACE, COMM_STATUS_BROADCAST_SIGNAL_STATUS)) ||
-               (dbus_message_is_signal(msg, COMM_STATUS_BROADCAST_DBUS_INSTALL_INTERFACE, COMM_STATUS_BROADCAST_EVENT_INSTALL)) ||
-               (dbus_message_is_signal(msg, COMM_STATUS_BROADCAST_DBUS_UNINSTALL_INTERFACE, COMM_STATUS_BROADCAST_EVENT_UNINSTALL)) ||
-               (dbus_message_is_signal(msg, COMM_STATUS_BROADCAST_DBUS_MOVE_INTERFACE, COMM_STATUS_BROADCAST_EVENT_MOVE)) ||
-               (dbus_message_is_signal(msg, COMM_STATUS_BROADCAST_DBUS_UPGRADE_INTERFACE, COMM_STATUS_BROADCAST_EVENT_UPGRADE)) ||
-               (dbus_message_is_signal(msg, COMM_STATUS_BROADCAST_DBUS_INSTALL_PROGRESS_INTERFACE, COMM_STATUS_BROADCAST_EVENT_INSTALL_PROGRESS))) {
-
-               /* Signal type check */
-               if (dbus_message_get_args(msg, &err,
-                                         DBUS_TYPE_STRING, &req_id,
-                                         DBUS_TYPE_STRING, &pkg_type,
-                                         DBUS_TYPE_STRING, &pkgid,
-                                         DBUS_TYPE_STRING, &key,
-                                         DBUS_TYPE_STRING, &val,
-                                         DBUS_TYPE_INVALID)) {
-                       /* Got signal! */
-                       dbg("Got signal: %s / %s / %s / %s / %s", req_id,
-                           pkg_type, pkgid, key, val);
-
-                       /* Run signal callback if exist */
-                       if (sig_cb_data && sig_cb_data->cb) {
-                               sig_cb_data->cb(sig_cb_data->cb_data, req_id,
-                                               pkg_type, pkgid, key, val);
-
-                               dbg("callback function is end");
-                       }
-
-                       dbg("handled signal. exit function");
-                       return DBUS_HANDLER_RESULT_HANDLED;
-               }
-       }
-       dbg("Didn't handled signal. anyway exit function");
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-/**
- * signal_callback_data free function
- * Just free it!
- */
-void _free_sig_cb_data(void *memory)
-{
-       struct signal_callback_data *sig_cb_data;
-       sig_cb_data = (struct signal_callback_data *)memory;
-       if (!sig_cb_data)
-               return;
-       free(sig_cb_data);
-}
-
-/*******************
- * API description
- */
-
-/**
- * Create a new comm_client object
- */
-comm_client *comm_client_new(void)
-{
-       DBusError err;
-       comm_client *cc = NULL;
-
-       /* Allocate memory for ADT:comm_client */
-       cc = calloc(1, sizeof(comm_client));
-       if (NULL == cc) {
-               ERR("No memory");
-               goto ERROR_CLEANUP;
-       }
-
-       /* Connect to dbus */
-       dbus_error_init(&err);
-       cc->conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
-       if (dbus_error_is_set(&err)) {
-               ERR("dbus connection error (%s)", err.message);
-               dbus_error_free(&err);
-               goto ERROR_CLEANUP;
-       }
-       if (NULL == cc->conn) {
-               ERR("dbus connection is not set, even dbus error isn't raised");
-               goto ERROR_CLEANUP;
-       }
-       dbus_connection_set_exit_on_disconnect(cc->conn,FALSE);
-
-       return cc;
-
- ERROR_CLEANUP:
-       if (cc)
-               free(cc);
-       return NULL;
-}
-
-/**
- * Free comm_client object
- */
-int comm_client_free(comm_client *cc)
-{
-       if (!cc)
-               return -1;
-       if (!(cc->conn))  {
-               ERR("Invalid dbus connection");
-               return -2;
-       }
-
-       /* Free signal filter if signal callback is exist */
-       if (cc->sig_cb_data) {
-               dbus_connection_remove_filter(cc->conn,
-                                             _on_signal_handle_filter,
-                                             cc->sig_cb_data);
-               cc->sig_cb_data = NULL;
-       }
-       if (dbus_connection_get_is_connected(cc->conn)) {
-       /* Cleanup ADT */
-       /* flush remaining buffer: blocking mode */
-               dbus_connection_flush(cc->conn);
-       }
-       dbus_connection_close(cc->conn);
-       dbus_connection_unref(cc->conn);
-       cc->conn = NULL;
-       free(cc);
-
-       return 0;
-}
-
-/**
- * Request a message
- */
-int
-comm_client_request(
-               comm_client *cc,
-               const char *req_id,
-               const int req_type,
-               const char *pkg_type,
-               const char *pkgid,
-               const char *args,
-               const char *cookie,
-               uid_t uid,
-               int is_block)
-{      
-       DBusError err;
-       DBusMessage *msg = NULL;
-       int r = COMM_RET_ERROR; /* Default return */
-
-       if (!cc){
-               ERR("Invalid dbus input");
-               return COMM_RET_ERROR;
-       }
-
-       /* Create a dbus message */
-       msg = dbus_message_new_method_call(COMM_PKG_MGR_DBUS_SERVICE,
-                                          COMM_PKG_MGR_DBUS_PATH,
-                                          COMM_PKG_MGR_DBUS_INTERFACE,
-                                          COMM_PKG_MGR_METHOD_REQUEST);
-       if (NULL == msg) {
-               r = COMM_RET_NOMEM;
-               ERR("dbus_message_new_method_call fail : msg is NULL");
-               goto ERROR_CLEANUP;
-       }
-
-       /* Assign default values if NULL (NULL is not allowed) */
-       if (NULL == req_id)
-               req_id = "tmp_reqid";
-       if (NULL == pkg_type)
-               pkg_type = "none";
-       if (NULL == pkgid)
-               pkgid = "";
-       if (NULL == args)
-               args = "";
-       if (NULL == cookie)
-               cookie = "";
-
-       dbus_error_init(&err);
-
-       /* Append arguments */
-       if (!dbus_message_append_args(msg,
-                                     DBUS_TYPE_STRING, &req_id,
-                                     DBUS_TYPE_INT32, &req_type,
-                                     DBUS_TYPE_STRING, &pkg_type,
-                                     DBUS_TYPE_STRING, &pkgid,
-                                     DBUS_TYPE_STRING, &args,
-                                     DBUS_TYPE_STRING, &cookie,
-                                     DBUS_TYPE_INT32, &uid,
-                                     DBUS_TYPE_INVALID)) {
-               r = -3;
-               ERR("dbus_message_append_args fail");
-               goto ERROR_CLEANUP;
-       }
-
-       /* Send message , timeout -1 = _DBUS_DEFAULT_TIMEOUT_VALUE (25 * 1000) 25 seconds*/
-       if (is_block == 1){
-               if(!dbus_connection_send_with_reply_and_block(cc->conn, msg,
-                                                             -1, NULL)) {
-                       ERR("try send msg to dbus by timeout");
-                       sleep(1);
-                       if(!dbus_connection_send_with_reply_and_block(cc->conn, msg,
-                                                                         -1, &err)) {
-                               r = -4;
-                               ERR("dbus_connection_send_with_reply_and_block fail");
-
-                               __comm_proc_iter_kill_cmdline("pkgmgr-server");
-
-                               if (dbus_error_is_set(&err))
-                                       ERR("dbus error:%s", err.message);
-                               goto ERROR_CLEANUP;
-                       }
-               }
-       } else {
-               if (!dbus_connection_send(cc->conn, msg, NULL)) {
-                       r = -5;
-                       ERR("dbus_connection_send fail");
-                       goto ERROR_CLEANUP;
-               }
-       }
-       dbus_connection_flush(cc->conn);
-
-       /* Cleanup and return */
-       dbus_message_unref(msg);
-       /* NOTE: It is not needed to free DBusMessageIter. */
-       dbus_error_free(&err);
-       return 0;
-
- ERROR_CLEANUP:
-       if (COMM_RET_NOMEM == r)
-               ERR("No memory!");
-       else
-               ERR("General error!");
-
-       if (msg)
-               dbus_message_unref(msg);
-
-       dbus_error_free(&err);
-
-       return r;
-}
-
-/**
- * Set a callback for status signal
- */
-int
-comm_client_set_status_callback(int comm_status_type, comm_client *cc, status_cb cb, void *cb_data)
-{
-       DBusError err;
-       char buf[256] = { 0, };
-       int r = COMM_RET_ERROR;
-
-       dbus_error_init(&err);
-
-       if (NULL == cc)
-               goto ERROR_CLEANUP;
-
-       /* Add a rule for signal */
-       snprintf(buf, 255, "type='signal',interface='%s'",      __get_interface(comm_status_type));
-       dbus_bus_add_match(cc->conn, buf, &err);
-       if (dbus_error_is_set(&err)) {
-               ERR("dbus error:%s", err.message);
-               r = COMM_RET_ERROR;
-               goto ERROR_CLEANUP;
-       }
-
-       /* If previous signal handler is set already, remove filter first */
-       if (cc->sig_cb_data) {
-               dbus_connection_remove_filter(cc->conn,
-                                             _on_signal_handle_filter,
-                                             cc->sig_cb_data);
-               /* TODO: Is it needed to free cc->sig_cb_data here? */
-       }
-
-       /* Create new sig_cb_data */
-       cc->sig_cb_data = calloc(1, sizeof(struct signal_callback_data));
-       (cc->sig_cb_data)->cb = cb;
-       (cc->sig_cb_data)->cb_data = cb_data;
-
-       /* Add signal filter */
-       if (!dbus_connection_add_filter(cc->conn,
-                                       _on_signal_handle_filter,
-                                       cc->sig_cb_data, _free_sig_cb_data)) {
-               r = COMM_RET_NOMEM;
-               goto ERROR_CLEANUP;
-       }
-
-       /* Cleanup and return */
-       dbus_error_free(&err);
-       return COMM_RET_OK;
-
- ERROR_CLEANUP:
-       if (COMM_RET_NOMEM == r)
-               ERR("No memory");
-       else
-               ERR("General error");
-
-       dbus_error_free(&err);
-       return r;
-}
-
diff --git a/comm/comm_client_gdbus.c b/comm/comm_client_gdbus.c
new file mode 100755 (executable)
index 0000000..de3944b
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * slp-pkgmgr
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
+ * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+/*
+ * comm_client_gdbus.c
+ * comm_client library using gdbus
+ */
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include "comm_config.h"
+#include "comm_client.h"
+#include "comm_pkg_mgr_client_gdbus_generated.h"
+
+/*******************
+ * ADT description
+ */
+
+/* Storing status_cb */
+struct signal_callback_data {
+       status_cb cb;
+       void *cb_data;
+};
+
+/* comm_client ADT */
+struct comm_client {
+       guint subscription_id;
+       GDBusConnection *conn;
+       struct signal_callback_data *sig_cb_data;
+};
+
+#define COMM_CLIENT_RETRY_MAX  5
+
+static int __retry_request(comm_client *cc,
+       const gchar *req_id,
+       gint req_type,
+       const gchar *pkg_type,
+       const gchar *pkgid,
+       const gchar *args,
+       const gchar *cookie,
+       uid_t uid,
+       gint *ret)
+{      
+       OrgTizenSlpPkgmgr *proxy;
+       GError *error = NULL;
+       int rc = 0;
+
+       proxy = org_tizen_slp_pkgmgr_proxy_new_sync(cc->conn,
+                       G_DBUS_PROXY_FLAGS_NONE, COMM_PKG_MGR_DBUS_SERVICE,
+                       COMM_PKG_MGR_DBUS_PATH,
+                       NULL, &error);
+       if (proxy == NULL) {
+               ERR("Unable to create proxy[rc=%d, err=%s]\n", rc, error->message);
+               return FALSE;
+       }
+
+       rc = org_tizen_slp_pkgmgr_call_request_sync(proxy,
+                       req_id, req_type, pkg_type, pkgid, args, cookie, uid, &ret, NULL, &error);
+       if (!rc) {
+               ERR("Failed to send request[rc=%d, err=%s]\n", rc, error->message);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+static const gchar *__get_interface(int status_type)
+{
+       char *ifc = NULL;
+
+       switch (status_type) {
+               case COMM_STATUS_BROADCAST_ALL:
+                       ifc = COMM_STATUS_BROADCAST_DBUS_INTERFACE;
+                       break;
+
+               case COMM_STATUS_BROADCAST_INSTALL:
+                       ifc = COMM_STATUS_BROADCAST_DBUS_INSTALL_INTERFACE;
+                       break;
+
+               case COMM_STATUS_BROADCAST_UNINSTALL:
+                       ifc = COMM_STATUS_BROADCAST_DBUS_UNINSTALL_INTERFACE;
+                       break;
+
+               case COMM_STATUS_BROADCAST_MOVE:
+                       ifc = COMM_STATUS_BROADCAST_DBUS_MOVE_INTERFACE;
+                       break;
+
+               case COMM_STATUS_BROADCAST_INSTALL_PROGRESS:
+                       ifc = COMM_STATUS_BROADCAST_DBUS_INSTALL_PROGRESS_INTERFACE;
+                       break;
+
+               case COMM_STATUS_BROADCAST_UPGRADE:
+                       ifc = COMM_STATUS_BROADCAST_DBUS_UPGRADE_INTERFACE;
+                       break;
+
+               default:
+                       break;
+       }
+       return ifc;
+}
+
+/**
+ * signal handler filter
+ * Filter signal, and run user callback
+ */
+void _on_signal_handle_filter(GDBusConnection *conn,
+               const gchar *sender_name,
+               const gchar *object_path,
+               const gchar *interface_name,
+               const gchar *signal_name,
+               GVariant *parameters,
+               gpointer user_data)
+{
+       if (interface_name && strcmp(interface_name, COMM_STATUS_BROADCAST_DBUS_INTERFACE) &&
+               strcmp(interface_name, COMM_STATUS_BROADCAST_DBUS_INSTALL_INTERFACE) &&
+               strcmp(interface_name, COMM_STATUS_BROADCAST_DBUS_UNINSTALL_INTERFACE) &&
+               strcmp(interface_name, COMM_STATUS_BROADCAST_DBUS_UPGRADE_INTERFACE) &&
+               strcmp(interface_name, COMM_STATUS_BROADCAST_DBUS_MOVE_INTERFACE) &&
+               strcmp(interface_name, COMM_STATUS_BROADCAST_DBUS_INSTALL_PROGRESS_INTERFACE)) {
+               dbg("Interface name did not match. Drop the message");
+               return;
+       }
+       if (signal_name && strcmp(signal_name, COMM_STATUS_BROADCAST_SIGNAL_STATUS) &&
+               strcmp(signal_name, COMM_STATUS_BROADCAST_EVENT_INSTALL) &&
+               strcmp(signal_name, COMM_STATUS_BROADCAST_EVENT_UNINSTALL) &&
+               strcmp(signal_name, COMM_STATUS_BROADCAST_EVENT_UPGRADE) &&
+               strcmp(signal_name, COMM_STATUS_BROADCAST_EVENT_MOVE) &&
+               strcmp(signal_name, COMM_STATUS_BROADCAST_EVENT_INSTALL_PROGRESS)) {
+               dbg("Signal name did not match. Drop the message");
+               return;
+       }
+       /* Values to be received by signal */
+       char *req_id = NULL;
+       char *pkg_type = NULL;
+       char *pkgid = NULL;
+       char *key = NULL;
+       char *val = NULL;
+
+       /* User's signal handler */
+       struct signal_callback_data *sig_cb_data;
+       if (user_data)
+               sig_cb_data = (struct signal_callback_data *)user_data;
+       else
+               return;
+
+       g_variant_get(parameters, "(&s&s&s&s&s)",
+                               &req_id, &pkg_type, &pkgid, &key, &val);
+       /* Got signal! */
+       SECURE_LOGD("Got signal: [%s] %s / %s / %s / %s / %s", signal_name, req_id,
+           pkg_type, pkgid, key, val);
+
+       /* Run signal callback if exist */
+       if (sig_cb_data && sig_cb_data->cb) {
+               sig_cb_data->cb(sig_cb_data->cb_data, req_id,
+                               pkg_type, pkgid, key, val);
+               dbg("callback function is end");
+       }
+       dbg("Handled signal. Exit function");
+       return;
+}
+
+/**
+ * signal_callback_data free function
+ * Just free it!
+ */
+void _free_sig_cb_data(void *data)
+{
+       struct signal_callback_data *sig_cb_data = NULL;
+       sig_cb_data = (struct signal_callback_data *)data;
+       free(sig_cb_data);
+}
+
+/*******************
+ * API description
+ */
+
+/**
+ * Create a new comm_client object
+ */
+comm_client *comm_client_new(void)
+{
+       GError *error = NULL;
+       comm_client *cc = NULL;
+
+       /* Allocate memory for ADT:comm_client */
+       g_type_init();
+       cc = calloc(1, sizeof(comm_client));
+       if (NULL == cc) {
+               ERR("No memory");
+               return NULL;
+       }
+
+       /* Connect to gdbus. Gets shared BUS */
+       cc->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (error) {
+               ERR("gdbus connection error (%s)", error->message);
+               g_error_free(error);
+               goto ERROR_CLEANUP;
+       }
+       if (NULL == cc->conn) {
+               ERR("gdbus connection is not set, even gdbus error isn't raised");
+               goto ERROR_CLEANUP;
+       }
+       return cc;
+
+ ERROR_CLEANUP:
+       if (cc)
+               free(cc);
+       return NULL;
+}
+
+/**
+ * Free comm_client object
+ */
+int comm_client_free(comm_client *cc)
+{
+       if (!cc)
+               return -1;
+       if (!(cc->conn) || g_dbus_connection_is_closed(cc->conn)) {
+               ERR("Invalid gdbus connection");
+               return -2;
+       }
+
+       if (cc->sig_cb_data) {
+               g_dbus_connection_signal_unsubscribe(cc->conn, cc->subscription_id);
+               /* TODO: Is it needed to free cc->sig_cb_data here? */
+               /* _free_sig_cb_data(cc->sig_cb_data); */
+       }
+
+       /* Cleanup ADT */
+       /* flush remaining buffer: blocking mode */
+       g_dbus_connection_flush_sync(cc->conn, NULL, NULL);
+
+       /* Free signal filter if signal callback is exist */
+
+       /* just unref because it is shared BUS.
+       If ref count is 0 it will get free'd automatically
+       */
+       g_object_unref(cc->conn);
+       free(cc);
+
+       return 0;
+}
+
+/**
+ * Request a message
+ */
+int
+comm_client_request(
+               comm_client *cc,
+               const char *req_id,
+               const int req_type,
+               const char *pkg_type,
+               const char *pkgid,
+               const char *args,
+               const char *cookie,
+               uid_t uid,
+               int is_block)
+{
+       GError *error = NULL;
+       int rc = 0;
+       int ret = 0;
+       int retry_cnt = 0;
+
+       OrgTizenSlpPkgmgr *proxy;
+       if (!cc){
+               ERR("Invalid gdbus input");
+               return COMM_RET_ERROR;
+       }
+       proxy = org_tizen_slp_pkgmgr_proxy_new_sync(cc->conn,
+                       G_DBUS_PROXY_FLAGS_NONE, COMM_PKG_MGR_DBUS_SERVICE,
+                       COMM_PKG_MGR_DBUS_PATH,
+                       NULL, &error);
+       if (proxy == NULL) {
+               ERR("Unable to create proxy[rc=%d, err=%s]\n", rc, error->message);
+               return COMM_RET_ERROR;
+       }
+
+       /* Assign default values if NULL (NULL is not allowed) */
+       if (req_id == NULL)
+               req_id = "tmp_reqid";
+       if (pkg_type == NULL)
+               pkg_type = "none";
+       if (pkgid == NULL)
+               pkgid = "";
+       if (args == NULL)
+               args = "";
+       if (cookie == NULL)
+               cookie = "";
+
+       rc = org_tizen_slp_pkgmgr_call_request_sync(proxy,
+                       req_id, req_type, pkg_type, pkgid, args, cookie, uid, &ret, NULL, &error);
+
+       while ((rc == FALSE) && (retry_cnt < COMM_CLIENT_RETRY_MAX)) {
+               ERR("Failed to send request, sleep and retry[rc=%d, err=%s]\n", rc, error->message);
+               sleep(1);
+
+               retry_cnt++;
+
+               rc = __retry_request(cc, req_id, req_type, pkg_type, pkgid, args, cookie, uid, &ret);
+               if(rc == TRUE) {
+                       ERR("__retry_request is success[retry_cnt=%d]\n", retry_cnt);
+               }
+       }
+       
+       return rc == TRUE ? COMM_RET_OK : COMM_RET_ERROR;
+}
+
+/**
+ * Set a callback for status signal
+ */
+int
+comm_client_set_status_callback(int comm_status_type, comm_client *cc, status_cb cb, void *cb_data)
+{
+       int r = COMM_RET_ERROR;
+       char *ifc = NULL;
+
+       if (NULL == cc)
+               return NULL;
+
+       ifc = __get_interface(comm_status_type);
+       if (ifc == NULL) {
+               ERR("Invalid interface name\n");
+               return COMM_RET_ERROR;
+       }
+
+       /* Create new sig_cb_data */
+       cc->sig_cb_data = calloc(1, sizeof(struct signal_callback_data));
+       if ( cc->sig_cb_data ) {
+               (cc->sig_cb_data)->cb = cb;
+               (cc->sig_cb_data)->cb_data = cb_data;
+       } else {
+               r = COMM_RET_ERROR;
+               goto ERROR_CLEANUP;
+       }
+       /* Add a filter for signal */
+       cc->subscription_id = g_dbus_connection_signal_subscribe(cc->conn, NULL, ifc,
+               NULL, NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
+               _on_signal_handle_filter, (gpointer)cc->sig_cb_data, _free_sig_cb_data);
+       if (!cc->subscription_id) {
+               ERR("Failed to add filter\n");
+               r = COMM_RET_ERROR;
+               goto ERROR_CLEANUP;
+       }
+
+       return COMM_RET_OK;
+
+ ERROR_CLEANUP:
+       ERR("General error");
+       return r;
+}
+