X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=daemon%2Fdaemon.c;h=ae53677220e86e914e7a839b6a400377a78d03fc;hb=bf21f0426fe844a434b929c90929052fef518052;hp=976ee0bf31b877d10b463cfb68fce86d580855f7;hpb=1c992a3cc6c5a82c8a526e741a0ba8e29b7fcf30;p=platform%2Fcore%2Fsystem%2Fswap-manager.git diff --git a/daemon/daemon.c b/daemon/daemon.c index 976ee0b..ae53677 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -40,165 +40,39 @@ #include // for accept #include // for mkdir #include // for eventfd -#include // for epoll apis #include // for timerfd #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_READELF_PATH "/home/developer/sdk_tools/da/readelf" #define SCREENSHOT_DIR "/tmp/da" -#define EPOLL_SIZE 10 #define MAX_APP_LAUNCH_TIME 60 #define MAX_CONNECT_TIMEOUT_TIME 5*60 -#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); - buffer[ret] = '\0'; - } 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"); - if (_file_read(cmd_fp, buffer, BUF_SIZE) < 0) { - LOGE("Failed to read input_id\n"); - if (cmd_fp != NULL) - pclose(cmd_fp); - return ret; - } - // 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) -{ - 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)); - } - } -} - -uint64_t get_total_alloc_size() +uint64_t get_total_alloc_size(void) { int i; uint64_t allocsize = 0; @@ -242,35 +116,58 @@ static void setEmptyTargetSlot(int index) // start and terminate control functions // ============================================================================= +static Ecore_Fd_Handler *launch_timer_handler; + +//stop application launch timer +static int stop_app_launch_timer() +{ + close(manager.app_launch_timerfd); + manager.app_launch_timerfd = -1; + + return 0; +} + +static Eina_Bool launch_timer_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + LOGE("Failed to launch application\n"); + if (stop_app_launch_timer() < 0) + LOGE("cannot stop app launch timer\n"); + + return ECORE_CALLBACK_CANCEL; +} + //start application launch timer function -static int start_app_launch_timer() +static int start_app_launch_timer(int apps_count) { int res = 0; - struct epoll_event ev; + + 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; + 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"); - close(manager.app_launch_timerfd); - manager.app_launch_timerfd = -1; + stop_app_launch_timer(); res = -1; } else { - // add event fd to epoll list - ev.events = EPOLLIN; - ev.data.fd = manager.app_launch_timerfd; - if (epoll_ctl(manager.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; + 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"); @@ -284,18 +181,23 @@ static int start_app_launch_timer() return res; } -//stop application launch timer -static int stop_app_launch_timer() +static inline void inc_apps_to_run() { - if (0 > epoll_ctl(manager.efd, EPOLL_CTL_DEL, - manager.app_launch_timerfd, NULL)) - LOGW("fail to EPOLL DEL of app launch timerfd\n"); - close(manager.app_launch_timerfd); - manager.app_launch_timerfd = -1; - return 0; + manager.apps_to_run++; +} + +static inline void dec_apps_to_run() +{ + if (manager.apps_to_run > 0) + manager.apps_to_run--; } -int kill_app_by_info(const struct app_info_t *app_info) +static inline int get_apps_to_run() +{ + return manager.apps_to_run; +} + +static int kill_app_by_info(const struct app_info_t *app_info) { int res = 0; @@ -338,6 +240,8 @@ static int exec_app(const struct app_info_t *app_info) if (exec_app_tizen(app_info->app_id, app_info->exe_path)) { LOGE("Cannot exec tizen app %s\n", app_info->app_id); res = -1; + } else { + inc_apps_to_run(); } break; case APP_TYPE_RUNNING: @@ -348,6 +252,8 @@ static int exec_app(const struct app_info_t *app_info) if (exec_app_common(app_info->exe_path)) { LOGE("Cannot exec common app %s\n", app_info->exe_path); res = -1; + } else { + inc_apps_to_run(); } break; default: @@ -356,17 +262,84 @@ static int exec_app(const struct app_info_t *app_info) break; } - if (res == 0 && app_info->app_type != APP_TYPE_RUNNING) - if (start_app_launch_timer() < 0) - res = -1; - LOGI("ret=%d\n", res); return res; } -int launch_timer_start() +// just send stop message to all target process +static void terminate_all_target() +{ + int i; + ssize_t sendlen; + 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); + } + } + } +} + +// terminate all target and wait for threads +void terminate_all() +{ + int i; + terminate_all_target(); + + // wait for all other thread exit + 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 +// TODO: don't send data to host +static void terminate_error(char *errstr, int send_to_host) +{ + 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(); +} + +static Ecore_Fd_Handler *connect_timer_handler; + +static Eina_Bool connect_timer_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + 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; +} + +static int launch_timer_start(void) { - static struct epoll_event ev; int res = 0; manager.connect_timeout_timerfd = @@ -382,14 +355,14 @@ int launch_timer_start() close(manager.connect_timeout_timerfd); manager.connect_timeout_timerfd = -1; } else { - // add event fd to epoll list - ev.events = EPOLLIN; - ev.data.fd = manager.connect_timeout_timerfd; - if (epoll_ctl(manager.efd, EPOLL_CTL_ADD, - manager.connect_timeout_timerfd, &ev) < 0) - { - // fail to add event fd - LOGE("fail to add app connection timeout timer fd to epoll list\n"); + 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 { @@ -404,10 +377,7 @@ int launch_timer_start() return res; } -static void epoll_add_input_events(); -static void epoll_del_input_events(); - -int prepare_profiling() +int prepare_profiling(void) { struct app_list_t *app = NULL; const struct app_info_t *app_info = NULL; @@ -433,7 +403,7 @@ int prepare_profiling() } -int start_profiling() +int start_profiling(void) { struct app_list_t *app = NULL; const struct app_info_t *app_info = NULL; @@ -450,9 +420,7 @@ int start_profiling() LOGW("Failed to create directory for screenshot : %s\n", strerror(errno)); -#ifndef LOCALTEST - smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS); -#endif + set_label_for_all(SCREENSHOT_DIR); if (samplingStart() < 0) { LOGE("Cannot start sampling\n"); @@ -461,10 +429,18 @@ int start_profiling() } if (IS_OPT_SET(FL_RECORDING)) - epoll_add_input_events(); + add_input_events(); - if (exec_app(app_info)) { - LOGE("Cannot exec app\n"); + 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; } @@ -473,7 +449,7 @@ int start_profiling() recording_stop: if (IS_OPT_SET(FL_RECORDING)) - epoll_del_input_events(); + del_input_events(); samplingStop(); exit: @@ -484,7 +460,7 @@ int start_profiling() void stop_profiling(void) { if (IS_OPT_SET(FL_RECORDING)) - epoll_del_input_events(); + del_input_events(); samplingStop(); } @@ -496,12 +472,12 @@ static void reconfigure_recording(struct conf_t conf) uint64_t to_disable = (new_features ^ old_features) & old_features; if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) { - epoll_del_input_events(); + del_input_events(); prof_session.conf.use_features0 &= ~FL_RECORDING; } if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) { - epoll_add_input_events(); + add_input_events(); prof_session.conf.use_features0 |= FL_RECORDING; } @@ -521,97 +497,7 @@ int reconfigure(struct conf_t conf) return 0; } -// just send stop message to all target process -static void terminate_all_target() -{ - int i; - ssize_t sendlen; - 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) { - // send to only first main target proces - LOGI("TERMINATE send exit msg (socket %d) " - "by terminate_all_target()\n", - manager.target[i].socket); - break; - } - } - } -} - -// terminate all target and wait for threads -void terminate_all() -{ - int i; - terminate_all_target(); - - // wait for all other thread exit - 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 -// TODO: don't send data to host -static void terminate_error(char *errstr, int send_to_host) -{ - 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(); -} - -#define MAX_EVENTS_NUM 10 -static int deviceEventHandler(input_dev *dev, int input_type) -{ - 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 { - size = read(dev->fd, &in_ev[count], sizeof(*in_ev)); - if (size > 0) - count++; - } while (count < MAX_EVENTS_NUM && size > 0); - - if (count) { - LOGI("read %d %s events\n", - count, - input_type == INPUT_ID_KEY ? STR_KEY : STR_TOUCH); - log = gen_message_event(in_ev, count, input_type); - printBuf((char *)log, MSG_DATA_HDR_LEN + log->len); - write_to_buf(log); - free_msg_data(log); - } - } else { - LOGW("unknown input_type\n"); - ret = 1; // it is not error - } - return ret; -} +static Ecore_Fd_Handler *target_handlers[MAX_TARGET_COUNT]; static int target_event_pid_handler(int index, uint64_t msg) { @@ -646,7 +532,7 @@ static int target_event_pid_handler(int index, uint64_t msg) return 0; } -static int target_event_stop_handler(int epollfd, int index, uint64_t msg) +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, @@ -655,9 +541,7 @@ static int target_event_stop_handler(int epollfd, int index, uint64_t msg) if (index == 0) // main application stop_replay(); - if (0 > epoll_ctl(epollfd, EPOLL_CTL_DEL, - manager.target[index].event_fd, NULL)) - LOGW("fail to EPOLL DEL of event fd(%d)\n", index); + ecore_main_fd_handler_del(target_handlers[index]); setEmptyTargetSlot(index); // all target client are closed @@ -675,7 +559,7 @@ static int target_event_stop_handler(int epollfd, int index, uint64_t msg) // return plus value if non critical error occur // return minus value if critical error occur // return -11 if all target process closed -static int target_event_handler(int epollfd, int index, uint64_t msg) +static int target_event_handler(int index, uint64_t msg) { int err = 0; if (msg & EVENT_PID) @@ -684,20 +568,38 @@ static int target_event_handler(int epollfd, int index, uint64_t msg) return err; if (msg & EVENT_STOP || msg & EVENT_ERROR) - err = target_event_stop_handler(epollfd, index, msg); + err = target_event_stop_handler(index, msg); 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 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) +static int targetServerHandler(void) { msg_target_t log; - struct epoll_event ev; int index = getEmptyTargetSlot(); if (index == MAX_TARGET_COUNT) { @@ -710,19 +612,19 @@ static int targetServerHandler(int efd) if (manager.target[index].socket >= 0) { /* accept succeed */ - fd_setup_smack_attributes(manager.target[index].socket); + fd_setup_attributes(manager.target[index].socket); /* send config message to target process */ log.type = MSG_OPTION; - log.length = sprintf(log.data, "%lu", - (unsigned long int)prof_session.conf.use_features0); + 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); + 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", @@ -730,12 +632,14 @@ static int targetServerHandler(int efd) 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", + 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; } @@ -745,14 +649,13 @@ static int targetServerHandler(int efd) // fail to make recv thread LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket); - if (0 > epoll_ctl(efd, EPOLL_CTL_DEL, - manager.target[index].event_fd, NULL)) - LOGW("fail to EPOLL DEL of event fd(%d)\n", index); + ecore_main_fd_handler_del(target_handlers[index]); goto TARGET_CONNECT_FAIL; } - if (manager.app_launch_timerfd >= 0) { - LOGI("release launch timer\n"); + 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"); } @@ -778,53 +681,12 @@ 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 hostServerHandler(int efd) -{ - static int hostserverorder = 0; - int csocket; - struct epoll_event ev; - - 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 (hostserverorder == 0) { - manager.host.control_socket = csocket; - unlink_portfile(); - LOGI("host control socket connected = %d\n", csocket); - } else { - manager.host.data_socket = csocket; - LOGI("host data socket connected = %d\n", csocket); - } - - hostserverorder++; - return 0; - } else { - // accept error - LOGE("Failed to accept from host server socket\n"); - 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; @@ -834,9 +696,6 @@ static int controlSocketHandler(int efd) if (manager.connect_timeout_timerfd >= 0) { LOGI("release connect timeout timer\n"); - if (0 > epoll_ctl(efd, EPOLL_CTL_DEL, - manager.connect_timeout_timerfd, NULL)) - LOGW("fail to EPOLL DEL of timeout timer fd\n"); close(manager.connect_timeout_timerfd); manager.connect_timeout_timerfd = -1; } @@ -870,96 +729,235 @@ static int controlSocketHandler(int efd) return res; } -static void epoll_add_input_events() +static Eina_Bool host_ctrl_cb(void *data, Ecore_Fd_Handler *fd_handler) { - struct epoll_event ev; - int i; + 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; +} - // 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(manager.efd, - EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0 - && errno != EEXIST) - LOGE("keyboard device file epoll_ctl error: %s\n", strerror(errno)); - } +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 } - 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(manager.efd, - EPOLL_CTL_ADD, - g_touch_dev[i].fd, &ev) < 0 - && errno != EEXIST) - LOGE("touch device file epoll_ctl error: %s\n", strerror(errno)); + 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(void) +{ + static int hostserverorder = 0; + int csocket; + + 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 + + if (hostserverorder == 0) { + manager.host.control_socket = csocket; + unlink_portfile(); + LOGI("host control socket connected = %d\n", csocket); + 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 + LOGE("Failed to accept from host server socket\n"); + return -1; } } -static void epoll_del_input_events() +static int kernel_handler(void) { - int i; + int res, size, ret; + socklen_t optlen; + struct nlmsghdr *nlh; + struct cn_msg *msg; + ssize_t len; + + /* Get buffer size */ + optlen = sizeof(size); + + /* We're using SOCK_DGRAM, so, get it maximum size */ + res = getsockopt(manager.kernel_socket, SOL_SOCKET, SO_SNDBUF, &size, + &optlen); + + if (res == -1) { + LOGE("Get maximum buffer size failed\n"); + return -1; + } + + /* 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 free_and_end; + } + + /* nlh data field contains connectors message */ + msg = NLMSG_DATA(nlh); + if (msg->len == 0) { + ret = -1; + goto free_and_end; + } + + /* Insert your message handler here */ + + ret = 0; - // remove device fds from epoll event pool - for (i = 0; g_key_dev[i].fd != ARRAY_END; i++) - if (g_key_dev[i].fd >= 0) - if (epoll_ctl(manager.efd, - EPOLL_CTL_DEL, g_key_dev[i].fd, NULL) < 0) - LOGE("keyboard device file epoll_ctl error: %s\n", strerror(errno)); - - for (i = 0; g_touch_dev[i].fd != ARRAY_END; i++) - if (g_touch_dev[i].fd >= 0) - if (epoll_ctl(manager.efd, - EPOLL_CTL_DEL, - g_touch_dev[i].fd, NULL) < 0) - LOGE("touch device file epoll_ctl error: %s\n", strerror(errno)); +free_and_end: + free(nlh); + + return ret; } -static bool initialize_epoll_events(void) + +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) { - struct epoll_event ev; + // connect request from host + int result = hostServerHandler(); + if (result < 0) { + LOGE("Internal DA framework error (hostServerHandler)\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); + } + + 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"); + } - if ((manager.efd = epoll_create1(0)) < 0) { - LOGE("epoll creation error\n"); + return ECORE_CALLBACK_RENEW; +} + +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; } - // add server sockets to epoll event pool - ev.events = EPOLLIN; - ev.data.fd = manager.host_server_socket; - if (epoll_ctl(manager.efd, EPOLL_CTL_ADD, - manager.host_server_socket, &ev) < 0) { - LOGE("Host server socket epoll_ctl error\n"); + + 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; } - ev.events = EPOLLIN; - ev.data.fd = manager.target_server_socket; - if (epoll_ctl(manager.efd, EPOLL_CTL_ADD, - manager.target_server_socket, &ev) < 0) { - LOGE("Target server socket epoll_ctl error\n"); + + 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; } // return 0 for normal case -int daemonLoop() +int daemonLoop(void) { int return_value = 0; - struct epoll_event *events = malloc(EPOLL_SIZE * sizeof(*events)); - _get_fds(g_key_dev, INPUT_ID_KEY); - _get_fds(g_touch_dev, INPUT_ID_TOUCH); + ecore_init(); - if (!events) { - LOGE("Out of memory when allocate epoll event pool\n"); + if (init_input_events() == -1) { return_value = -1; goto END_EVENT; } - if (!initialize_epoll_events()) { + + if (!initialize_events()) { return_value = -1; goto END_EFD; } @@ -972,153 +970,12 @@ int daemonLoop() init_prof_session(&prof_session); - // handler loop - while (1) { - int i, k; - ssize_t recvLen; - // number of occured events - int numevent = epoll_wait(manager.efd, events, EPOLL_SIZE, -1); - if (numevent <= 0) { - LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno); - continue; - } - - 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 == target_event_handler(manager.efd, k, u)) { - LOGI("all target process is closed\n"); - continue; - } - } - break; - } - } - - 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) { - LOGE("Internal DA framework error, " - "Please re-run the profiling (touch dev)\n"); - continue; - } - break; - } - } - - 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) { - LOGE("Internal DA framework error, " - "Please re-run the profiling (key dev)\n"); - continue; - } - break; - } - } - - if (g_key_dev[k].fd != ARRAY_END) - continue; - - // connect request from target - if (events[i].data.fd == manager.target_server_socket) { - if (targetServerHandler(manager.efd) < 0) { - // critical error - terminate_error("Internal DA framework error, " - "Please re-run the profiling " - "(targetServerHandler)\n", 1); - continue; - } - } else if (events[i].data.fd == manager.host_server_socket) { - // connect request from host - int result = hostServerHandler(manager.efd); - if (result < 0) { - LOGE("Internal DA framework error (hostServerHandler)\n"); - continue; - } - } else if (events[i].data.fd == manager.host.control_socket) { - // control message from host - 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); - return_value = 0; - goto END_EFD; - } else if (result < 0) { - LOGE("Control socket handler.\n"); - } - } 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 - if (0 > epoll_ctl(manager.efd, - EPOLL_CTL_DEL, - manager.host.data_socket, - NULL)) - LOGW("fail to EPOLL DEL of host data socket\n"); - close(manager.host.data_socket); - manager.host.data_socket = -1; - // TODO: finish transfer thread - } - - LOGI("host message from data socket %d\n", - recvLen); - } else if (events[i].data.fd == manager.app_launch_timerfd) { - // check for application launch timerfd - // send to host timeout error message for launching application - LOGE("Failed to launch application\n"); - if (stop_app_launch_timer() < 0) - LOGE("cannot stop app launch timer\n"); - continue; - } else if (events[i].data.fd == manager.connect_timeout_timerfd) { - // check for connection timeout timerfd - // send to host timeout error message for launching application - terminate_error("no incoming connections", 1); - if (0 > epoll_ctl(manager.efd, EPOLL_CTL_DEL, - manager.connect_timeout_timerfd, - NULL)) - LOGW("fail to EPOLL DEL of timeout timer fd\n"); - close(manager.connect_timeout_timerfd); - manager.connect_timeout_timerfd = -1; - LOGE("No connection in %d sec. shutdown.\n", - MAX_CONNECT_TIMEOUT_TIME); - goto END_EFD; - } else { - // unknown socket - // never happened - LOGW("Unknown socket fd (%d)\n", - events[i].data.fd); - } - } - } + ecore_main_loop_begin(); + ecore_shutdown(); END_EFD: LOGI("close efd\n"); close(manager.efd); END_EVENT: - free(events); return return_value; }