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 /* Internal vconf to maintain telephony load info (Number of times telephony daemon is loaded) */
51 #define VCONFKEY_TELEPHONY_DAEMON_LOAD_COUNT "memory/private/telephony/daemon_load_count"
53 #define NOTUSED(var) (var = var)
55 static Server *_server = NULL;
57 static void __usage_info(const char *exec)
59 printf("Usage: %s [OPTION]... [PLUGIN_PATH]\n", exec);
61 printf(" -T, --testload\t run with plugin load test mode and exit\n");
62 printf(" -h, --help\t\t display this help and exit\n");
66 void tcore_log(enum tcore_log_type type, enum tcore_log_priority priority, const char *tag, const char *fmt, ...)
72 case TCORE_LOG_TYPE_RADIO: {
73 if (priority >= TCORE_LOG_INFO) {
75 vsnprintf(buf, 1023, fmt, ap);
77 __dlog_print(LOG_ID_RADIO, priority, tag, buf);
79 #ifdef TIZEN_DEBUG_ENABLE
81 vsnprintf(buf, 1023, fmt, ap);
83 __dlog_print(LOG_ID_RADIO, priority, tag, buf);
88 case TCORE_LOG_TYPE_TIME_CHECK: {
89 #ifdef TIZEN_DEBUG_ENABLE /* User Mode should not log performance data */
90 float a = 0.00, b = 0.00;
92 FILE *fp = fopen("/proc/uptime", "r");
93 g_return_if_fail(NULL != fp);
95 if(fscanf(fp, "%f %f", &a, &b)){};
97 next = sprintf(buf, "[UPTIME] %f ", a);
102 vsnprintf(buf + next, 1023 - next, fmt, ap);
104 __dlog_print(LOG_ID_RADIO, priority, tag, buf);
113 static void glib_log(const gchar *log_domain, GLogLevelFlags log_level,
114 const gchar *msg, gpointer user_data)
120 __dlog_print (LOG_ID_RADIO, DLOG_ERROR, "GLIB", msg);
123 #ifdef TIZEN_DEBUG_ENABLE
124 static void telephony_signal_handler(int signo)
131 monitor_server_state(_server);
135 tcore_server_exit(_server);
139 warn("*~*~*~* Unhandled Signal: [%d] *~*~*~*", signo);
147 static void __log_uptime()
149 float a = 0.00, b = 0.00;
150 FILE *fp = fopen("/proc/uptime", "r");
151 g_return_if_fail(NULL != fp);
152 info("scanned %d items", fscanf(fp, "%f %f", &a, &b));
153 info("proc uptime = %f idletime = %f\n", a, b);
157 static gboolean __init_plugin(TcorePlugin *plugin)
159 const struct tcore_plugin_define_desc *desc = tcore_plugin_get_description(plugin);
161 if (!desc || !desc->init)
164 if (!desc->init(plugin)) { /* TODO: Remove plugin from server */
165 char *plugin_name = tcore_plugin_get_filename(plugin);
166 if (NULL != plugin_name) {
167 err("plugin(%s) init failed.", plugin_name);
176 static gboolean init_plugins(Server *s)
178 GSList *list = tcore_server_ref_plugins(s);
180 while (list != NULL) {
181 if (G_UNLIKELY(FALSE == __init_plugin(list->data))) {
182 list = g_slist_next(list);
185 list = g_slist_next(list);
191 static void *__load_plugin(const gchar *filename, struct tcore_plugin_define_desc **desc_out)
194 struct tcore_plugin_define_desc *desc = NULL;
195 struct stat stat_buf;
198 handle = dlopen(filename, RTLD_LAZY);
199 if (G_UNLIKELY(NULL == handle)) {
200 err("fail to load '%s': %s", filename, dlerror());
204 desc = dlsym(handle, "plugin_define_desc");
205 if (G_UNLIKELY(NULL == desc)) {
206 err("fail to load symbol: %s", dlerror());
211 dbg("%s plugin", desc->name);
212 dbg(" - path = %s", filename);
213 dbg(" - version = %d", desc->version);
214 dbg(" - priority = %d", desc->priority);
216 memset(&stat_buf, 0x00, sizeof(stat_buf));
217 memset(&file_date, '\0', sizeof(file_date));
219 if (0 == stat(filename, &stat_buf)) {
220 if (NULL != ctime_r(&stat_buf.st_mtime, file_date)) {
221 if (1 < strlen(file_date))
222 file_date[strlen(file_date)-1] = '\0';
223 dbg(" - date = %s", file_date);
227 if (G_LIKELY(desc->load)) {
228 if (G_UNLIKELY(FALSE == desc->load())) {
229 warn("false return from load(). skip this plugin");
235 if (NULL != desc_out)
241 static gboolean load_plugins(Server *s, const char *path, gboolean flag_test_load)
243 const gchar *file = NULL;
244 gchar *filename = NULL;
247 struct tcore_plugin_define_desc *desc = NULL;
252 dir = g_dir_open(path, 0, NULL);
256 while ((file = g_dir_read_name(dir)) != NULL) {
257 if (g_str_has_prefix(file, "lib") == TRUE
258 || g_str_has_suffix(file, ".so") == FALSE)
261 filename = g_build_filename(path, file, NULL);
264 if (G_UNLIKELY((handle = __load_plugin(filename, &desc)) == NULL)) {
269 /* Don't add to server if flag_test_load */
270 if (flag_test_load) {
271 dbg("success to load '%s'", filename);
277 tcore_server_add_plugin(s, tcore_plugin_new(s, desc, filename, handle));
279 dbg("%s added", desc->name);
287 int main(int argc, char *argv[])
289 #ifdef TIZEN_DEBUG_ENABLE
290 struct sigaction sigact;
293 gboolean flag_test_load = FALSE;
294 int opt = 0, opt_index = 0, ret_code = EXIT_SUCCESS;
295 int daemon_load_count = 0;
296 struct option options[] = {
298 { "testload", 0, &flag_test_load, 1 },
301 const char *plugin_path = DEFAULT_PLUGINS_PATH;
302 char *tcore_ver = NULL;
303 struct sysinfo sys_info;
305 TIME_CHECK("Starting Telephony");
308 if (0 == sysinfo(&sys_info))
309 info("uptime: %ld secs", sys_info.uptime);
313 tcore_ver = tcore_util_get_version();
314 info("daemon version: %s", DAEMON_VERSION);
315 info("libtcore version: %s", tcore_ver);
317 info("glib version: %u.%u.%u", glib_major_version, glib_minor_version, glib_micro_version);
319 /* Telephony reset handling*/
320 vconf_get_int(VCONFKEY_TELEPHONY_DAEMON_LOAD_COUNT,&daemon_load_count);
322 vconf_set_int(VCONFKEY_TELEPHONY_DAEMON_LOAD_COUNT,daemon_load_count);
323 dbg("daemon load count = [%d]", daemon_load_count);
325 #ifdef TIZEN_DEBUG_ENABLE
326 /* Signal Registration */
327 sigact.sa_handler = telephony_signal_handler;
328 sigemptyset(&sigact.sa_mask);
330 if (sigaction(SIGTERM, &sigact, NULL) < 0)
331 warn("sigaction(SIGTERM) failed.");
332 if (sigaction(SIGUSR1, &sigact, NULL) < 0)
333 warn("sigaction(SIGUSR1) failed.");
336 /* Commandline option parser TODO: Replace with GOptionContext */
338 opt = getopt_long(argc, argv, "hT", options, &opt_index);
347 __usage_info(argv[0]);
351 warn("unhandled opt_index.");
357 __usage_info(argv[0]);
362 flag_test_load = TRUE;
365 warn("unhandled opt case.");
371 plugin_path = argv[optind];
373 info("plugin_path: [%s]", plugin_path);
375 #if !GLIB_CHECK_VERSION(2, 35, 0)
378 #if !GLIB_CHECK_VERSION(2, 31, 0)
382 s = tcore_server_new();
383 if (G_UNLIKELY(NULL == s)) {
384 err("server_new failed.");
385 ret_code = EXIT_FAILURE;
390 g_log_set_default_handler(glib_log, s);
393 if (G_UNLIKELY(FALSE == load_plugins(s, (const char *)plugin_path, flag_test_load))) {
394 err("load_plugins failed.");
395 ret_code = EXIT_FAILURE;
399 TIME_CHECK("Loading Plugins Complete");
401 if (flag_test_load) {
402 ret_code = EXIT_SUCCESS;
406 /* Initialize Plugins */
407 if (G_UNLIKELY(FALSE == init_plugins(s))) {
408 err("init_plugins failed.");
409 ret_code = EXIT_FAILURE;
413 info("server mainloop start");
414 TIME_CHECK("Initializing Plugins Complete. Starting Daemon");
416 if (G_UNLIKELY(TCORE_RETURN_SUCCESS != tcore_server_run(s))) {
417 err("server_run failed.");
418 ret_code = EXIT_FAILURE;
422 tcore_server_free(s); _server = NULL;