Remove vconf key define which moved to vconf internal package
[platform/core/telephony/telephony-daemon.git] / src / main.c
index efd2959..e04dc9f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * telephony-daemon
  *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
  *
  * Contact: Ja-young Gu <jygu@samsung.com>
  *
  * limitations under the License.
  */
 
-#include <systemd/sd-daemon.h>
+#ifdef TIZEN_DEBUG_ENABLE
+#include "monitor.h"
+#endif
+
+#include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <time.h>
+
 #include <dlfcn.h>
 #include <getopt.h>
-#include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/sysinfo.h>
 
 #include <glib.h>
-#include <glib-object.h>
 #include <dlog.h>
+#include <vconf.h>
 
 #include <tcore.h>
 #include <plugin.h>
 #include <server.h>
-#include <util.h>
-#include <log.h>
-
-#include "monitor.h"
 
 #ifndef DAEMON_VERSION
 #define DAEMON_VERSION "unknown"
 #endif
 
-static Server *_server;
+#ifndef DEFAULT_PLUGINS_PATH
+#define DEFAULT_PLUGINS_PATH "/usr/lib/telephony/plugins/"
+#endif
+
+#define NOTUSED(var) (var = var)
+
+static Server *_server = NULL;
+
+static void __usage_info(const char *exec)
+{
+       printf("Usage: %s [OPTION]... [PLUGIN_PATH]\n", exec);
+       printf("\n");
+       printf("  -T, --testload\t run with plugin load test mode and exit\n");
+       printf("  -h, --help\t\t display this help and exit\n");
+       printf("\n");
+}
 
 void tcore_log(enum tcore_log_type type, enum tcore_log_priority priority, const char *tag, const char *fmt, ...)
 {
        va_list ap;
        char buf[1024];
 
-       va_start(ap, fmt);
-       vsnprintf(buf, 1023, fmt, ap);
-       va_end(ap);
+       switch (type) {
+       case TCORE_LOG_TYPE_RADIO: {
+               if (priority >= TCORE_LOG_INFO) {
+                       va_start(ap, fmt);
+                       vsnprintf(buf, 1023, fmt, ap);
+                       va_end(ap);
+                       __dlog_print(LOG_ID_RADIO, priority, tag, buf);
+               } else {
+               #ifdef TIZEN_DEBUG_ENABLE
+                       va_start(ap, fmt);
+                       vsnprintf(buf, 1023, fmt, ap);
+                       va_end(ap);
+                       __dlog_print(LOG_ID_RADIO, priority, tag, buf);
+               #endif
+               }
+       } break;
+
+       case TCORE_LOG_TYPE_TIME_CHECK: {
+       #ifdef TIZEN_DEBUG_ENABLE /* User Mode should not log performance data */
+               float a = 0.00, b = 0.00;
+               int next = 0;
+               FILE *fp = fopen("/proc/uptime", "r");
+               g_return_if_fail(NULL != fp);
+
+               if(fscanf(fp, "%f %f", &a, &b)){};
+               fclose(fp);
+               next = sprintf(buf, "[UPTIME] %f ", a);
+               if (next < 0)
+                       return;
+
+               va_start(ap, fmt);
+               vsnprintf(buf + next, 1023 - next, fmt, ap);
+               va_end(ap);
+               __dlog_print(LOG_ID_RADIO, priority, tag, buf);
+       #endif
+       } break;
+
+       default:
+       break;
+       }
+}
+
+static void glib_log(const gchar *log_domain, GLogLevelFlags log_level,
+               const gchar *msg, gpointer user_data)
+{
+       NOTUSED(log_domain);
+       NOTUSED(log_level);
+       NOTUSED(user_data);
+
+       __dlog_print (LOG_ID_RADIO, DLOG_ERROR, "GLIB", msg);
+}
+
+#ifdef TIZEN_DEBUG_ENABLE
+static void telephony_signal_handler(int signo)
+{
+       if (!_server)
+               return;
+
+       switch (signo) {
+       case SIGUSR1: {
+               monitor_server_state(_server);
+       } break;
+
+       case SIGTERM: {
+               tcore_server_exit(_server);
+       } break;
+
+       default: {
+               warn("*~*~*~* Unhandled Signal: [%d] *~*~*~*", signo);
+       } break;
+       } /* end switch */
 
-       __dlog_print(type, priority, tag, buf);
+       return;
 }
