libsyscommon library removal 72/255572/2 accepted/tizen_6.5_unified accepted/tizen_7.0_unified accepted/tizen_7.0_unified_hotfix accepted/tizen_8.0_unified tizen_6.5 tizen_7.0 tizen_7.0_hotfix tizen_8.0 accepted/tizen/6.5/unified/20211028.102627 accepted/tizen/7.0/unified/20221110.061334 accepted/tizen/7.0/unified/hotfix/20221116.105326 accepted/tizen/8.0/unified/20231005.093351 accepted/tizen/unified/20210321.225812 submit/tizen/20210319.085957 submit/tizen/20210319.090004 submit/tizen_6.5/20211028.162201 tizen_6.5.m2_release tizen_7.0_m2_release tizen_8.0_m2_release
authorrohit <rohit1.kr@samsung.com>
Fri, 19 Mar 2021 08:10:10 +0000 (13:40 +0530)
committerrohit <rohit1.kr@samsung.com>
Fri, 19 Mar 2021 08:40:09 +0000 (14:10 +0530)
Change-Id: I78dbd9f336559e473d825f793f014628251fdb49

CMakeLists.txt
lbs-server/src/battery-monitor/CMakeLists.txt
lbs-server/src/battery-monitor/battery-monitor.c
lbs-server/src/battery-monitor/lbs_dbus.c [new file with mode: 0755]
lbs-server/src/battery-monitor/lbs_dbus.h [new file with mode: 0755]
packaging/lbs-server.spec

index 6edfeff..b98006f 100755 (executable)
@@ -7,7 +7,7 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 SET(BIN_DIR "${PREFIX}/bin")
 
 #Dependencies
-SET(common_dp "glib-2.0 lbs-dbus dlog gio-2.0 lbs-location libsyscommon hal-api-common hal-api-location")
+SET(common_dp "glib-2.0 lbs-dbus dlog gio-2.0 lbs-location hal-api-common hal-api-location")
 SET(server_dp "${common_dp} tapi vconf vconf-internal-keys gthread-2.0  gio-unix-2.0 capi-network-connection capi-network-wifi-manager capi-system-info libtzplatform-config")
 SET(module_dp "${common_dp} gmodule-2.0")
 SET(haltests_dp "${server_dp} capi-system-info vconf")
index bbba076..9937f06 100755 (executable)
@@ -7,7 +7,6 @@ pkg_check_modules(libshared REQUIRED
        glib-2.0
        gio-2.0
        gio-unix-2.0
-       libsyscommon
        dlog)
 
 FOREACH(flag ${libshared_CFLAGS})
index e7fe494..67eb814 100755 (executable)
 #include <sys/time.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <libsyscommon/dbus-system.h>
 #include <lbs_dbus_server.h>
 #include <stdbool.h>
 #include <vconf.h>
 #include <vconf-keys.h>
 #include <setting.h>
 
+#include "lbs_dbus.h"
 #include "battery-monitor.h"
 #include "battery-monitor_log.h"
 
@@ -573,11 +573,11 @@ void bm_init(void *data)
        if (!ht_lbs_client)
                _E("Failed to client to app_id hash table");
 
-       ret = dbus_handle_add_dbus_object(NULL, DBUS_LBSSERVER_BM_PATH, &bm_lbs_dbus_interface);
+       ret = lbs_dbus_add_dbus_object(NULL, DBUS_LBSSERVER_BM_PATH, &bm_lbs_dbus_interface);
        if (ret < 0)
                _E("Failed to init dbus method: %d", ret);
 
-       if (dbus_handle_register_dbus_object_all(NULL) < 0)
+       if (lbs_dbus_register_dbus_object_all(NULL) < 0)
                _E("Failed to register dbus method: %d", ret);
 
        gps_state = bm_get_gps_state();
@@ -629,7 +629,7 @@ void bm_exit(void *data)
 
        int ret;
 
-       ret = dbus_handle_unregister_dbus_object(NULL, DBUS_LBSSERVER_BM_PATH);
+       ret = lbs_dbus_unregister_dbus_object(NULL, DBUS_LBSSERVER_BM_PATH);
        if (ret < 0)
                _E("Failed to unregister dbus object: %d", ret);
 
