X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=daemon%2Fdaemon.c;h=ae53677220e86e914e7a839b6a400377a78d03fc;hb=bf21f0426fe844a434b929c90929052fef518052;hp=a61daf7cad6b78308f7589428fa45a05329c51a3;hpb=549fb176ae1f5dee3c8ee87712cd93ba48fef1f9;p=platform%2Fcore%2Fsystem%2Fswap-manager.git diff --git a/daemon/daemon.c b/daemon/daemon.c index a61daf7..ae53677 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -1,211 +1,85 @@ /* -* DA manager -* -* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. -* -* Contact: -* -* Jaewon Lim -* Woojin Jung -* Juyoung Kim -* + * DA manager + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * Jaewon Lim + * Woojin Jung + * Juyoung Kim + * Cherepanov Vitaliy + * Nikita Kalyazin + * * 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. -* -* Contributors: -* - S-Core Co., Ltd -* -*/ - + * 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. + * + * Contributors: + * - S-Core Co., Ltd + * - Samsung RnD Institute Russia + * + */ +#define __STDC_FORMAT_MACROS #include -#include // for realpath -#include // for strtok, strcpy, strncpy -#include // for realpath +#include // for realpath +#include // for strtok, strcpy, strncpy +#include // for realpath +#include -#include // for errno +#include // for errno #include // for accept, mkdir, opendir, readdir #include // for accept #include // for mkdir #include // for eventfd -#include // for epoll apis #include // for timerfd -#include // for access, sleep +#include // for access, sleep +#include +#include +#include #include -#ifndef LOCALTEST -#include // for fsetxattr -#include -#endif - -#include -#include #include + +#include + +#include + #include "daemon.h" #include "sys_stat.h" #include "utils.h" #include "da_protocol.h" +#include "da_inst.h" #include "da_data.h" +#include "input_events.h" +#include "smack.h" +#include "us_interaction_msg.h" #include "debug.h" -#define DA_WORK_DIR "/home/developer/sdk_tools/da/" +#define DA_WORK_DIR "/home/developer/sdk_tools/da/" #define DA_READELF_PATH "/home/developer/sdk_tools/da/readelf" #define SCREENSHOT_DIR "/tmp/da" -#define EPOLL_SIZE 10 -#define MAX_CONNECT_SIZE 12 -#define MAX_APP_LAUNCH_TIME 6 - -#define MAX_DEVICE 10 -#define MAX_FILENAME 128 -#define BUF_SIZE 1024 -#define ARRAY_END (-11) - -input_dev g_key_dev[MAX_DEVICE]; -input_dev g_touch_dev[MAX_DEVICE]; - -// return bytes size of readed data -// return 0 if no data readed or error occurred -static int _file_read(FILE* fp, char *buffer, int size) -{ - int ret = 0; - - if(fp != NULL && size > 0) - { - ret = fread((void*)buffer, sizeof(char), size, fp); - } - else - { - // fp is null - if(size > 0) - buffer[0] = '\0'; - - ret = 0; // error case - } - - return ret; -} - -// get input id of given input device -static int get_input_id(char* inputname) -{ - static int query_cmd_type = 0; // 1 if /lib/udev/input_id, 2 if udevadm - FILE* cmd_fp = NULL; - char buffer[BUF_SIZE]; - char command[MAX_FILENAME]; - int ret = -1; - - // determine input_id query command - if(unlikely(query_cmd_type == 0)) - { - if(access("/lib/udev/input_id", F_OK) == 0) // there is /lib/udev/input_id - { - query_cmd_type = 1; - } - else // there is not /lib/udev/input_id - { - query_cmd_type = 2; - } - } - - // make command string - if(query_cmd_type == 1) - { - sprintf(command, "/lib/udev/input_id /class/input/%s", inputname); - } - else - { - sprintf(command, "udevadm info --name=input/%s --query=property", inputname); - } - - // run command - cmd_fp = popen(command, "r"); - _file_read(cmd_fp, buffer, BUF_SIZE); +#define MAX_APP_LAUNCH_TIME 60 +#define MAX_CONNECT_TIMEOUT_TIME 5*60 - // determine input id - if(strstr(buffer, INPUT_ID_STR_KEY)) // key - { - ret = INPUT_ID_KEY; - } - else if(strstr(buffer, INPUT_ID_STR_TOUCH)) // touch - { - ret = INPUT_ID_TOUCH; - } - else if(strstr(buffer, INPUT_ID_STR_KEYBOARD)) // keyboard - { - ret = INPUT_ID_KEY; - } - else if(strstr(buffer, INPUT_ID_STR_TABLET)) // touch (emulator) - { - ret = INPUT_ID_TOUCH; - } - - if(cmd_fp != NULL) - pclose(cmd_fp); - return ret; -} - -// get filename and fd of given input type devices -static void _get_fds(input_dev *dev, int input_id) -{ - DIR *dp; - struct dirent *d; - int count = 0; - - dp = opendir("/sys/class/input"); - - if(dp != NULL) - { - while((d = readdir(dp)) != NULL) - { - if(!strncmp(d->d_name, "event", 5)) // start with "event" - { - // event file - if(input_id == get_input_id(d->d_name)) - { - sprintf(dev[count].fileName, "/dev/input/%s", d->d_name); - dev[count].fd = open(dev[count].fileName, O_RDWR | O_NONBLOCK); - count++; - } - } - } - - closedir(dp); - } - dev[count].fd = ARRAY_END; // end of input_dev array -} - -//static -void _device_write(input_dev *dev, struct input_event* in_ev) +uint64_t get_total_alloc_size(void) { int i; - for(i = 0; dev[i].fd != ARRAY_END; i++) - { - if(dev[i].fd >= 0) - { - write(dev[i].fd, in_ev, sizeof(struct input_event)); - LOGI("write(%d, %d, %d)\n",dev[i].fd, (int)in_ev, sizeof(struct input_event)); - } - } -} - -long long get_total_alloc_size() -{ - int i; - long long allocsize = 0; + uint64_t allocsize = 0; - for(i = 0; i < MAX_TARGET_COUNT; i++) - { - if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0) + for (i = 0; i < MAX_TARGET_COUNT; i++) { + if (manager.target[i].socket != -1 && + manager.target[i].allocmem > 0) allocsize += manager.target[i].allocmem; } return allocsize; @@ -214,9 +88,8 @@ long long get_total_alloc_size() static int getEmptyTargetSlot() { int i; - for(i = 0; i < MAX_TARGET_COUNT; i++) - { - if(manager.target[i].socket == -1) + for (i = 0; i < MAX_TARGET_COUNT; i++) { + if (manager.target[i].socket == -1) break; } @@ -225,175 +98,172 @@ static int getEmptyTargetSlot() static void setEmptyTargetSlot(int index) { - if(index >= 0 && index < MAX_TARGET_COUNT) - { + if (index >= 0 && index < MAX_TARGET_COUNT) { manager.target[index].pid = -1; manager.target[index].recv_thread = -1; manager.target[index].allocmem = 0; - manager.target[index].starttime = 0; manager.target[index].initial_log = 0; - if(manager.target[index].event_fd != -1) + if (manager.target[index].event_fd != -1) close(manager.target[index].event_fd); manager.target[index].event_fd = -1; - if(manager.target[index].socket != -1) + if (manager.target[index].socket != -1) close(manager.target[index].socket); manager.target[index].socket = -1; } } -// ====================================================================================== -// send functions to host -// ====================================================================================== - -int pseudoSendDataToHost(struct msg_data_t* log) -{ +// ============================================================================= +// start and terminate control functions +// ============================================================================= - printBuf((char *)log, MSG_DATA_HDR_LEN + log->len); -/* LOGI("try send to <%d><%s>\n", dev->fd, dev->fileName); */ +static Ecore_Fd_Handler *launch_timer_handler; - write_to_buf(log); +//stop application launch timer +static int stop_app_launch_timer() +{ + close(manager.app_launch_timerfd); + manager.app_launch_timerfd = -1; return 0; } -int sendDataToHost(msg_t* log) +static Eina_Bool launch_timer_cb(void *data, Ecore_Fd_Handler *fd_handler) { - if (manager.host.data_socket != -1) - { - char logstr[DA_MSG_MAX]; - int loglen; + LOGE("Failed to launch application\n"); + if (stop_app_launch_timer() < 0) + LOGE("cannot stop app launch timer\n"); - if(log->length != 0) - loglen = sprintf(logstr, "%d|%d|%s\n", log->type, log->length + 1, log->data); - else - loglen = sprintf(logstr, "%d|%d|\n", log->type, log->length + 1); + return ECORE_CALLBACK_CANCEL; +} -// loglen = sprintf(logstr, "%d|%s\n", log->type, log->data); +//start application launch timer function +static int start_app_launch_timer(int apps_count) +{ + int res = 0; - pthread_mutex_lock(&(manager.host.data_socket_mutex)); - send(manager.host.data_socket, logstr, loglen, MSG_NOSIGNAL); - pthread_mutex_unlock(&(manager.host.data_socket_mutex)); - return 0; + assert(apps_count >= 0 && "negative apps count"); + + if (apps_count == 0) + return res; + + manager.app_launch_timerfd = + timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC); + if (manager.app_launch_timerfd > 0) { + struct itimerspec ctime; + ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME * apps_count; + ctime.it_value.tv_nsec = 0; + ctime.it_interval.tv_sec = 0; + ctime.it_interval.tv_nsec = 0; + if (timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL) < 0) { + LOGE("fail to set app launch timer\n"); + stop_app_launch_timer(); + res = -1; + } else { + launch_timer_handler = + ecore_main_fd_handler_add(manager.app_launch_timerfd, + ECORE_FD_READ, + launch_timer_cb, + NULL, + NULL, NULL); + if (!launch_timer_handler) { + LOGE("fail to add app launch timer fd to \n"); + stop_app_launch_timer(); + res = -2; + } else { + LOGI("application launch time started\n"); + } + } + } else { + LOGE("cannot create launch timer\n"); + res = -3; } - else - return 1; + + return res; } -// msgstr can be NULL -/* -static int sendACKStrToHost(enum HostMessageType resp, char* msgstr) +static inline void inc_apps_to_run() { - if (manager.host.control_socket != -1) - { - char logstr[DA_MSG_MAX]; - int loglen; - - if(msgstr != NULL) - loglen = sprintf(logstr, "%d|%d|%s", (int)resp, strlen(msgstr), msgstr); - else - loglen = sprintf(logstr, "%d|0|", (int)resp); + manager.apps_to_run++; +} - send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL); - return 0; - } - else - return 1; +static inline void dec_apps_to_run() +{ + if (manager.apps_to_run > 0) + manager.apps_to_run--; } -*/ +static inline int get_apps_to_run() +{ + return manager.apps_to_run; +} -//static -int sendACKCodeToHost(enum HostMessageType resp, int msgcode) +static int kill_app_by_info(const struct app_info_t *app_info) { - // FIXME: - //disabled string protocol - return 0; - if (manager.host.control_socket != -1) - { - char codestr[16]; - char logstr[DA_MSG_MAX]; - int loglen, codelen; + int res = 0; - codelen = sprintf(codestr, "%d", msgcode); - loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr); + if (app_info == NULL) { + LOGE("Cannot exec app. app_info is NULL"); + return -1; + } - send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL); - return 0; + switch (app_info->app_type) { + case APP_TYPE_TIZEN: + res = kill_app(app_info->exe_path); + break; + case APP_TYPE_RUNNING: + // TODO: nothing, it's running + LOGI("already started\n"); + break; + case APP_TYPE_COMMON: + res = kill_app(app_info->exe_path); + break; + default: + LOGE("Unknown app type %d\n", app_info->app_type); + res = -1; + break; } - else - return 1; -} -// ======================================================================================== -// start and terminate control functions -// ======================================================================================== + return res; +} -int startProfiling(long launchflag) +static int exec_app(const struct app_info_t *app_info) { - const struct app_info_t *app_info = &prof_session.app_info; - - // remove previous screen capture files - remove_indir(SCREENSHOT_DIR); - mkdir(SCREENSHOT_DIR, 0777); -#ifndef LOCALTEST - smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS); -#endif - manager.config_flag = launchflag; + int res = 0; - if (samplingStart() < 0) + if (app_info == NULL) { + LOGE("Cannot exec app. app_info is NULL"); return -1; + } switch (app_info->app_type) { case APP_TYPE_TIZEN: if (exec_app_tizen(app_info->app_id, app_info->exe_path)) { LOGE("Cannot exec tizen app %s\n", app_info->app_id); - samplingStop(); - return -1; + res = -1; + } else { + inc_apps_to_run(); } break; case APP_TYPE_RUNNING: // TODO: nothing, it's running + LOGI("already started\n"); break; case APP_TYPE_COMMON: if (exec_app_common(app_info->exe_path)) { LOGE("Cannot exec common app %s\n", app_info->exe_path); - samplingStop(); - return -1; + res = -1; + } else { + inc_apps_to_run(); } break; default: LOGE("Unknown app type %d\n", app_info->app_type); - samplingStop(); - return -1; + res = -1; break; } - if (start_replay() != 0) { - LOGE("Cannot start replay thread\n"); - return -1; - } - - return 0; -} - -// terminate single target -// just send stop message to target process -static void terminate_target(int index) -{ - ssize_t sendlen; - msg_t sendlog; - sendlog.type = MSG_STOP; - sendlog.length = 0; - - if(manager.target[index].socket != -1) - { - // result of sending to disconnected socket is not expected - sendlen = send(manager.target[index].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL); - if(sendlen != -1) - { - LOGI("TERMINATE send exit msg (socket %d) by terminate_target()\n", manager.target[index].socket); - } - } + LOGI("ret=%d\n", res); + return res; } // just send stop message to all target process @@ -401,19 +271,20 @@ static void terminate_all_target() { int i; ssize_t sendlen; - msg_t sendlog; + msg_target_t sendlog; sendlog.type = MSG_STOP; sendlog.length = 0; - for (i = 0; i < MAX_TARGET_COUNT; i++) - { - if(manager.target[i].socket != -1) - { - sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL); - if(sendlen != -1) - { - LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket); + for (i = 0; i < MAX_TARGET_COUNT; i++) { + if (manager.target[i].socket != -1) { + sendlen = send(manager.target[i].socket, &sendlog, + sizeof(sendlog.type) + + sizeof(sendlog.length), MSG_NOSIGNAL); + if (sendlen != -1) { + LOGI("TERMINATE send exit msg (socket %d) " + "by terminate_all_target()\n", + manager.target[i].socket); } } } @@ -423,783 +294,688 @@ static void terminate_all_target() void terminate_all() { int i; - samplingStop(); terminate_all_target(); // wait for all other thread exit - for(i = 0; i < MAX_TARGET_COUNT; i++) - { - if(manager.target[i].recv_thread != -1) - { + for (i = 0; i < MAX_TARGET_COUNT; i++) { + if (manager.target[i].recv_thread != -1) { + LOGI("join recv thread [%d] is started\n", i); pthread_join(manager.target[i].recv_thread, NULL); + LOGI("join recv thread %d. done\n", i); } } } // terminate all profiling by critical error -static void terminate_error(char* errstr, int sendtohost) +// TODO: don't send data to host +static void terminate_error(char *errstr, int send_to_host) { - msg_t log; - - LOGE("TERMINATE ERROR: %s\n", errstr); - if(sendtohost) - { - log.type = MSG_ERROR; - log.length = sprintf(log.data, "%s", errstr); - sendDataToHost(&log); + LOGE("termination all with err '%s'\n", errstr); + struct msg_data_t *msg = NULL; + if (send_to_host != 0) { + msg = gen_message_error(errstr); + if (msg) { + write_to_buf(msg); + free_msg_data(msg); + } else { + LOGI("cannot generate error message\n"); + } } - terminate_all(); } -// =========================================================================================== -// message parsing and handling functions -// =========================================================================================== -/* -static int parseDeviceMessage(msg_t* log) +static Ecore_Fd_Handler *connect_timer_handler; + +static Eina_Bool connect_timer_cb(void *data, Ecore_Fd_Handler *fd_handler) { - char eventType[MAX_FILENAME]; - struct input_event in_ev; - int i, index; + terminate_error("no incoming connections", 1); + close(manager.connect_timeout_timerfd); + manager.connect_timeout_timerfd = -1; + LOGE("No connection in %d sec. shutdown.\n", + MAX_CONNECT_TIMEOUT_TIME); + ecore_main_loop_quit(); + + return ECORE_CALLBACK_CANCEL; +} - if(log == NULL) - return -1; +static int launch_timer_start(void) +{ + int res = 0; - eventType[0] = '\0'; - in_ev.type = 0; - in_ev.code = 0; - in_ev.value = 0; + manager.connect_timeout_timerfd = + timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC); + if (manager.connect_timeout_timerfd > 0) { + struct itimerspec ctime; + ctime.it_value.tv_sec = MAX_CONNECT_TIMEOUT_TIME; + ctime.it_value.tv_nsec = 0; + ctime.it_interval.tv_sec = 0; + ctime.it_interval.tv_nsec = 0; + if (timerfd_settime(manager.connect_timeout_timerfd, 0, &ctime, NULL) < 0) { + LOGE("fail to set connect timeout timer\n"); + close(manager.connect_timeout_timerfd); + manager.connect_timeout_timerfd = -1; + } else { + connect_timer_handler = + ecore_main_fd_handler_add(manager.connect_timeout_timerfd, + ECORE_FD_READ, + connect_timer_cb, + NULL, + NULL, NULL); + if (!connect_timer_handler) { + LOGE("fail to add app connection timeout timer fd\n"); + close(manager.connect_timeout_timerfd); + manager.connect_timeout_timerfd = -1; + } else { + LOGI("connection timeout timer started\n"); + } + } + } else { + LOGE("cannot create connection timeout timer\n"); + } - index = 0; - for(i = 0; i < log->length; i++) - { - if(log->data[i] == '\n') - break; + LOGI("ret=%d\n", res); + return res; +} - if(log->data[i] == '`') // meet separate - { - i++; - index++; - continue; - } +int prepare_profiling(void) +{ + struct app_list_t *app = NULL; + const struct app_info_t *app_info = NULL; - if(index == 0) // parse eventType - { - eventType[i] = log->data[i]; - eventType[i+1] = '\0'; - } - else if(index == 1) // parse in_ev.type - { - in_ev.type = in_ev.type * 10 + (log->data[i] - '0'); - } - else if(index == 2) // parse in_ev.code - { - in_ev.code = in_ev.code * 10 + (log->data[i] - '0'); - } - else if(index == 3) // parse in_ev.value - { - in_ev.value = in_ev.value * 10 + (log->data[i] - '0'); + app_info = app_info_get_first(&app); + if (app_info == NULL) { + LOGE("No app info found\n"); + return -1; + } + + //all apps + while (app_info != NULL) { + if (kill_app_by_info(app_info) != 0) { + LOGE("kill app failed\n"); + return -1; } + app_info = app_info_get_next(&app); } + //init rw for systeminfo + //init recv send network systeminfo + sys_stat_prepare(); + return 0; - if(index != 3) - return -1; // parse error +} - if(0 == strncmp(eventType, STR_TOUCH, strlen(STR_TOUCH))) - { - _device_write(g_touch_dev, &in_ev); +int start_profiling(void) +{ + struct app_list_t *app = NULL; + const struct app_info_t *app_info = NULL; + int res = 0; + + app_info = app_info_get_first(&app); + if (app_info == NULL) { + LOGE("No app info found\n"); + return -1; } - else if(0 == strncmp(eventType, STR_KEY, strlen(STR_KEY))) - { - _device_write(g_key_dev, &in_ev); + // remove previous screen capture files + remove_indir(SCREENSHOT_DIR); + if (mkdir(SCREENSHOT_DIR, 0777) == -1 && errno != EEXIST) + LOGW("Failed to create directory for screenshot : %s\n", + strerror(errno)); + + set_label_for_all(SCREENSHOT_DIR); + + if (samplingStart() < 0) { + LOGE("Cannot start sampling\n"); + res = -1; + goto exit; } - return 0; + if (IS_OPT_SET(FL_RECORDING)) + add_input_events(); + + while (app_info != NULL) { + if (exec_app(app_info)) { + LOGE("Cannot exec app\n"); + res = -1; + goto recording_stop; + } + app_info = app_info_get_next(&app); + } + + if (start_app_launch_timer(get_apps_to_run()) < 0) { + res = -1; + goto recording_stop; + } + + goto exit; + + recording_stop: + if (IS_OPT_SET(FL_RECORDING)) + del_input_events(); + samplingStop(); + + exit: + LOGI("return %d\n", res); + return res; } -*/ -// return 0 if normal case -// return plus value if non critical error occur -// return minus value if critical error occur -/* static int _hostMessageHandler(int efd,struct msg_t* log) */ -/* { */ -/* int ret = 0; */ - -/* long flag = 0; */ -/* char *barloc, *tmploc; */ -/* char execPath[PATH_MAX]; */ - -/* if (log == NULL) */ -/* return 1; */ - -/* switch (log->type) */ -/* { */ -/* case MSG_REPLAY: */ -/* sendACKStrToHost(MSG_OK, NULL); */ -/* parseDeviceMessage(log); */ -/* break; */ -/* case MSG_VERSION: */ -/* if(strcmp(PROTOCOL_VERSION, log->data) != 0) */ -/* { */ -/* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_PROTOCOL_VERSION); */ -/* } */ -/* else */ -/* { */ -/* sendACKStrToHost(MSG_OK, NULL); */ -/* } */ -/* break; */ -/* case MSG_START: */ -/* LOGI("MSG_START handling : %s\n", log->data); */ -/* if(log->length == 0) */ -/* { */ -/* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */ -/* return -1; // wrong message format */ -/* } */ - -/* // parsing for host start status */ -/* tmploc = log->data; */ -/* barloc = strchr(tmploc, '|'); */ -/* if(barloc == NULL) */ -/* { */ -/* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */ -/* return -1; // wrong message format */ -/* } */ - -/* // parsing for target launch option flag */ -/* tmploc = barloc + 1; */ -/* barloc = strchr(tmploc, '|'); */ -/* if(barloc != NULL) */ -/* { */ -/* while(tmploc < barloc) */ -/* { */ -/* flag = (flag * 10) + (*tmploc - '0'); */ -/* tmploc++; */ -/* } */ -/* } */ -/* else */ -/* { */ -/* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */ -/* return -1; // wrong message format */ -/* } */ -/* LOGI("launch flag : %lx\n", flag); */ - -/* // parsing for application package name */ -/* tmploc = barloc + 1; */ -/* strcpy(manager.appPath, tmploc); */ - -/* get_executable(manager.appPath, execPath, PATH_MAX); // get exact app executable file name */ -/* LOGI("executable app path %s\n", manager.appPath); */ - -/* #ifdef RUN_APP_LOADER */ -/* kill_app(manager.appPath); */ -/* #else */ -/* kill_app(execPath); */ -/* #endif */ - -/* { */ -/* char command[PATH_MAX]; */ -/* struct epoll_event ev; */ - -/* //save app install path */ -/* mkdir(DA_WORK_DIR, 0775); */ -/* sprintf(command, */ -/* "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH, */ -/* execPath, DA_INSTALL_PATH); */ -/* LOGI("appInstallCommand %s\n", command); */ -/* system(command); */ - -/* sprintf(command, */ -/* "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH, */ -/* execPath, DA_BUILD_OPTION); */ -/* LOGI("appInstallCommand %s\n", command); */ -/* system(command); */ - -/* if(startProfiling(flag) < 0) */ -/* { */ -/* sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING); */ -/* return -1; */ -/* } */ - -/* manager.app_launch_timerfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC); */ -/* if(manager.app_launch_timerfd > 0) */ -/* { */ -/* struct itimerspec ctime; */ -/* ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME; */ -/* ctime.it_value.tv_nsec = 0; */ -/* ctime.it_interval.tv_sec = 0; */ -/* ctime.it_interval.tv_nsec = 0; */ -/* if(0 > timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL)) */ -/* { */ -/* LOGE("fail to set app launch timer\n"); */ -/* close(manager.app_launch_timerfd); */ -/* manager.app_launch_timerfd = -1; */ -/* } */ -/* else */ -/* { */ -/* // add event fd to epoll list */ -/* ev.events = EPOLLIN; */ -/* ev.data.fd = manager.app_launch_timerfd; */ -/* if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.app_launch_timerfd, &ev) < 0) */ -/* { */ -/* // fail to add event fd */ -/* LOGE("fail to add app launch timer fd to epoll list\n"); */ -/* close(manager.app_launch_timerfd); */ -/* manager.app_launch_timerfd = -1; */ -/* } */ -/* } */ -/* } */ -/* } */ -/* sendACKStrToHost(MSG_OK, NULL); */ -/* break; */ -/* case MSG_STOP: */ -/* LOGI("MSG_STOP handling\n"); */ -/* sendACKStrToHost(MSG_OK, NULL); */ -/* terminate_all(); */ -/* break; */ -/* case MSG_OPTION: */ -/* if(log->length > 0) */ -/* { */ -/* int i; */ -/* msg_t sendlog; */ -/* manager.config_flag = atoi(log->data); */ -/* sendACKStrToHost(MSG_OK, NULL); */ - -/* LOGI("MSG_OPTION : str(%s), flag(%x)\n", log->data, manager.config_flag); */ - -/* sendlog.type = MSG_OPTION; */ -/* sendlog.length = sprintf(sendlog.data, "%u", manager.config_flag); */ - -/* for(i = 0; i < MAX_TARGET_COUNT; i++) */ -/* { */ -/* if(manager.target[i].socket != -1) */ -/* { */ -/* send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length, MSG_NOSIGNAL); */ -/* } */ -/* } */ -/* } */ -/* else */ -/* { */ -/* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */ -/* ret = 1; */ -/* } */ -/* break; */ -/* case MSG_ISALIVE: */ -/* sendACKStrToHost(MSG_OK, NULL); */ -/* break; */ -/* default: */ -/* LOGW("Unknown msg\n"); */ -/* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_TYPE); */ -/* ret = 1; */ -/* break; */ -/* } */ -/* return ret; */ -/* } */ - -// ======================================================================================== -// socket and event_fd handling functions -// ======================================================================================== +void stop_profiling(void) +{ + if (IS_OPT_SET(FL_RECORDING)) + del_input_events(); + samplingStop(); +} -// return 0 if normal case -// return plus value if non critical error occur -// return minus value if critical error occur - /* -static int deviceEventHandler(input_dev* dev, int input_type) +static void reconfigure_recording(struct conf_t conf) { - int ret = 0; - struct input_event in_ev; - msg_t log; - - if(input_type == INPUT_ID_TOUCH) - { - //touch read - read(dev->fd, &in_ev, sizeof(struct input_event)); - log.type = MSG_RECORD; - log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u", - STR_TOUCH, dev->fileName, in_ev.time.tv_sec, - in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value); - sendDataToHost(&log); + uint64_t old_features = prof_session.conf.use_features0; + uint64_t new_features = conf.use_features0; + uint64_t to_enable = (new_features ^ old_features) & new_features; + uint64_t to_disable = (new_features ^ old_features) & old_features; + + if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) { + del_input_events(); + prof_session.conf.use_features0 &= ~FL_RECORDING; } - else if(input_type == INPUT_ID_KEY) - { - //key read - read(dev->fd, &in_ev, sizeof(struct input_event)); - log.type = MSG_RECORD; - log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u", - STR_KEY, dev->fileName, in_ev.time.tv_sec, - in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value); - sendDataToHost(&log); + + if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) { + add_input_events(); + prof_session.conf.use_features0 |= FL_RECORDING; } - else - { - LOGW("unknown input_type\n"); - ret = 1; + +} + +int reconfigure(struct conf_t conf) +{ + reconfigure_recording(conf); + + samplingStop(); + memcpy(&prof_session.conf, &conf, sizeof(conf)); + if (samplingStart() < 0) { + LOGE("Cannot start sampling\n"); + return -1; } - return ret; + return 0; } -*/ -#define MAX_EVENTS_NUM 10 -static int deviceEventHandler(input_dev* dev, int input_type) +static Ecore_Fd_Handler *target_handlers[MAX_TARGET_COUNT]; + +static int target_event_pid_handler(int index, uint64_t msg) { - int ret = 0; - ssize_t size = 0; - int count = 0; - struct input_event in_ev[MAX_EVENTS_NUM]; - struct msg_data_t *log; - - if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY) - { - do { -// LOGI(">read %s events\n,", input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH); - size = read(dev->fd, &in_ev[count], sizeof(*in_ev) ); -// LOGI("0) - count++; - } while (count < MAX_EVENTS_NUM && size > 0); - - if(count != 0){ - LOGI("readed %d %s events\n", count, input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH); - log = gen_message_event(in_ev, count, input_type); - pseudoSendDataToHost(log); - reset_data_msg(log); + struct app_list_t *app = NULL; + struct app_info_t *app_info = NULL; + if (index == 0) { // main application + app_info = app_info_get_first(&app); + if (app_info == NULL) { + LOGE("No app info found\n"); + return -1; + } + + while (app_info != NULL) { + if (is_same_app_process(app_info->exe_path, + manager.target[index].pid)) + break; + app_info = app_info_get_next(&app); + } + + if (app_info == NULL) { + LOGE("pid %d not found in app list\n", + manager.target[index].pid); + return -1; + } + + if (start_replay() != 0) { + LOGE("Cannot start replay thread\n"); + return -1; } } - else - { - LOGW("unknown input_type\n"); - ret = 1; + manager.target[index].initial_log = 1; + return 0; +} + +static int target_event_stop_handler(int index, uint64_t msg) +{ + LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n", + manager.target[index].socket, manager.target[index].pid, + manager.target_count - 1); + + if (index == 0) // main application + stop_replay(); + + ecore_main_fd_handler_del(target_handlers[index]); + + setEmptyTargetSlot(index); + // all target client are closed + if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) { + LOGI("all targets are stopped\n"); + if (stop_all() != ERR_NO) + LOGE("Stop failed\n"); + return -11; } - return ret; + + return 0; } // return 0 if normal case // return plus value if non critical error occur // return minus value if critical error occur // return -11 if all target process closed -static int targetEventHandler(int epollfd, int index, uint64_t msg) +static int target_event_handler(int index, uint64_t msg) { - if(msg & EVENT_PID) - { - manager.target[index].initial_log = 1; - } + int err = 0; + if (msg & EVENT_PID) + err = target_event_pid_handler(index, msg); + if (err) + return err; - if(msg & EVENT_STOP || msg & EVENT_ERROR) - { - LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n", - manager.target[index].socket, manager.target[index].pid, manager.target_count - 1); + if (msg & EVENT_STOP || msg & EVENT_ERROR) + err = target_event_stop_handler(index, msg); - epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL); - setEmptyTargetSlot(index); - if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) // all target client are closed - return -11; + return err; +} + +static Eina_Bool target_event_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + uint64_t u; + ssize_t recvLen; + int index = (int)data; + + recvLen = read(manager.target[index].event_fd, &u, sizeof(uint64_t)); + if (recvLen != sizeof(uint64_t)) { + // maybe closed, but ignoring is more safe then + // removing fd from event loop + } else { + if (-11 == target_event_handler(index, u)) { + LOGI("all target process is closed\n"); + } } - return 0; + return ECORE_CALLBACK_RENEW; } -// return 0 if normal case -// return plus value if non critical error occur -// return minus value if critical error occur -static int targetServerHandler(int efd) +/** + * return 0 if normal case + * return plus value if non critical error occur + * return minus value if critical error occur + */ +static int targetServerHandler(void) { - msg_t log; - struct epoll_event ev; + msg_target_t log; int index = getEmptyTargetSlot(); - if(index == MAX_TARGET_COUNT) - { + if (index == MAX_TARGET_COUNT) { LOGW("Max target number(8) reached, no more target can connected\n"); return 1; } - manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL); + manager.target[index].socket = + accept(manager.target_server_socket, NULL, NULL); - if(manager.target[index].socket >= 0) // accept succeed - { -#ifndef LOCALTEST - // set smack attribute for certification - fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0); - fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0); -#endif /* LOCALTEST */ + if (manager.target[index].socket >= 0) { + /* accept succeed */ + fd_setup_attributes(manager.target[index].socket); - // send config message to target process + /* send config message to target process */ log.type = MSG_OPTION; - log.length = sprintf(log.data, "%u", manager.config_flag); - send(manager.target[index].socket, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_NOSIGNAL); + log.length = sprintf(log.data, "%llu", + prof_session.conf.use_features0); + if (0 > send(manager.target[index].socket, &log, + sizeof(log.type) + sizeof(log.length) + log.length, + MSG_NOSIGNAL)) + LOGE("fail to send data to target index(%d)\n", index); // make event fd - manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK); - if(manager.target[index].event_fd == -1) - { + manager.target[index].event_fd = eventfd(EFD_CLOEXEC, EFD_NONBLOCK); + if (manager.target[index].event_fd == -1) { // fail to make event fd - LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket); + LOGE("fail to make event fd for socket (%d)\n", + manager.target[index].socket); goto TARGET_CONNECT_FAIL; } - // add event fd to epoll list - ev.events = EPOLLIN; - ev.data.fd = manager.target[index].event_fd; - if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0) - { - // fail to add event fd - LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket); + target_handlers[index] = + ecore_main_fd_handler_add(manager.target[index].event_fd, + ECORE_FD_READ, + target_event_cb, + (void *)index, + NULL, NULL); + if (!target_handlers[index]) { + LOGE("fail to add event fd for socket (%d)\n", + manager.target[index].socket); goto TARGET_CONNECT_FAIL; } // make recv thread for target - if(makeRecvThread(index) != 0) - { + if (makeRecvThread(index) != 0) { // fail to make recv thread - LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket); - epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL); + LOGE("fail to make recv thread for socket (%d)\n", + manager.target[index].socket); + ecore_main_fd_handler_del(target_handlers[index]); goto TARGET_CONNECT_FAIL; } - if(manager.app_launch_timerfd >= 0) - { - epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL); - close(manager.app_launch_timerfd); - manager.app_launch_timerfd = -1; + dec_apps_to_run(); + + if ((manager.app_launch_timerfd > 0) && (get_apps_to_run() == 0)) { + if (stop_app_launch_timer() < 0) + LOGE("cannot stop app launch timer\n"); } LOGI("target connected = %d(running %d target)\n", - manager.target[index].socket, manager.target_count + 1); + manager.target[index].socket, manager.target_count + 1); manager.target_count++; return 0; - } - else // accept error - { + } else { + // accept error LOGE("Failed to accept at target server socket\n"); } -TARGET_CONNECT_FAIL: - if(manager.target_count == 0) // if this connection is main connection - { + TARGET_CONNECT_FAIL: + if (manager.target_count == 0) { + // if this connection is main connection return -1; - } - else // if this connection is not main connection then ignore process by error - { + } else { + // if this connection is not main connection then ignore process by error setEmptyTargetSlot(index); return 1; } } +static Ecore_Fd_Handler *host_ctrl_handler; +static Ecore_Fd_Handler *host_data_handler; + +// return plus value if non critical error occur +// return minus value if critical error occur +// return -11 if socket closed +static int controlSocketHandler(int efd) +{ + ssize_t recv_len; + struct msg_t msg_head; + struct msg_t *msg; + int res = 0; + + if (manager.connect_timeout_timerfd >= 0) { + LOGI("release connect timeout timer\n"); + close(manager.connect_timeout_timerfd); + manager.connect_timeout_timerfd = -1; + } + // Receive header + recv_len = recv(manager.host.control_socket, + &msg_head, MSG_CMD_HDR_LEN, 0); + // error or close request from host + if (recv_len == -1 || recv_len == 0) + return -11; + else { + msg = malloc(MSG_CMD_HDR_LEN + msg_head.len); + if (!msg) { + LOGE("Cannot alloc msg\n"); + sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0); + return -1; + } + msg->id = msg_head.id; + msg->len = msg_head.len; + if (msg->len > 0) { + // Receive payload (if exists) + recv_len = recv(manager.host.control_socket, + msg->payload, msg->len, MSG_WAITALL); + if (recv_len == -1) + return -11; + } + printBuf((char *)msg, MSG_CMD_HDR_LEN + msg->len); + res = host_message_handler(msg); + free(msg); + } + + return res; +} + +static Eina_Bool host_ctrl_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + int result = controlSocketHandler(manager.efd); + if (result == -11) { + // socket close + //if the host disconnected. + //In all other cases daemon must report an error and continue the loop + //close connect_timeoutt and host socket and quit + LOGI("Connection closed. Termination. (%d)\n", + manager.host.control_socket); + ecore_main_loop_quit(); + } else if (result < 0) { + LOGE("Control socket handler.\n"); + } + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool host_data_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + ssize_t recvLen; + char recvBuf[32]; + + recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT); + if (recvLen == 0) { + // close data socket + ecore_main_fd_handler_del(host_data_handler); + close(manager.host.data_socket); + manager.host.data_socket = -1; + // TODO: finish transfer thread + } + + LOGI("host message from data socket %d\n", recvLen); + + return ECORE_CALLBACK_RENEW; +} + // return 0 if normal case // return plus value if non critical error occur // return minus value if critical error occur -static int hostServerHandler(int efd) +static int hostServerHandler(void) { static int hostserverorder = 0; int csocket; - struct epoll_event ev; - if(hostserverorder > 1) // control and data socket connected already - return 1; // ignore + if (hostserverorder > 1) // control and data socket connected already + return 1; // ignore csocket = accept(manager.host_server_socket, NULL, NULL); - if(csocket >= 0) // accept succeed - { - ev.events = EPOLLIN; - ev.data.fd = csocket; - if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0) - { - // consider as accept fail - LOGE("Failed to add socket fd to epoll list\n"); - close(csocket); - return -1; - } + if (csocket >= 0) { + // accept succeed - if(hostserverorder == 0) - { + if (hostserverorder == 0) { manager.host.control_socket = csocket; unlink_portfile(); LOGI("host control socket connected = %d\n", csocket); - } - else - { + host_ctrl_handler = + ecore_main_fd_handler_add(manager.host.control_socket, + ECORE_FD_READ, + host_ctrl_cb, + NULL, + NULL, NULL); + if (!host_ctrl_handler) { + LOGE("Failed to add host control socket fd\n"); + close(csocket); + return -1; + } + } else { manager.host.data_socket = csocket; LOGI("host data socket connected = %d\n", csocket); + + host_data_handler = + ecore_main_fd_handler_add(manager.host.data_socket, + ECORE_FD_READ, + host_data_cb, + NULL, + NULL, NULL); + if (!host_data_handler) { + LOGE("Failed to add host data socket fd\n"); + close(csocket); + return -1; + } } hostserverorder++; return 0; - } - else // accept error - { + } else { + // accept error LOGE("Failed to accept from host server socket\n"); return -1; } } - -// return 0 if normal case -// return plus value if non critical error occur -// return minus value if critical error occur -// return -11 if socket closed - -static int controlSocketHandler(int efd) +static int kernel_handler(void) { - ssize_t recv_len; - struct msg_t msg; - int res = 0; + int res, size, ret; + socklen_t optlen; + struct nlmsghdr *nlh; + struct cn_msg *msg; + ssize_t len; - // Receive header - recv_len = recv(manager.host.control_socket, - &msg, - MSG_CMD_HDR_LEN, 0); - // error or close request from host - if (recv_len == -1 || recv_len == 0) - return -11; - else { - if (msg.len > 0) { - msg.payload = malloc(msg.len); - if (!msg.payload) { - LOGE("Cannot alloc msg payload\n"); - sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); - return 1; - } - // Receive payload (if exists) - recv_len = recv(manager.host.control_socket, - msg.payload, - msg.len, MSG_WAITALL); - } - res = host_message_handler(&msg); - reset_msg(&msg); - } + /* Get buffer size */ + optlen = sizeof(size); - return res; -} + /* We're using SOCK_DGRAM, so, get it maximum size */ + res = getsockopt(manager.kernel_socket, SOL_SOCKET, SO_SNDBUF, &size, + &optlen); -// return 0 for normal case -int daemonLoop() -{ - int ret = 0; // return value - int i, k; - ssize_t recvLen; - - struct epoll_event ev, *events; - int efd; // epoll fd - int numevent; // number of occured events - - _get_fds(g_key_dev, INPUT_ID_KEY); - _get_fds(g_touch_dev, INPUT_ID_TOUCH); - - // initialize epoll event pool - events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE); - if(events == NULL) - { - LOGE("Out of memory when allocate epoll event pool\n"); - ret = -1; - goto END_RETURN; + if (res == -1) { + LOGE("Get maximum buffer size failed\n"); + return -1; } - if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0) - { - LOGE("epoll creation error\n"); + + /* Alloc mem for nlh message struct and receive it */ + nlh = malloc(size); + if (nlh == NULL) + return -1; + len = recv(manager.kernel_socket, nlh, size, 0); + if ((len <= 0) || (nlh->nlmsg_len == 0)) { ret = -1; - goto END_EVENT; + goto free_and_end; } - // add server sockets to epoll event pool - ev.events = EPOLLIN; - ev.data.fd = manager.host_server_socket; - if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.host_server_socket, &ev) < 0) - { - LOGE("Host server socket epoll_ctl error\n"); + /* nlh data field contains connectors message */ + msg = NLMSG_DATA(nlh); + if (msg->len == 0) { ret = -1; - goto END_EFD; + goto free_and_end; } - ev.events = EPOLLIN; - ev.data.fd = manager.target_server_socket; - if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target_server_socket, &ev) < 0) - { - LOGE("Target server socket epoll_ctl error\n"); - ret = -1; - goto END_EFD; + + /* Insert your message handler here */ + + ret = 0; + +free_and_end: + free(nlh); + + return ret; +} + + +static Ecore_Fd_Handler *host_connect_handler; +static Ecore_Fd_Handler *target_connect_handler; +static Ecore_Fd_Handler *kernel_connect_handler; + +static Eina_Bool host_connect_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + // connect request from host + int result = hostServerHandler(); + if (result < 0) { + LOGE("Internal DA framework error (hostServerHandler)\n"); } - // add device fds to epoll event pool - ev.events = EPOLLIN; - for(i = 0; g_key_dev[i].fd != ARRAY_END; i++) - { - if(g_key_dev[i].fd >= 0) - { - ev.data.fd = g_key_dev[i].fd; - if(epoll_ctl(efd, EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0) - { - LOGE("keyboard device file epoll_ctl error\n"); - } - } + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool target_connect_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + if (targetServerHandler() < 0) { + // critical error + terminate_error("Internal DA framework error, " + "Please re-run the profiling " + "(targetServerHandler)\n", 1); } - ev.events = EPOLLIN; - for(i = 0; g_touch_dev[i].fd != ARRAY_END; i++) - { - if(g_touch_dev[i].fd >= 0) - { - ev.data.fd = g_touch_dev[i].fd; - if(epoll_ctl(efd, EPOLL_CTL_ADD, g_touch_dev[i].fd, &ev) < 0) - { - LOGE("touch device file epoll_ctl error\n"); - } - } + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool kernel_connect_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + if (kernel_handler() < 0) { + LOGE("Internal DA framework error (kernel_handler)\n"); } - // handler loop - while (1) - { - numevent = epoll_wait(efd, events, EPOLL_SIZE, -1); - if(numevent <= 0) - { - LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno); - continue; - } + return ECORE_CALLBACK_RENEW; +} - for(i = 0; i < numevent; i++) - { - // check for request from event fd - for(k = 0; k < MAX_TARGET_COUNT; k++) - { - if(manager.target[k].socket != -1 && - events[i].data.fd == manager.target[k].event_fd) - { - uint64_t u; - recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t)); - if(recvLen != sizeof(uint64_t)) - { - // maybe closed, but ignoring is more safe then removing fd from epoll list - } - else - { - if(-11 == targetEventHandler(efd, k, u)) - { - LOGI("all target process is closed\n"); - continue; - } - } - break; - } - } +static bool initialize_events(void) +{ + host_connect_handler = + ecore_main_fd_handler_add(manager.host_server_socket, + ECORE_FD_READ, + host_connect_cb, + NULL, + NULL, NULL); + if (!host_connect_handler) { + LOGE("Host server socket add error\n"); + return false; + } + + target_connect_handler = + ecore_main_fd_handler_add(manager.target_server_socket, + ECORE_FD_READ, + target_connect_cb, + NULL, + NULL, NULL); + if (!target_connect_handler) { + LOGE("Target server socket add error\n"); + return false; + } + + kernel_connect_handler = + ecore_main_fd_handler_add(manager.kernel_socket, + ECORE_FD_READ, + kernel_connect_cb, + NULL, + NULL, NULL); + if (!kernel_connect_handler) { + LOGE("Kernel socket add error\n"); + return false; + } + + return true; +} - if(k != MAX_TARGET_COUNT) - continue; - - // check for request from device fd - for(k = 0; g_touch_dev[k].fd != ARRAY_END; k++) - { - if(g_touch_dev[k].fd >= 0 && - events[i].data.fd == g_touch_dev[k].fd) - { - if(deviceEventHandler(&g_touch_dev[k], INPUT_ID_TOUCH) < 0) - { - terminate_error("Internal DA framework error, Please re-run the profiling.", 1); - ret = -1; - goto END_EFD; - } - break; - } - } +// return 0 for normal case +int daemonLoop(void) +{ + int return_value = 0; - if(g_touch_dev[k].fd != ARRAY_END) - continue; - - for(k = 0; g_key_dev[k].fd != ARRAY_END; k++) - { - if(g_key_dev[k].fd >= 0 && - events[i].data.fd == g_key_dev[k].fd) - { - if(deviceEventHandler(&g_key_dev[k], INPUT_ID_KEY) < 0) - { - terminate_error("Internal DA framework error, Please re-run the profiling.", 1); - ret = -1; - goto END_EFD; - } - break; - } - } + ecore_init(); - if(g_key_dev[k].fd != ARRAY_END) - continue; - - // connect request from target - if(events[i].data.fd == manager.target_server_socket) - { - if(targetServerHandler(efd) < 0) // critical error - { - terminate_error("Internal DA framework error, Please re-run the profiling.", 1); - ret = -1; - goto END_EFD; - } - } - // connect request from host - else if(events[i].data.fd == manager.host_server_socket) - { - int result = hostServerHandler(efd); - if(result < 0) - { - terminate_error("Internal DA framework error, Please re-run the profiling.", 1); - ret = -1; - goto END_EFD; - } - } - // control message from host - else if(events[i].data.fd == manager.host.control_socket) - { - int result = controlSocketHandler(efd); - if(result == -11) // socket close - { - // close target and host socket and quit - LOGI("host close = %d\n", manager.host.control_socket); - ret = 0; - goto END_EFD; - } - else if(result < 0) - { - terminate_error("Internal DA framework error, Please re-run the profiling.", 1); - ret = -1; - goto END_EFD; - } - } - else if(events[i].data.fd == manager.host.data_socket) - { - char recvBuf[32]; - recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT); - if(recvLen == 0) - { // close data socket - epoll_ctl(efd, EPOLL_CTL_DEL, manager.host.data_socket, NULL); - close(manager.host.data_socket); - manager.host.data_socket = -1; - // TODO: finish transfer thread - } - - LOGW("host message from data socket %d\n", recvLen); - } - // check for application launch timerfd - else if(events[i].data.fd == manager.app_launch_timerfd) - { - // send to host timeout error message for launching application - terminate_error("Failed to launch application", 1); - epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL); - close(manager.app_launch_timerfd); - manager.app_launch_timerfd = -1; - ret = -1; - goto END_EFD; - } - // unknown socket - else - { - // never happened - LOGW("Unknown socket fd (%d)\n", events[i].data.fd); - } - } + if (init_input_events() == -1) { + return_value = -1; + goto END_EVENT; } -END_EFD: - close(efd); -END_EVENT: - free(events); -END_RETURN: - return ret; + if (!initialize_events()) { + return_value = -1; + goto END_EFD; + } + + if (launch_timer_start() < 0) { + LOGE("Launch timer start failed\n"); + return_value = -1; + goto END_EFD; + } + + init_prof_session(&prof_session); + + ecore_main_loop_begin(); + ecore_shutdown(); + + END_EFD: + LOGI("close efd\n"); + close(manager.efd); + END_EVENT: + return return_value; }