+#endif
+
+static void __log_uptime()
+{
+       float a = 0.00, b = 0.00;
+       FILE *fp = fopen("/proc/uptime", "r");
+       g_return_if_fail(NULL != fp);
+       info("scanned %d items", fscanf(fp, "%f %f", &a, &b));
+       info("proc uptime = %f idletime = %f\n", a, b);
+       fclose(fp);
+}
+
+static gboolean __init_plugin(TcorePlugin *plugin)
+{
+       const struct tcore_plugin_define_desc *desc = tcore_plugin_get_description(plugin);
+
+       if (!desc || !desc->init)
+               return FALSE;
 
-static gboolean load_plugins(Server *s, const char *path, int flag_test_load)
+       if (!desc->init(plugin)) { /* TODO: Remove plugin from server */
+               char *plugin_name = tcore_plugin_get_filename(plugin);
+               if (NULL != plugin_name) {
+                       err("plugin(%s) init failed.", plugin_name);
+                       free(plugin_name);
+               }
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean init_plugins(Server *s)
 {
-       const gchar *file;
-       char *filename;
-       GDir *dir;
-       void *handle;
-       GSList *list;
+       GSList *list = tcore_server_ref_plugins(s);
+
+       while (list != NULL) {
+               if (G_UNLIKELY(FALSE == __init_plugin(list->data))) {
+                       list = g_slist_next(list);
+                       continue;
+               }
+               list = g_slist_next(list);
+       }
+
+       return TRUE;
+}
+
+static void *__load_plugin(const gchar *filename, struct tcore_plugin_define_desc **desc_out)
+{
+       void *handle = NULL;
+       struct tcore_plugin_define_desc *desc = NULL;
        struct stat stat_buf;
        char file_date[27];
 
-       TcorePlugin *p;
-       struct tcore_plugin_define_desc *desc;
+       handle = dlopen(filename, RTLD_LAZY);
+       if (G_UNLIKELY(NULL == handle)) {
+               err("fail to load '%s': %s", filename, dlerror());
+               return NULL;
+       }
+
+       desc = dlsym(handle, "plugin_define_desc");
+       if (G_UNLIKELY(NULL == desc)) {
+               err("fail to load symbol: %s", dlerror());
+               dlclose(handle);
+               return NULL;
+       }
+
+       dbg("%s plugin", desc->name);
+       dbg(" - path = %s", filename);
+       dbg(" - version = %d", desc->version);
+       dbg(" - priority = %d", desc->priority);
 
-       if ((path == NULL) || (s == NULL))
+       memset(&stat_buf, 0x00, sizeof(stat_buf));
+       memset(&file_date, '\0', sizeof(file_date));
+
+       if (0 == stat(filename, &stat_buf)) {
+               if (NULL != ctime_r(&stat_buf.st_mtime, file_date)) {
+                       if (1 < strlen(file_date))
+                               file_date[strlen(file_date)-1] = '\0';
+                       dbg(" - date = %s", file_date);
+               }
+       }
+
+       if (G_LIKELY(desc->load)) {
+               if (G_UNLIKELY(FALSE == desc->load())) {
+                       warn("false return from load(). skip this plugin");
+                       dlclose(handle);
+                       return NULL;
+               }
+       }
+
+       if (NULL != desc_out)
+               *desc_out = desc;
+
+       return handle;
+}
+
+static gboolean load_plugins(Server *s, const char *path, gboolean flag_test_load)
+{
+       const gchar *file = NULL;
+       gchar *filename = NULL;
+       GDir *dir = NULL;
+       void *handle = NULL;
+       struct tcore_plugin_define_desc *desc = NULL;
+
+       if (!path || !s)
                return FALSE;
 
        dir = g_dir_open(path, 0, NULL);
-       if (dir == NULL)
+       if (!dir)
                return FALSE;
 
        while ((file = g_dir_read_name(dir)) != NULL) {
                if (g_str_has_prefix(file, "lib") == TRUE
-                               || g_str_has_suffix(file, ".so") == FALSE)
+                       || g_str_has_suffix(file, ".so") == FALSE)
                        continue;
 
                filename = g_build_filename(path, file, NULL);
 
-               handle = dlopen(filename, RTLD_NOW);
-               if (handle == NULL) {
-                       dbg("fail to load '%s': %s", filename, dlerror());
+               /* Load a plugin */
+               if (G_UNLIKELY((handle = __load_plugin(filename, &desc)) == NULL)) {
                        g_free(filename);
                        continue;
                }
 
+               /* Don't add to server if flag_test_load */
                if (flag_test_load) {
                        dbg("success to load '%s'", filename);
                        dlclose(handle);
@@ -102,148 +271,97 @@ static gboolean load_plugins(Server *s, const char *path, int flag_test_load)
                        continue;
                }
 
-               desc = dlsym(handle, "plugin_define_desc");
-               if (desc == NULL) {
-                       dbg("fail to load symbol: %s", dlerror());
-                       dlclose(handle);
-                       g_free(filename);
-                       continue;
-               }
-
-               dbg("%s plugin", desc->name);
-               dbg(" - path = %s", filename);
-               dbg(" - version = %d", desc->version);
-               dbg(" - priority = %d", desc->priority);
-
-               memset(&stat_buf, 0, sizeof(struct stat));
-               if (stat(filename, &stat_buf) == 0) {
-                       if (ctime_r(&stat_buf.st_mtime, file_date) != NULL) {
-                               if (strlen(file_date) > 1)
-                                       file_date[strlen(file_date)-1] = '\0';
-
-                               dbg(" - date = %s", file_date);
-                       }
-               }
-
-               if (desc->load) {
-                       if (desc->load() == FALSE) {
-                               dbg("false return from load(). skip this plugin");
-                               dlclose(handle);
-                               g_free(filename);
-                               continue;
-                       }
-               }
-
-               p = tcore_plugin_new(s, desc, filename, handle);
-               tcore_server_add_plugin(s, p);
+               tcore_server_add_plugin(s, tcore_plugin_new(s, desc, filename, handle));
 
                dbg("%s added", desc->name);
                g_free(filename);
        }
        g_dir_close(dir);
 
-       info("plugin load finished");
-
-       list = tcore_server_ref_plugins(s);
-       for (; list; list = list->next) {
-               p = list->data;
-               if (p == NULL)
-                       continue;
-
-               desc = (struct tcore_plugin_define_desc *)tcore_plugin_get_description(p);
-               if (desc == NULL)
-                       continue;
-
-               if (desc->init == NULL)
-                       continue;
-
-               if (desc->init(p) == FALSE) {
-                       dbg("plugin(%s) init failed.", tcore_plugin_get_filename(p));
-               }
-       }
-
-       info("plugin init finished");
-
        return TRUE;
 }
 
-static void usage(const char *name)
-{
-       printf("Usage: %s [OPTION]... [PLUGIN_PATH]\n", name);
-       printf("\n");
-       printf("  -T, --testload\t run with plugin load test mode and exit\n");
-       printf("  -h, --help\t\t display this help and exit\n");
-       printf("\n");
-}
-
-static void on_signal_usr1(int signo)
-{
-       if (_server == NULL)
-               return;
-
-       monitor_server_state(_server);
-}
-
 int main(int argc, char *argv[])
 {
-       struct sigaction sigact_usr1;
-       Server *s;
-       int flag_test_load = 0;
-       int opt;
-       int opt_index;
+#ifdef TIZEN_DEBUG_ENABLE
+       struct sigaction sigact;
+#endif
+       Server *s = NULL;
+       gboolean flag_test_load = FALSE;
+       int opt = 0, opt_index = 0, ret_code = EXIT_SUCCESS;
+       int daemon_load_count = 0;
        struct option options[] = {
-                       { "help", 0, 0, 0 },
-                       { "testload", 0, &flag_test_load, 1 },
-                       { 0, 0, 0, 0 }
+               { "help", 0, 0, 0 },
+               { "testload", 0, &flag_test_load, 1 },
+               { 0, 0, 0, 0 }
        };
-       char *plugin_path = "/usr/lib/telephony/plugins/";
-       char *tcore_ver;
-       struct sysinfo info;
+       const char *plugin_path = DEFAULT_PLUGINS_PATH;
+       char *tcore_ver = NULL;
+       struct sysinfo sys_info;
 
-       if (sysinfo(&info) == 0) {
-               info("uptime: %ld secs", info.uptime);
-       }
+       TIME_CHECK("Starting Telephony");
 
-       info("daemon version: %s", DAEMON_VERSION);
+       /* System Uptime */
+       if (0 == sysinfo(&sys_info))
+               info("uptime: %ld secs", sys_info.uptime);
+       __log_uptime();
 
+       /* Version Info */
        tcore_ver = tcore_util_get_version();
+       info("daemon version: %s", DAEMON_VERSION);
        info("libtcore version: %s", tcore_ver);
        free(tcore_ver);
-
-       sigact_usr1.sa_handler = on_signal_usr1;
-       sigemptyset(&sigact_usr1.sa_mask);
-       sigaddset(&sigact_usr1.sa_mask, SIGUSR1);
-       sigact_usr1.sa_flags = 0;
-
-       if (sigaction(SIGUSR1, &sigact_usr1, NULL) < 0) {
+       info("glib version: %u.%u.%u", glib_major_version, glib_minor_version, glib_micro_version);
+
+       /* Telephony reset handling*/
+       vconf_get_int(VCONFKEY_TELEPHONY_DAEMON_LOAD_COUNT,&daemon_load_count);
+       daemon_load_count++;
+       vconf_set_int(VCONFKEY_TELEPHONY_DAEMON_LOAD_COUNT,daemon_load_count);
+       dbg("daemon load count = [%d]", daemon_load_count);
+
+#ifdef TIZEN_DEBUG_ENABLE
+       /* Signal Registration */
+       sigact.sa_handler = telephony_signal_handler;
+       sigemptyset(&sigact.sa_mask);
+       sigact.sa_flags = 0;
+       if (sigaction(SIGTERM, &sigact, NULL) < 0)
+               warn("sigaction(SIGTERM) failed.");
+       if (sigaction(SIGUSR1, &sigact, NULL) < 0)
                warn("sigaction(SIGUSR1) failed.");
-       }
+#endif
 
-       while (1) {
+       /* Commandline option parser TODO: Replace with GOptionContext */
+       while (TRUE) {
                opt = getopt_long(argc, argv, "hT", options, &opt_index);
 
-               if (opt == -1)
+               if (-1 == opt)
                        break;
 
                switch (opt) {
-                       case 0:
-                               switch (opt_index) {
-                                       case 0: // help
-                                               usage(argv[0]);
-                                               return 0;
-                                               break;
-                               }
-                               break;
-
-                       case 'h':
-                               usage(argv[0]);
+               case 0: {
+                       switch (opt_index) {
+                       case 0: {
+                               __usage_info(argv[0]);
                                return 0;
-                               break;
-
-                       case 'T':
-                               flag_test_load = 1;
-                               break;
-               }
+                       } break;
+                       default: {
+                               warn("unhandled opt_index.");
+                       } break;
+                       } /* end switch */
+               } break;
+
+               case 'h': {
+                       __usage_info(argv[0]);
+                       return 0;
+               } break;
+
+               case 'T': {
+                       flag_test_load = TRUE;
+               } break;
+               default: {
+                       warn("unhandled opt case.");
+               } break;
+               } /* end switch */
        }
 
        if (optind < argc)
@@ -251,43 +369,53 @@ int main(int argc, char *argv[])
 
        info("plugin_path: [%s]", plugin_path);
 
-#if !GLIB_CHECK_VERSION(2,35,0)
+#if !GLIB_CHECK_VERSION(2, 35, 0)
        g_type_init();
 #endif
-#if !GLIB_CHECK_VERSION (2, 31, 0)
+#if !GLIB_CHECK_VERSION(2, 31, 0)
        g_thread_init(NULL);
 #endif
 
        s = tcore_server_new();
-       if (s == NULL) {
+       if (G_UNLIKELY(NULL == s)) {
                err("server_new failed.");
-               goto end;
+               ret_code = EXIT_FAILURE;
+               goto END;
        }
        _server = s;
 
-       if (load_plugins(s, plugin_path, flag_test_load) == FALSE)
-               goto free_end;
+       g_log_set_default_handler(glib_log, s);
 
-       if (flag_test_load)
-               goto free_end;
+       /* Load Plugins */
+       if (G_UNLIKELY(FALSE == load_plugins(s, (const char *)plugin_path, flag_test_load))) {
+               err("load_plugins failed.");
+               ret_code = EXIT_FAILURE;
+               goto END;
+       }
 
-       info("server mainloop start");
+       TIME_CHECK("Loading Plugins Complete");
 
-       /* Notification to systemd */
-       sd_notify(0, "READY=1");
+       if (flag_test_load) {
+               ret_code = EXIT_SUCCESS;
+               goto END;
+       }
 
-       if (tcore_server_run(s) == FALSE) {
-               err("server_run failed.");
+       /* Initialize Plugins */
+       if (G_UNLIKELY(FALSE == init_plugins(s))) {
+               err("init_plugins failed.");
+               ret_code = EXIT_FAILURE;
+               goto END;
        }
 
-       /*
-        * RUNNING
-        */
+       info("server mainloop start");
+       TIME_CHECK("Initializing Plugins Complete. Starting Daemon");
 
-free_end:
-       info("server end");
-       tcore_server_free(s);
+       if (G_UNLIKELY(TCORE_RETURN_SUCCESS != tcore_server_run(s))) {
+               err("server_run failed.");
+               ret_code = EXIT_FAILURE;
+       }
 
-end:
-       return EXIT_SUCCESS;
+END:
+       tcore_server_free(s); _server = NULL;
+       return ret_code;
 }