4 * Copyright 2013 Samsung Electronics Co. Ltd.
5 * Copyright 2013 Intel Corporation.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
27 #include <sys/sysinfo.h>
28 #include <systemd/sd-daemon.h>
41 #ifndef DAEMON_VERSION
42 #define DAEMON_VERSION "unknown"
45 #ifndef DEFAULT_PLUGINS_PATH
46 #define DEFAULT_PLUGINS_PATH "/usr/lib/telephony/plugins/"
49 #define NOTUSED(var) (var = var)
51 static Server *_server = NULL;
53 static void __usage_info(const gchar *exec)
55 printf("Usage: %s [OPTION]... [PLUGIN_PATH]\n", exec);
57 printf(" -T, --testload\t run with plugin load test mode and exit\n");
58 printf(" -h, --help\t\t display this help and exit\n");
62 void tcore_log(enum tcore_log_type type, enum tcore_log_priority priority, const gchar *tag, const gchar *fmt, ...)
68 vsnprintf(buf, 1023, fmt, ap);
71 __dlog_print(type, priority, tag, buf);
74 static void glib_log(const gchar *log_domain, GLogLevelFlags log_level,
75 const gchar *msg, gpointer user_data)
81 __dlog_print (LOG_ID_RADIO, DLOG_ERROR, "GLIB", msg);
85 static void telephony_signal_handler(gint signo)
87 if (_server == NULL) {
88 err("Server is NULL");
94 monitor_server_state(_server);
98 tcore_server_free(_server);
102 warn("*~*~*~* Unhandled Signal: [%d] *~*~*~*", signo);
108 static void __log_uptime()
110 float a = 0.00, b = 0.00;
111 FILE *fp = fopen("/proc/uptime", "r");
112 g_return_if_fail(NULL != fp);
114 info("Scanned %d items", fscanf(fp, "%f %f", &a, &b));
115 info("proc uptime = %f idletime = %f\n", a, b);
120 static gboolean __init_plugin(TcorePlugin *plugin)
122 const struct tcore_plugin_define_desc *desc = tcore_plugin_get_description(plugin);
124 if ((desc == NULL) || (desc->init == NULL)) {
125 err("desc: [%p] desc->init: [%p]", desc, (desc ? desc->init : NULL));
129 if (desc->init(plugin) == FALSE) { /* TODO: Remove plugin from server */
130 gchar *plugin_name = tcore_plugin_get_filename(plugin);
131 if (plugin_name != NULL) {
132 err("Plug-in '%s' init failed!!!", plugin_name);
133 tcore_free(plugin_name);
141 static gboolean init_plugins(Server *s)
143 GSList *list = tcore_server_ref_plugins(s);
145 while (list != NULL) {
146 if (G_UNLIKELY(FALSE == __init_plugin(list->data))) {
147 list = g_slist_next(list);
150 list = g_slist_next(list);
153 info("[TIME_CHECK] plugin init finished");
157 static void *__load_plugin(const gchar *filename, struct tcore_plugin_define_desc **desc_out)
160 struct tcore_plugin_define_desc *desc;
161 struct stat stat_buf;
164 handle = dlopen(filename, RTLD_NOW);
165 if (G_UNLIKELY(NULL == handle)) {
166 err("Failed to open '%s': %s", filename, dlerror());
170 desc = dlsym(handle, "plugin_define_desc");
171 if (G_UNLIKELY(NULL == desc)) {
172 err("Failed to load symbol: %s", dlerror());
178 dbg("'%s' plugin", desc->name);
179 dbg(" - path = %s", filename);
180 dbg(" - version = %d", desc->version);
181 dbg(" - priority = %d", desc->priority);
183 memset(&stat_buf, 0x00, sizeof(stat_buf));
184 memset(&file_date, '\0', sizeof(file_date));
186 if (stat(filename, &stat_buf) == 0) {
187 if (ctime_r(&stat_buf.st_mtime, file_date) != NULL) {
188 if (strlen(file_date) > 1)
189 file_date[strlen(file_date)-1] = '\0';
191 dbg(" - date = %s", file_date);
195 if (G_LIKELY(desc->load)) {
196 if (G_UNLIKELY(desc->load() == FALSE)) {
197 warn("Failed to load Plug-in");
204 if (desc_out != NULL)
210 static gboolean load_plugins(Server *s, const gchar *path, gboolean flag_test_load)
212 const gchar *file = NULL;
213 gchar *filename = NULL;
216 struct tcore_plugin_define_desc *desc = NULL;
218 if ((path == NULL) || (s == NULL)) {
219 err("path: [%p] s: [%p]", path, s);
223 dir = g_dir_open(path, 0, NULL);
225 err("Failed to open directory '%s'", path);
229 while ((file = g_dir_read_name(dir)) != NULL) {
230 if (g_str_has_prefix(file, "lib") == TRUE
231 || g_str_has_suffix(file, ".so") == FALSE)
234 filename = g_build_filename(path, file, NULL);
237 if (G_UNLIKELY((handle = __load_plugin(filename, &desc)) == NULL)) {
242 /* Don't add to server if flag_test_load */
243 if (flag_test_load) {
244 dbg("Loading '%s' - Successful", filename);
251 /* Add Plug-in to Server Plug-in list */
252 tcore_server_add_plugin(s, tcore_plugin_new(s, desc, filename, handle));
253 dbg("'%s' added", desc->name);
259 info("[TIME_CHECK] Plug-in load finished");
264 gint main(gint argc, gchar *argv[])
266 #ifdef ENABLE_MONITOR
267 struct sigaction sigact;
270 gboolean flag_test_load = FALSE;
271 gint opt = 0, opt_index = 0, ret_code = EXIT_SUCCESS;
272 struct option options[] = {
274 { "testload", 0, &flag_test_load, 1 },
277 gchar *plugin_path = DEFAULT_PLUGINS_PATH;
278 gchar *tcore_ver = NULL;
279 struct sysinfo sys_info;
282 if (sysinfo(&sys_info) == 0)
283 info("uptime: %ld secs", sys_info.uptime);
287 tcore_ver = tcore_util_get_version();
288 info("daemon version: %s", DAEMON_VERSION);
289 info("libtcore version: %s", tcore_ver);
290 tcore_free(tcore_ver);
291 info("glib version: %u.%u.%u", glib_major_version, glib_minor_version, glib_micro_version);
293 #ifdef ENABLE_MONITOR
294 /* Signal Registration */
295 sigact.sa_handler = telephony_signal_handler;
296 sigemptyset(&sigact.sa_mask);
298 if (sigaction(SIGTERM, &sigact, NULL) < 0)
299 warn("sigaction(SIGTERM) failed.");
300 if (sigaction(SIGUSR1, &sigact, NULL) < 0)
301 warn("sigaction(SIGUSR1) failed.");
303 /* Additional signals for dedugging the cause of Telephony crash */
304 if (sigaction(SIGINT, &sigact, NULL) < 0)
305 warn("sigaction(SIGINT) failed.");
306 if (sigaction(SIGABRT, &sigact, NULL) < 0)
307 warn("sigaction(SIGABRT) failed.");
308 if (sigaction(SIGHUP, &sigact, NULL) < 0)
309 warn("sigaction(SIGHUP) failed.");
310 if (sigaction(SIGSEGV, &sigact, NULL) < 0)
311 warn("sigaction(SIGSEGV) failed.");
312 if (sigaction(SIGXCPU, &sigact, NULL) < 0)
313 warn("sigaction(SIGXCPU) failed.");
314 if (sigaction(SIGQUIT, &sigact, NULL) < 0)
315 warn("sigaction(SIGQUIT) failed.");
318 /* Commandline option parser TODO: Replace with GOptionContext */
320 opt = getopt_long(argc, argv, "hT", options, &opt_index);
328 __usage_info(argv[0]);
335 __usage_info(argv[0]);
340 flag_test_load = TRUE;
346 plugin_path = argv[optind];
348 info("plugin_path: [%s]", plugin_path);
350 #if !GLIB_CHECK_VERSION(2, 35, 0)
353 #if !GLIB_CHECK_VERSION(2, 31, 0)
357 s = tcore_server_new();
358 if (G_UNLIKELY(NULL == s)) {
359 err("server_new failed.");
364 g_log_set_default_handler(glib_log, s);
367 if (G_UNLIKELY(FALSE == load_plugins(s, (const gchar *)plugin_path, flag_test_load))) {
368 err("load_plugins failed.");
369 ret_code = EXIT_FAILURE;
373 if (flag_test_load) {
374 ret_code = EXIT_SUCCESS;
378 /* Initialize Plugins */
379 if (G_UNLIKELY(FALSE == init_plugins(s))) {
380 err("init_plugins failed.");
381 ret_code = EXIT_FAILURE;
385 info("Server mainloop start");
387 /* Notification to systemd */
388 sd_notify(0, "READY=1");
391 if (G_UNLIKELY(FALSE == tcore_server_run(s))) {
392 err("Server_run - Failed!!!");
393 ret_code = EXIT_FAILURE;
397 tcore_server_free(s);