diff --git a/lbs-server/src/battery-monitor/lbs_dbus.c b/lbs-server/src/battery-monitor/lbs_dbus.c
new file mode 100755 (executable)
index 0000000..03a83b6
--- /dev/null
@@ -0,0 +1,858 @@
+/*
+ * lbs-server
+ *
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+
+#include "lbs_dbus.h"
+#include "battery-monitor_log.h"
+
+/* 10 seconds */
+#define DBUS_REPLY_TIMEOUT     (10000)
+
+static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM;
+static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static GBusType dbus_handle_get_default_bus_type(void)
+{
+       GBusType type;
+
+       pthread_mutex_lock(&g_mutex);
+       type = g_default_bus_type;
+       pthread_mutex_unlock(&g_mutex);
+
+       return type;
+}
+
+/* basic information */
+typedef struct {
+       GDBusConnection *conn;
+       GBusType bus_type;
+       gboolean priv;
+       GList *list_names;      /* dbus_name */
+       GList *list_object;     /* dbus_object_handle_s */
+       pthread_mutex_t mutex;
+} dbus_handle_s;
+
+/* path + interfaces */
+typedef struct {
+       dbus_handle_s *dh;      /* dbus handle */
+       const char *path;       /* object path */
+       GList *list_ifaces;     /* dbus_interface_s */
+} dbus_object_handle_s;
+
+typedef struct {
+       dbus_object_handle_s *oh;       /* object handle */
+       const char *name;       /* interface name */
+       GList *list_methods;    /* const dbus_method_s */
+       guint reg_id;
+       int modified;
+} dbus_interface_s;
+
+#define get_dh_from_oh(oh) ((dbus_object_handle_s*)oh)->dh
+
+/* global shared bus : system, session */
+static dbus_handle_s g_dh[2];
+
+static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type);
+
+static dbus_handle_s * _dbus_handle_get_default_connection(void)
+{
+       return _dbus_handle_get_connection(dbus_handle_get_default_bus_type());
+}
+
+#define dbus_handle_lock(handle) do {\
+       assert(handle);\
+       pthread_mutex_lock(&((handle)->mutex));\
+} while (0);
+
+#define dbus_handle_unlock(handle) do {\
+       assert(handle);\
+       pthread_mutex_unlock(&(handle)->mutex);\
+} while (0);
+
+#define dcl_dbus_handle() dbus_handle_s *dh = (dbus_handle_s *)handle;
+
+static dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path);
+static dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name);
+static dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name);
+
+static dbus_interface_s *_iface_u_to_s(const dbus_interface_u *iface_u)
+{
+       dbus_interface_s *iface = NULL;
+
+       if (!iface_u || !iface_u->methods) {
+               _E("param is null");
+               return NULL;
+       }
+
+       iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s));
+       if (!iface) {
+               _E("failed to calloc");
+               return NULL;
+       }
+
+       iface->name = iface_u->name;
+       iface->modified = TRUE;
+
+       for (int i = 0 ; i < iface_u->nr_methods; ++i) {
+               //_D("attached %s:%p", iface_u->methods[i].member, iface_u->methods[i].func);
+               iface->list_methods = g_list_prepend(iface->list_methods, (void*)(iface_u->methods + i));
+       }
+
+       return iface;
+}
+
+static GDBusConnection * _get_bus(GBusType bus_type)
+{
+       GDBusConnection *conn = NULL;
+       GError *err = NULL;
+
+       if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
+               _E("Wrong bus_type %d", bus_type);
+               return NULL;
+       }
+
+       conn = g_bus_get_sync(bus_type, NULL, &err);
+       if (!conn || err) {
+               _E("failed to get bus:type:%d, %s\n", bus_type, err->message);
+               g_error_free(err);
+               return NULL;
+       }
+
+       return conn;
+}
+
+/* ref cout is 1 */
+static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type)
+{
+       int ibus = bus_type - 1;
+       dbus_handle_s *dh = NULL;
+
+       if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
+               _E("Unknown bus type %d", bus_type);
+               return NULL;
+       }
+       dh = &g_dh[ibus];
+
+       dbus_handle_lock(dh);
+
+       if (!dh->conn) {
+               dh->conn = _get_bus(bus_type);
+               if (!dh->conn) {
+                       dbus_handle_unlock(dh);
+                       return NULL;
+               }
+               dh->priv = FALSE;
+               dh->bus_type = bus_type;
+       }
+
+       dbus_handle_unlock(dh);
+
+       return dh;
+}
+
+#define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0)
+#define buf_block_size 8192
+
+#define buf_check_space_realloc(buf, nwrite, buf_len) do {\
+       if ((nwrite >= buf_len - 1024)) {\
+               if (buf_len >= buf_block_size * 10) {\
+                       _E("buf is too big to allocate. %d", buf_len);\
+               } else {\
+                       _E("buf_check_space_realloc");\
+                       char *tmp = NULL;\
+                       buf_len += buf_block_size;\
+                       tmp = (char *)realloc(buf, buf_len);\
+                       if (!tmp) {\
+                               _E("failed to realloc");\
+                       } else\
+                               buf = tmp;\
+               } \
+       } \
+} while (0);
+
+/* cal index of end of brace */
+static int _check_brace(const char * expr)
+{
+       int len = 0;
+       char qu[128];
+       int qucnt = 0;
+
+       if (!expr)
+               return -1;
+
+       len = strlen(expr);
+
+       if (expr[0] != '(' && expr[0] != '{')
+               return -1;
+
+       for (int i = 0 ; i < len; ++i) {
+
+               if (expr[i] == '(' || expr[i] == '{') {
+                       qu[qucnt++] = expr[i];
+                       if (qucnt >= sizeof(qu)) {
+                               _E("queue is too large. %s", expr);
+                               return -1;
+                       }
+                       continue;
+               }
+
+               if (expr[i] == ')' || expr[i] == '}') {
+                       char ch;
+
+                       if (qucnt > 0)
+                               ch = qu[qucnt-1];
+                       else
+                               return -1;
+
+                       if (expr[i] == ')') {
+                               if (ch == '(')
+                                       --qucnt;
+                               else
+                                       return -1;
+                       } else if (expr[i] == '}') {
+                               if (ch == '{')
+                                       --qucnt;
+                               else
+                                       return -1;
+                       } else
+                               return -1;
+
+                       if (qucnt == 0)
+                               return i + 1;
+               }
+       }
+
+       return -1;
+}
+
+/*
+in : interface_s
+out : xml format
+*/
+static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces)
+{
+       int nwrite = 0;
+       int len_args;
+       char *buf = NULL;
+       const dbus_method_s *pmethod;
+       int buf_len = buf_block_size;
+
+       if (!interfaces) {
+               _E("interfaces is null");
+               return -1;
+       }
+
+       // todo : check dbus naming rule for interface name. ?
+       if (!interfaces->name) {
+               _E("wrong interface name");
+               return -1;
+       }
+       if (!interfaces->list_methods) {
+               _E("no methods");
+               return -1;
+       }
+
+       buf = (char *)malloc(buf_len);
+       if (!buf) {
+               _E("buf is null. not enough memory\n");
+               return -1;
+       }
+
+       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "<node>""\n""\t""<interface name='%s'>""\n", interfaces->name);
+
+       /* members */
+       for (GList *item = g_list_first(interfaces->list_methods); item != NULL; item = g_list_next(item)) {
+               pmethod = (const dbus_method_s *)item->data;
+               if (!pmethod)
+                       continue;
+
+               /* check free space of buf */
+               buf_check_space_realloc(buf, nwrite, buf_len);
+
+               if (pmethod->signature_in == NULL && pmethod->signature_out == NULL) {
+                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'/>""\n", pmethod->member);
+                       continue;
+               }
+
+               /* <method name='###'> */
+               nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'>""\n", pmethod->member);
+
+               /* in args */
+               len_args = pmethod->signature_in ? strlen(pmethod->signature_in) : 0;
+               for (int m = 0; m < len_args; ++m) {
+                       // todo
+                       // array a(), as, ay ?
+                       if (pmethod->signature_in[m] == 'a') {
+                               int ei; //end index
+                               ei = _check_brace(pmethod->signature_in + m + 1);
+                               if (ei > 0) {
+                                       char tmp[128] = {0,};
+                                       strncpy(tmp, pmethod->signature_in + m, ei + 1);
+                                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='in'/>""\n", tmp, m);
+                                       m += ei;
+                                       continue;
+                               } else {
+                                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], pmethod->signature_in[m+1], m);
+                                       m += 1;
+                                       continue;
+                               }
+                       }
+                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], m);
+               }
+
+               /* out args */
+               len_args = pmethod->signature_out ? strlen(pmethod->signature_out) : 0;
+               for (int m = 0; m < len_args; ++m) {
+                       // array
+                       // todo: container type
+                       if (pmethod->signature_out[m] == 'a') {
+                               int ei; //end index
+                               ei = _check_brace(pmethod->signature_out + m + 1);
+                               if (ei > 0) {
+                                       char tmp[128] = {0,};
+                                       strncpy(tmp, pmethod->signature_out + m, ei + 1);
+                                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='out'/>""\n", tmp, m);
+                                       m += ei;
+                                       continue;
+                               } else {
+                                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], pmethod->signature_out[m+1], m);
+                                       m += 1;
+                                       continue;
+                               }
+                       }
+                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], m);
+               }
+
+               /* </method> */
+               nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""</method>""\n");
+       }
+
+       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""</interface>""\n""</node>""");
+
+       *xml = buf;
+
+       /* todo: delete log */
+#if 0
+       if (nwrite <= 512)
+               _E("%s", buf);
+       else
+               _E("%s", buf + nwrite - 512);
+#endif
+       return 0;
+}
+
+static gint _compare_dbus_object(gconstpointer a, gconstpointer b)
+{
+       dbus_object_handle_s * pa = (dbus_object_handle_s *)a;
+       if (!pa->path || !((const char*)b))
+               return -1;
+       return strcmp(pa->path, (const char*)b);
+}
+
+static gint _compare_dbus_interface(gconstpointer a, gconstpointer b)
+{
+       dbus_interface_s * pa = (dbus_interface_s *)a;
+       if (!pa->name || !((const char*)b))
+               return -1;
+       return strcmp(pa->name, (const char*)b);
+}
+
+static gint _compare_dbus_method(gconstpointer a, gconstpointer b)
+{
+       dbus_method_s *pa = (dbus_method_s*)a;
+       if (!pa->member || !((const char*)b))
+               return -1;
+       return strcmp(pa->member, (const char*)b);
+}
+
+static dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path)
+{
+       if (!list_obj || !obj_path)
+               return NULL;
+
+       GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object);
+       if (!item)
+               return NULL;
+
+       return (dbus_object_handle_s *)item->data;
+}
+
+static dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name)
+{
+       if (!list_iface || !iface_name)
+               return NULL;
+
+       GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface);
+       if (!item)
+               return NULL;
+
+       return (dbus_interface_s *)item->data;
+}
+
+static dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name)
+{
+       if (!list_methods || !method_name)
+               return NULL;
+
+       GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method);
+       if (!item)
+               return NULL;
+
+       return (dbus_method_s *)item->data;
+}
+
+static void _free_func_object(gpointer data)
+{
+       dbus_interface_s *ih = (dbus_interface_s *)data;
+       dbus_object_handle_s *oh = NULL;
+
+       if (!ih) {
+               _E("interface handle is null");
+               assert(0); // something wrong
+               return ;
+       }
+
+       _E("unregister interface %s", ih->name);
+
+       /* just free list, not data(static dbus_method_s) */
+       g_list_free(ih->list_methods);
+
+       oh = ih->oh;
+       if (!oh) {
+               _E("object handle is null");
+               assert(0); // something wrong
+               return ;
+       }
+
+       /* remove ih from list_ifaces */
+       oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
+
+       /* interface_s is copy of interface_u */
+       free(ih);
+
+       /* remove oh from list_object */
+       if (!oh->list_ifaces) {
+               oh->dh->list_object = g_list_remove(oh->dh->list_object, oh);
+               free(oh);
+       }
+}
+
+static int _dbus_handle_attach_object(dbus_handle_s *dh, const char *obj_path, dbus_interface_s *iface)
+{
+       dbus_object_handle_s *oh = NULL;
+
+       if (!dh || !obj_path || !iface) {
+               _E("failed to attache object. wrong parameter");
+               return -1;
+       }
+
+       /* find object handle */
+       if (dh->list_object)
+               oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
+
+       if (!oh) {
+               oh = (dbus_object_handle_s*)calloc(1, sizeof(dbus_object_handle_s));
+               if (!oh) {
+                       _E("failed to calloc");
+                       return -1;
+               }
+               oh->dh = dh;
+               oh->path = obj_path;
+
+               /* attach object */
+               dh->list_object = g_list_prepend(dh->list_object, oh);
+       }
+
+       iface->oh = oh;
+       /* attach interface */
+       oh->list_ifaces = g_list_prepend(oh->list_ifaces, iface);
+
+       return 0;
+}
+
+static void _method_call_handler(GDBusConnection *conn,
+                               const gchar *sender,
+                               const gchar *path,
+                               const gchar *iface,
+                               const gchar *name,
+                               GVariant *param,
+                               GDBusMethodInvocation *invocation,
+                               gpointer user_data)
+{
+       dbus_interface_s *iface_s = (dbus_interface_s *)user_data;
+       const dbus_method_s *methods;
+       GVariant *reply = NULL;
+
+       /* todo: ghash ? */
+       methods = _dbus_handle_lookup_method(iface_s->list_methods, name);
+       if (methods) {
+               reply = methods->func(conn, sender, path, iface, name, param, invocation, get_dh_from_oh(iface_s->oh));
+
+               /* async, maybe they will reply...maybe.. */
+               if (!reply)
+                       return;
+       } else {
+               _E("no methods");
+       }
+
+       g_dbus_method_invocation_return_value(invocation, reply);
+}
+
+static GDBusInterfaceVTable path_vtable = {_method_call_handler};
+
+
+/*
+before register object, attach object into dbus handle
+_dbus_handle_attach_object()
+*/
+static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, dbus_interface_s *iface)
+{
+       dcl_dbus_handle();
+       int ret = 0;
+       char *buf = NULL;
+       GError *err = NULL;
+       GDBusNodeInfo * nodeinfo = NULL;
+       GDBusInterfaceInfo *ifaceinfo = NULL;
+
+       if (!obj_path || !iface) {
+               _E("wrong parameter\n");
+               return -1;
+       }
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+       if (!dh->conn) {
+               _E("connection is null\n");
+               return -1;
+       }
+
+       ret = _get_xml_from_interfaces(&buf, iface);
+       if (ret < 0) {
+               _E("failed to make xml format");
+               goto err;
+       }
+
+       /* todo: delete this */
+#if 0
+       if (strlen(buf) <= 512) {
+               _E("%s", buf);
+       } else {
+               _E("%s", buf + strlen(buf) - 512);
+       }
+#endif
+
+       nodeinfo = g_dbus_node_info_new_for_xml(buf, &err);
+       if (!nodeinfo || err) {
+               _E("failed to make introspection data:err:%s:xml:%s\n", err->message, buf);
+               ret = -1;
+               goto err;
+       }
+
+       ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, iface->name);
+       if (!ifaceinfo) {
+               _E("failed to g_dbus_node_info_lookup_interface");
+               ret = -1;
+               goto err;
+       }
+
+       /*
+               path own single interface
+               if interface is already registered, then failed.
+               g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered
+       */
+       ret = g_dbus_connection_register_object(dh->conn,
+                                               obj_path,
+                                               ifaceinfo/*ref 2*/,
+                                               &path_vtable,
+                                               (void*)iface,
+                                               _free_func_object,
+                                               &err);
+       if (err) {
+               _E("failed to register object:err:%s:\n", err->message);
+               ret = -1;
+               goto err;
+       }
+
+       iface->reg_id = ret;
+       iface->modified = FALSE;
+
+err:
+       /* todo: detach object */
+       //_dbus_handle_detach_object(dh, obj_path, iface);
+       /* attach interface before register object */
+       /*ret = _dbus_handle_detach_object(dh, obj_path, iface);
+       if (ret < 0) {
+               _E("failed to attach object");
+               goto err;
+       }*/
+
+       if (nodeinfo)
+               g_dbus_node_info_unref(nodeinfo);
+       if (buf)
+               free(buf);
+       if (err)
+               g_error_free(err);
+
+       return ret;
+}
+
+int lbs_dbus_unregister_dbus_object(dbus_handle_h handle, const char *obj_path)
+{
+       dcl_dbus_handle();
+       dbus_object_handle_s *oh = NULL;
+       int ret = 0;
+
+       if (!obj_path)
+               return -1;
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+       if (!dh->list_object) {
+               _E("list_object is empty");
+               return 0;
+       }
+
+       oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
+       if (!oh) {
+               _E("no object with name %s", obj_path);
+               return -1;
+       }
+
+       /* unregister every interface of object*/
+       for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) {
+               dbus_interface_s *ih = item->data;
+               if (!ih) {
+                       _E("this is error");
+                       assert(0);
+               }
+
+               /* remove ih from list_ifaces */
+               if (!ih->reg_id) {
+                       item = g_list_previous(item);
+
+                       /* remove and free link */
+                       oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
+
+                       /* free list_methods */
+                       g_list_free(ih->list_methods);
+
+                       /* free data */
+                       free(ih);
+                       continue;
+               }
+
+               /* unregister object by id */
+               ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id);
+               if (!ret)
+                       _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id);
+       }
+
+       return 0;
+}
+
+/*
+add object temporarily.
+lbs_dbus_register_dbus_object_all register every objects on connection.
+
+return registered method count
+*/
+int lbs_dbus_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
+{
+       dcl_dbus_handle();
+       dbus_object_handle_s *oh = NULL;
+       dbus_interface_s *ih = NULL;
+       int cnt;
+
+       if (!obj_path || !iface_u) {
+               _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
+               return -1;
+       }
+       if (iface_u && (!iface_u->name || !iface_u->methods)) {
+               _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
+               return -1;
+       }
+
+       cnt = iface_u->nr_methods;
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+
+       if (!dh->conn) {
+               _E("failed to register method. connection is null\n");
+               return -1;
+       }
+
+       /* if there are no object list, just add */
+       if (!dh->list_object) {
+               if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
+                       _E("failed to attach object");
+                       return -1;
+               }
+               goto out;
+       }
+
+       oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
+       /* if there are no matched object, just add */
+       if (!oh) {
+               if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
+                       _E("failed to attach object");
+                       return -1;
+               }
+               goto out;
+       }
+
+       /* this is an error, interface must have one or more item ? */
+       if (!oh->list_ifaces) {
+               _E("error. list_ifaces is null\n");
+               assert(0);
+               goto out;
+       }
+
+       ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
+       /* if there are no matched interface, just add */
+       if (!ih) {
+               if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
+                       _E("failed to attach object");
+                       return -1;
+               }
+               goto out;
+       }
+
+       /*  todo:
+               1. unregister interface
+               2. update interface and methods
+               3. register interface
+       */
+       if (ih->reg_id) {
+               _E("interface already registered, ignore new interface");
+               return -1;
+       }
+
+       /* attach new methods */
+       cnt = 0;
+       for (int i = 0; i < iface_u->nr_methods; ++i) {
+               GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method);
+               if (!item) {
+                       //_D("attached %s", iface_u->methods[i].member);
+                       ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i));
+                       ++cnt;
+               }
+       }
+
+       if (cnt)
+               ih->modified = TRUE;
+
+out:
+       /*todo: delete debugging log */
+       //if (dh && dh->list_object)
+       //      _D("obj list len %d", g_list_length(dh->list_object));
+       //if (oh && oh->list_ifaces)
+       //      _D("iface list len %d", g_list_length(oh->list_ifaces));
+       //if (ih && ih->list_methods)
+       //      _D("method list len %d", g_list_length(ih->list_methods));
+
+       return cnt;
+}
+
+int lbs_dbus_register_dbus_object_all(dbus_handle_h handle)
+{
+       dcl_dbus_handle();
+       dbus_object_handle_s *oh = NULL;
+       dbus_interface_s *ih = NULL;
+       int ret_dbus = 0;
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+       if (!dh->conn) {
+               _E("connection is null\n");
+               return -1;
+       }
+
+       if (!dh->list_object) {
+               _E("obj list is empty");
+               return -1;
+       }
+
+       /*if (dh && dh->list_object)
+               _D("obj list len %d", g_list_length(dh->list_object));*/
+
+       for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) {
+               oh = (dbus_object_handle_s *)item->data;
+
+               if (!oh) {
+                       _E("something wrong");
+                       assert(0);
+               }
+               if (!oh->list_ifaces) {
+                       _E("path %s: list_ifaces are null", oh->path);
+                       goto err;
+               }
+
+               //_D("iface list len %d", g_list_length(oh->list_ifaces));
+
+               for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) {
+                       ih = (dbus_interface_s *)li->data;
+
+                       /* if there are no modification, goto next */
+                       if (!ih->modified)
+                               continue;
+
+                       /* todo: if already registered interface, unregister first */
+
+                       /*_E("interface %s:", ih->name);
+                       if (ih && ih->list_methods)
+                               _D("method list len %d", g_list_length(ih->list_methods));*/
+
+                       ret_dbus = _dbus_handle_register_dbus_object(dh, oh->path, ih);
+                       if (ret_dbus <= 0)
+                               _E("failed to register dbus object%d", ret_dbus);
+
+               }
+       }
+       return 0;
+err:
+
+       // todo: delete all updates
+
+       return -1;
+}
diff --git a/lbs-server/src/battery-monitor/lbs_dbus.h b/lbs-server/src/battery-monitor/lbs_dbus.h
new file mode 100755 (executable)
index 0000000..0b10c6f
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * lbs-server
+ *
+ * Copyright (c) 2011-2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef _LBS_DBUS_H_
+#define _LBS_DBUS_H_
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <glib-unix.h>
+#include <gio/gunixfdlist.h>
+#include <stdarg.h>
+#include <assert.h>
+
+typedef struct {
+       const unsigned char *data;
+       int size;
+} dbus_byte;
+
+
+typedef void *dbus_handle_h;
+
+typedef void *dbus_object_handle_h;
+
+typedef struct {
+       const char *member;
+       const char *signature_in;
+       const char *signature_out;
+       GVariant *(*func)       (GDBusConnection *conn,
+                               const gchar *sender,
+                               const gchar *path,
+                               const gchar *iface,
+                               const gchar *name,
+                               GVariant *param,
+                               GDBusMethodInvocation *invocation,
+                               gpointer user_data);
+} dbus_method_s;
+
+typedef struct {
+       dbus_object_handle_h oh;
+       const char *name;
+       const dbus_method_s *methods;
+       int nr_methods;
+} dbus_interface_u;
+
+typedef struct {
+       guint   pid;
+       guint   uid;
+       gchar  *unique_name;
+       gchar  *sec_label;
+} GDBusCredentials;
+
+#define g_variant_get_safe(gvar, signature, ...) ((gvar && (g_strcmp0(signature, g_variant_get_type_string(gvar)) == 0)) ? g_variant_get(gvar, signature, __VA_ARGS__), TRUE : FALSE)
+
+#define dbus_handle_new_g_variant_tuple() g_variant_new_tuple(NULL, 0)
+
+typedef void (*destroy_notified)(void *data);
+
+typedef void (*dbus_pending_cb)(GVariant *var, void *user_data, GError *err);
+
+typedef struct {
+       dbus_pending_cb func;
+       void *data;
+} pending_call_data;
+
+
+int lbs_dbus_unregister_dbus_object            (dbus_handle_h handle,
+                                               const char *obj_path);
+
+int lbs_dbus_add_dbus_object                   (dbus_handle_h handle,
+                                               const char *obj_path,
+                                               const dbus_interface_u *iface_u);
+
+int lbs_dbus_register_dbus_object_all  (dbus_handle_h handle);
+
+#endif
index 1bc6d7b..8b1757c 100755 (executable)
@@ -27,7 +27,6 @@ BuildRequires: pkgconfig(libtzplatform-config)
 BuildRequires: pkgconfig(capi-network-connection)
 BuildRequires:  pkgconfig(hal-api-common)
 BuildRequires:  pkgconfig(hal-api-location)
-BuildRequires: pkgconfig(libsyscommon)
 BuildRequires: pkgconfig(gmock)