4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
6 * Contact: Ja-young Gu <jygu@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 #ifdef TIZEN_DEBUG_ENABLE
32 #include <sys/sysinfo.h>
42 #ifndef DAEMON_VERSION
43 #define DAEMON_VERSION "unknown"
46 #ifndef DEFAULT_PLUGINS_PATH
47 #define DEFAULT_PLUGINS_PATH "/usr/lib/telephony/plugins/"
50 #define NOTUSED(var) (var = var)
51 #define BUFFER_SIZE 1024
53 static Server *_server = NULL;
55 static void __usage_info(const char *exec)
57 info("Usage: %s [OPTION]... [PLUGIN_PATH]\n", exec);
59 info(" -T, --testload\t run with plugin load test mode and exit\n");
60 info(" -h, --help\t\t display this help and exit\n");
64 void tcore_log(enum tcore_log_type type, enum tcore_log_priority priority, const char *tag, const char *fmt, ...)
67 char buf[BUFFER_SIZE];
68 int log_id = LOG_ID_RADIO;
69 #ifdef TIZEN_PROFILE_TV
71 /* Increase log priority for debugging in TV profile */
72 priority = ((priority == TCORE_LOG_DEBUG) ? TCORE_LOG_INFO : priority);
76 case TCORE_LOG_TYPE_RADIO: {
77 if (priority >= TCORE_LOG_INFO) {
79 vsnprintf(buf, BUFFER_SIZE-1, fmt, ap);
81 __dlog_print(log_id, priority, tag, "%s", buf);
83 #ifdef TIZEN_DEBUG_ENABLE
85 vsnprintf(buf, BUFFER_SIZE-1, fmt, ap);
87 __dlog_print(log_id, priority, tag, "%s", buf);
92 case TCORE_LOG_TYPE_TIME_CHECK: {
93 #ifdef TIZEN_DEBUG_ENABLE /* User Mode should not log performance data */
94 float a = 0.00, b = 0.00;
96 FILE *fp = fopen("/proc/uptime", "r");
98 err("fopen() failed");
101 if (fscanf(fp, "%f %f", &a, &b) == 0)
102 next = snprintf(buf, BUFFER_SIZE, "[UPTIME] [Not Set] ");
104 next = snprintf(buf, BUFFER_SIZE, "[UPTIME] %f ", a);
110 vsnprintf(buf + next, (BUFFER_SIZE-1) - next, fmt, ap);
112 __dlog_print(log_id, priority, tag, "%s", buf);
121 static void glib_log(const gchar *log_domain, GLogLevelFlags log_level,
122 const gchar *msg, gpointer user_data)
128 __dlog_print(LOG_ID_RADIO, DLOG_ERROR, "GLIB", "%s", msg);
131 #ifdef TIZEN_DEBUG_ENABLE
132 static void telephony_signal_handler(int signo)
139 monitor_server_state(_server);
143 tcore_server_exit(_server);
144 dbg("*~*~*~* Signal: [SIGTERM] finished *~*~*~*");
147 #if defined(TIZEN_PROFILE_TV) || defined(TIZEN_PROFILE_IVI)
149 warn("*~*~*~* Ignore Signal: [SIGHUP] *~*~*~*");
154 warn("*~*~*~* Unhandled Signal: [%d] *~*~*~*", signo);
160 #elif defined(TIZEN_PROFILE_TV) || defined(TIZEN_PROFILE_IVI)
161 static void telephony_signal_handler(int signo)
168 warn("*~*~*~* Ignore Signal: [SIGHUP] *~*~*~*");
172 warn("*~*~*~* Unhandled Signal: [%d] *~*~*~*", signo);
180 static void __log_uptime()
182 float a = 0.00, b = 0.00;
183 FILE *fp = fopen("/proc/uptime", "r");
186 err("fopen() failed");
189 info("scanned %d items", fscanf(fp, "%f %f", &a, &b));
190 info("proc uptime = %f idletime = %f", a, b);
194 static gboolean __init_plugin(TcorePlugin *plugin)
196 const struct tcore_plugin_define_desc *desc = tcore_plugin_get_description(plugin);
198 if (!desc || !desc->init)
201 if (!desc->init(plugin)) { /* TODO: Remove plugin from server */
202 char *plugin_name = tcore_plugin_get_filename(plugin);
203 if (NULL != plugin_name) {
204 err("plugin(%s) init failed.", plugin_name);
213 static gboolean init_plugins(Server *s)
215 GSList *list = tcore_server_ref_plugins(s);
217 while (list != NULL) {
218 if (G_UNLIKELY(FALSE == __init_plugin(list->data))) {
219 list = g_slist_next(list);
222 list = g_slist_next(list);
228 static void *__load_plugin(const gchar *filename, struct tcore_plugin_define_desc **desc_out)
231 struct tcore_plugin_define_desc *desc = NULL;
233 handle = dlopen(filename, RTLD_LAZY);
234 if (NULL == handle) {
235 err("dlopen() failed:[%s][%s]", filename, dlerror());
239 desc = dlsym(handle, "plugin_define_desc");
241 err("dlsym() failed:[%s]", "plugin_define_desc");
246 dbg("%s (%s) version:[%d] priority:[%d] ", desc->name, filename, desc->version, desc->priority);
248 if (G_LIKELY(desc->load)) {
249 if (G_UNLIKELY(FALSE == desc->load())) {
250 warn("false return from load(). skip this plugin");
256 if (NULL != desc_out)
262 static gboolean load_plugins(Server *s, const char *path, gboolean flag_test_load)
264 const gchar *file = NULL;
265 gchar *filename = NULL;
268 struct tcore_plugin_define_desc *desc = NULL;
273 dir = g_dir_open(path, 0, NULL);
277 while ((file = g_dir_read_name(dir)) != NULL) {
278 if (g_str_has_prefix(file, "lib") == TRUE
279 || g_str_has_suffix(file, ".so") == FALSE)
282 filename = g_build_filename(path, file, NULL);
285 handle = __load_plugin(filename, &desc);
286 if (NULL == handle) {
291 /* Don't add to server if flag_test_load */
292 if (flag_test_load) {
293 dbg("success to load '%s'", filename);
299 tcore_server_add_plugin(s, tcore_plugin_new(s, desc, filename, handle));
301 dbg("%s added", desc->name);
309 int main(int argc, char *argv[])
311 #if defined(TIZEN_DEBUG_ENABLE) || defined(TIZEN_PROFILE_TV) || defined(TIZEN_PROFILE_IVI)
312 struct sigaction sigact;
315 gboolean flag_test_load = FALSE;
316 int opt = 0, opt_index = 0, ret_code = EXIT_SUCCESS;
317 int daemon_load_count = 0;
318 struct option options[] = {
320 { "testload", 0, &flag_test_load, 1 },
323 const char *plugin_path = DEFAULT_PLUGINS_PATH;
324 char *tcore_ver = NULL;
325 struct sysinfo sys_info;
327 TIME_CHECK("Starting Telephony");
330 if (0 == sysinfo(&sys_info))
331 info("uptime: %ld secs", sys_info.uptime);
335 tcore_ver = tcore_util_get_version();
336 info("[version] daemon : %s, libtcore : %s, glib : %u.%u.%u", DAEMON_VERSION, tcore_ver, glib_major_version, glib_minor_version, glib_micro_version);
339 /* Telephony reset handling*/
340 vconf_get_int(VCONFKEY_TELEPHONY_DAEMON_LOAD_COUNT, &daemon_load_count);
342 vconf_set_int(VCONFKEY_TELEPHONY_DAEMON_LOAD_COUNT, daemon_load_count);
343 info("daemon load count = [%d]", daemon_load_count);
345 #ifdef TIZEN_DEBUG_ENABLE
346 /* Signal Registration */
347 sigact.sa_handler = telephony_signal_handler;
348 sigemptyset(&sigact.sa_mask);
350 if (sigaction(SIGTERM, &sigact, NULL) < 0)
351 warn("sigaction(SIGTERM) failed.");
352 if (sigaction(SIGUSR1, &sigact, NULL) < 0)
353 warn("sigaction(SIGUSR1) failed.");
354 #if defined(TIZEN_PROFILE_TV) || defined(TIZEN_PROFILE_IVI)
355 /* SIGHUP should be ignored because cellular dongle ejection makes this signal */
356 if (sigaction(SIGHUP, &sigact, NULL) < 0)
357 warn("sigaction(SIGHUP) failed.");
359 #elif defined(TIZEN_PROFILE_TV) || defined(TIZEN_PROFILE_IVI)
360 /* Signal Registration */
361 sigact.sa_handler = telephony_signal_handler;
362 sigemptyset(&sigact.sa_mask);
364 /* SIGHUP should be ignored because cellular dongle ejection makes this signal */
365 if (sigaction(SIGHUP, &sigact, NULL) < 0)
366 warn("sigaction(SIGHUP) failed.");
369 if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
370 err("Child process won't be auto reaped: [%d]", errno);
372 /* Commandline option parser TODO: Replace with GOptionContext */
374 opt = getopt_long(argc, argv, "hT", options, &opt_index);
383 __usage_info(argv[0]);
387 warn("unhandled opt_index.");
393 __usage_info(argv[0]);
398 flag_test_load = TRUE;
401 warn("unhandled opt case.");
407 plugin_path = argv[optind];
409 info("plugin_path: [%s]", plugin_path);
411 #if !GLIB_CHECK_VERSION(2, 35, 0)
414 #if !GLIB_CHECK_VERSION(2, 31, 0)
418 s = tcore_server_new();
419 if (G_UNLIKELY(NULL == s)) {
420 err("server_new failed.");
421 ret_code = EXIT_FAILURE;
426 g_log_set_default_handler(glib_log, s);
429 if (G_UNLIKELY(FALSE == load_plugins(s, (const char *)plugin_path, flag_test_load))) {
430 err("load_plugins failed.");
431 ret_code = EXIT_FAILURE;
435 TIME_CHECK("Loading Plugins Complete");
437 if (flag_test_load) {
438 ret_code = EXIT_SUCCESS;
442 /* Initialize Plugins */
443 if (G_UNLIKELY(FALSE == init_plugins(s))) {
444 err("init_plugins failed.");
445 ret_code = EXIT_FAILURE;
449 info("server mainloop start");
450 TIME_CHECK("Initializing Plugins Complete. Starting Daemon");
452 if (G_UNLIKELY(TCORE_RETURN_SUCCESS != tcore_server_run(s))) {
453 err("server_run failed.");
454 ret_code = EXIT_FAILURE;
458 tcore_server_free(s); _server = NULL;