4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
8 * Jaewon Lim <jaewon81.lim@samsung.com>
9 * Woojin Jung <woojin2.jung@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
16 * http://www.apache.org/licenses/LICENSE-2.0
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
30 #include <stdlib.h> // for realpath
31 #include <string.h> // for strtok, strcpy, strncpy
32 #include <limits.h> // for realpath
34 #include <errno.h> // for errno
35 #include <sys/types.h> // for accept, mkdir, opendir, readdir
36 #include <sys/socket.h> // for accept
37 #include <sys/stat.h> // for mkdir
38 #include <sys/eventfd.h> // for eventfd
39 #include <sys/epoll.h> // for epoll apis
40 #include <sys/timerfd.h> // for timerfd
41 #include <unistd.h> // for access, sleep
46 #include <attr/xattr.h> // for fsetxattr
47 #include <sys/smack.h>
50 #include <linux/input.h>
56 #include "da_protocol.h"
60 #define DA_WORK_DIR "/home/developer/sdk_tools/da/"
61 #define DA_READELF_PATH "/home/developer/sdk_tools/da/readelf"
62 #define SCREENSHOT_DIR "/tmp/da"
65 #define MAX_CONNECT_SIZE 12
66 #define MAX_APP_LAUNCH_TIME 6
69 #define MAX_FILENAME 128
71 #define ARRAY_END (-11)
73 input_dev g_key_dev[MAX_DEVICE];
74 input_dev g_touch_dev[MAX_DEVICE];
76 // return bytes size of readed data
77 // return 0 if no data readed or error occurred
78 static int _file_read(FILE* fp, char *buffer, int size)
82 if(fp != NULL && size > 0)
84 ret = fread((void*)buffer, sizeof(char), size, fp);
92 ret = 0; // error case
98 // get input id of given input device
99 static int get_input_id(char* inputname)
101 static int query_cmd_type = 0; // 1 if /lib/udev/input_id, 2 if udevadm
103 char buffer[BUF_SIZE];
104 char command[MAX_FILENAME];
107 // determine input_id query command
108 if(unlikely(query_cmd_type == 0))
110 if(access("/lib/udev/input_id", F_OK) == 0) // there is /lib/udev/input_id
114 else // there is not /lib/udev/input_id
120 // make command string
121 if(query_cmd_type == 1)
123 sprintf(command, "/lib/udev/input_id /class/input/%s", inputname);
127 sprintf(command, "udevadm info --name=input/%s --query=property", inputname);
131 cmd_fp = popen(command, "r");
132 _file_read(cmd_fp, buffer, BUF_SIZE);
134 // determine input id
135 if(strstr(buffer, INPUT_ID_STR_KEY)) // key
139 else if(strstr(buffer, INPUT_ID_STR_TOUCH)) // touch
141 ret = INPUT_ID_TOUCH;
143 else if(strstr(buffer, INPUT_ID_STR_KEYBOARD)) // keyboard
147 else if(strstr(buffer, INPUT_ID_STR_TABLET)) // touch (emulator)
149 ret = INPUT_ID_TOUCH;
157 // get filename and fd of given input type devices
158 static void _get_fds(input_dev *dev, int input_id)
164 dp = opendir("/sys/class/input");
168 while((d = readdir(dp)) != NULL)
170 if(!strncmp(d->d_name, "event", 5)) // start with "event"
173 if(input_id == get_input_id(d->d_name))
175 sprintf(dev[count].fileName, "/dev/input/%s", d->d_name);
176 dev[count].fd = open(dev[count].fileName, O_RDWR | O_NONBLOCK);
184 dev[count].fd = ARRAY_END; // end of input_dev array
188 void _device_write(input_dev *dev, struct input_event* in_ev)
191 for(i = 0; dev[i].fd != ARRAY_END; i++)
195 write(dev[i].fd, in_ev, sizeof(struct input_event));
196 LOGI("write(%d, %d, %d)\n",dev[i].fd, (int)in_ev, sizeof(struct input_event));
201 long long get_total_alloc_size()
204 long long allocsize = 0;
206 for(i = 0; i < MAX_TARGET_COUNT; i++)
208 if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0)
209 allocsize += manager.target[i].allocmem;
214 static int getEmptyTargetSlot()
217 for(i = 0; i < MAX_TARGET_COUNT; i++)
219 if(manager.target[i].socket == -1)
226 static void setEmptyTargetSlot(int index)
228 if(index >= 0 && index < MAX_TARGET_COUNT)
230 manager.target[index].pid = -1;
231 manager.target[index].recv_thread = -1;
232 manager.target[index].allocmem = 0;
233 manager.target[index].starttime = 0;
234 manager.target[index].initial_log = 0;
235 if(manager.target[index].event_fd != -1)
236 close(manager.target[index].event_fd);
237 manager.target[index].event_fd = -1;
238 if(manager.target[index].socket != -1)
239 close(manager.target[index].socket);
240 manager.target[index].socket = -1;
244 // ======================================================================================
245 // send functions to host
246 // ======================================================================================
248 int pseudoSendDataToHost(struct msg_data_t* log)
251 printBuf((char *)log, MSG_DATA_HDR_LEN + log->len);
252 /* LOGI("try send to <%d><%s>\n", dev->fd, dev->fileName); */
259 int sendDataToHost(msg_t* log)
261 if (manager.host.data_socket != -1)
263 char logstr[DA_MSG_MAX];
267 loglen = sprintf(logstr, "%d|%d|%s\n", log->type, log->length + 1, log->data);
269 loglen = sprintf(logstr, "%d|%d|\n", log->type, log->length + 1);
271 // loglen = sprintf(logstr, "%d|%s\n", log->type, log->data);
273 pthread_mutex_lock(&(manager.host.data_socket_mutex));
274 send(manager.host.data_socket, logstr, loglen, MSG_NOSIGNAL);
275 pthread_mutex_unlock(&(manager.host.data_socket_mutex));
282 // msgstr can be NULL
284 static int sendACKStrToHost(enum HostMessageType resp, char* msgstr)
286 if (manager.host.control_socket != -1)
288 char logstr[DA_MSG_MAX];
292 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, strlen(msgstr), msgstr);
294 loglen = sprintf(logstr, "%d|0|", (int)resp);
296 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
306 int sendACKCodeToHost(enum HostMessageType resp, int msgcode)
309 //disabled string protocol
311 if (manager.host.control_socket != -1)
314 char logstr[DA_MSG_MAX];
317 codelen = sprintf(codestr, "%d", msgcode);
318 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr);
320 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
327 // ========================================================================================
328 // start and terminate control functions
329 // ========================================================================================
331 int startProfiling(long launchflag)
333 const struct app_info_t *app_info = &prof_session.app_info;
335 // remove previous screen capture files
336 remove_indir(SCREENSHOT_DIR);
337 mkdir(SCREENSHOT_DIR, 0777);
339 smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
341 manager.config_flag = launchflag;
343 if (samplingStart() < 0)
346 switch (app_info->app_type) {
348 if (exec_app_tizen(app_info->app_id, app_info->exe_path)) {
349 LOGE("Cannot exec tizen app %s\n", app_info->app_id);
354 case APP_TYPE_RUNNING:
355 // TODO: nothing, it's running
357 case APP_TYPE_COMMON:
358 if (exec_app_common(app_info->exe_path)) {
359 LOGE("Cannot exec common app %s\n", app_info->exe_path);
365 LOGE("Unknown app type %d\n", app_info->app_type);
371 if (start_replay() != 0) {
372 LOGE("Cannot start replay thread\n");
379 // terminate single target
380 // just send stop message to target process
381 static void terminate_target(int index)
385 sendlog.type = MSG_STOP;
388 if(manager.target[index].socket != -1)
390 // result of sending to disconnected socket is not expected
391 sendlen = send(manager.target[index].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
394 LOGI("TERMINATE send exit msg (socket %d) by terminate_target()\n", manager.target[index].socket);
399 // just send stop message to all target process
400 static void terminate_all_target()
406 sendlog.type = MSG_STOP;
409 for (i = 0; i < MAX_TARGET_COUNT; i++)
411 if(manager.target[i].socket != -1)
413 sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
416 LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket);
422 // terminate all target and wait for threads
427 terminate_all_target();
429 // wait for all other thread exit
430 for(i = 0; i < MAX_TARGET_COUNT; i++)
432 if(manager.target[i].recv_thread != -1)
434 pthread_join(manager.target[i].recv_thread, NULL);
439 // terminate all profiling by critical error
440 static void terminate_error(char* errstr, int sendtohost)
444 LOGE("TERMINATE ERROR: %s\n", errstr);
447 log.type = MSG_ERROR;
448 log.length = sprintf(log.data, "%s", errstr);
449 sendDataToHost(&log);
455 // ===========================================================================================
456 // message parsing and handling functions
457 // ===========================================================================================
459 static int parseDeviceMessage(msg_t* log)
461 char eventType[MAX_FILENAME];
462 struct input_event in_ev;
474 for(i = 0; i < log->length; i++)
476 if(log->data[i] == '\n')
479 if(log->data[i] == '`') // meet separate
486 if(index == 0) // parse eventType
488 eventType[i] = log->data[i];
489 eventType[i+1] = '\0';
491 else if(index == 1) // parse in_ev.type
493 in_ev.type = in_ev.type * 10 + (log->data[i] - '0');
495 else if(index == 2) // parse in_ev.code
497 in_ev.code = in_ev.code * 10 + (log->data[i] - '0');
499 else if(index == 3) // parse in_ev.value
501 in_ev.value = in_ev.value * 10 + (log->data[i] - '0');
506 return -1; // parse error
508 if(0 == strncmp(eventType, STR_TOUCH, strlen(STR_TOUCH)))
510 _device_write(g_touch_dev, &in_ev);
512 else if(0 == strncmp(eventType, STR_KEY, strlen(STR_KEY)))
514 _device_write(g_key_dev, &in_ev);
521 // return 0 if normal case
522 // return plus value if non critical error occur
523 // return minus value if critical error occur
524 /* static int _hostMessageHandler(int efd,struct msg_t* log) */
529 /* char *barloc, *tmploc; */
530 /* char execPath[PATH_MAX]; */
532 /* if (log == NULL) */
535 /* switch (log->type) */
537 /* case MSG_REPLAY: */
538 /* sendACKStrToHost(MSG_OK, NULL); */
539 /* parseDeviceMessage(log); */
541 /* case MSG_VERSION: */
542 /* if(strcmp(PROTOCOL_VERSION, log->data) != 0) */
544 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_PROTOCOL_VERSION); */
548 /* sendACKStrToHost(MSG_OK, NULL); */
551 /* case MSG_START: */
552 /* LOGI("MSG_START handling : %s\n", log->data); */
553 /* if(log->length == 0) */
555 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */
556 /* return -1; // wrong message format */
559 /* // parsing for host start status */
560 /* tmploc = log->data; */
561 /* barloc = strchr(tmploc, '|'); */
562 /* if(barloc == NULL) */
564 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */
565 /* return -1; // wrong message format */
568 /* // parsing for target launch option flag */
569 /* tmploc = barloc + 1; */
570 /* barloc = strchr(tmploc, '|'); */
571 /* if(barloc != NULL) */
573 /* while(tmploc < barloc) */
575 /* flag = (flag * 10) + (*tmploc - '0'); */
581 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */
582 /* return -1; // wrong message format */
584 /* LOGI("launch flag : %lx\n", flag); */
586 /* // parsing for application package name */
587 /* tmploc = barloc + 1; */
588 /* strcpy(manager.appPath, tmploc); */
590 /* get_executable(manager.appPath, execPath, PATH_MAX); // get exact app executable file name */
591 /* LOGI("executable app path %s\n", manager.appPath); */
593 /* #ifdef RUN_APP_LOADER */
594 /* kill_app(manager.appPath); */
596 /* kill_app(execPath); */
600 /* char command[PATH_MAX]; */
601 /* struct epoll_event ev; */
603 /* //save app install path */
604 /* mkdir(DA_WORK_DIR, 0775); */
605 /* sprintf(command, */
606 /* "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH, */
607 /* execPath, DA_INSTALL_PATH); */
608 /* LOGI("appInstallCommand %s\n", command); */
609 /* system(command); */
611 /* sprintf(command, */
612 /* "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH, */
613 /* execPath, DA_BUILD_OPTION); */
614 /* LOGI("appInstallCommand %s\n", command); */
615 /* system(command); */
617 /* if(startProfiling(flag) < 0) */
619 /* sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING); */
623 /* manager.app_launch_timerfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC); */
624 /* if(manager.app_launch_timerfd > 0) */
626 /* struct itimerspec ctime; */
627 /* ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME; */
628 /* ctime.it_value.tv_nsec = 0; */
629 /* ctime.it_interval.tv_sec = 0; */
630 /* ctime.it_interval.tv_nsec = 0; */
631 /* if(0 > timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL)) */
633 /* LOGE("fail to set app launch timer\n"); */
634 /* close(manager.app_launch_timerfd); */
635 /* manager.app_launch_timerfd = -1; */
639 /* // add event fd to epoll list */
640 /* ev.events = EPOLLIN; */
641 /* ev.data.fd = manager.app_launch_timerfd; */
642 /* if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.app_launch_timerfd, &ev) < 0) */
644 /* // fail to add event fd */
645 /* LOGE("fail to add app launch timer fd to epoll list\n"); */
646 /* close(manager.app_launch_timerfd); */
647 /* manager.app_launch_timerfd = -1; */
652 /* sendACKStrToHost(MSG_OK, NULL); */
655 /* LOGI("MSG_STOP handling\n"); */
656 /* sendACKStrToHost(MSG_OK, NULL); */
657 /* terminate_all(); */
659 /* case MSG_OPTION: */
660 /* if(log->length > 0) */
664 /* manager.config_flag = atoi(log->data); */
665 /* sendACKStrToHost(MSG_OK, NULL); */
667 /* LOGI("MSG_OPTION : str(%s), flag(%x)\n", log->data, manager.config_flag); */
669 /* sendlog.type = MSG_OPTION; */
670 /* sendlog.length = sprintf(sendlog.data, "%u", manager.config_flag); */
672 /* for(i = 0; i < MAX_TARGET_COUNT; i++) */
674 /* if(manager.target[i].socket != -1) */
676 /* send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length, MSG_NOSIGNAL); */
682 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */
686 /* case MSG_ISALIVE: */
687 /* sendACKStrToHost(MSG_OK, NULL); */
690 /* LOGW("Unknown msg\n"); */
691 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_TYPE); */
698 // ========================================================================================
699 // socket and event_fd handling functions
700 // ========================================================================================
702 // return 0 if normal case
703 // return plus value if non critical error occur
704 // return minus value if critical error occur
706 static int deviceEventHandler(input_dev* dev, int input_type)
709 struct input_event in_ev;
712 if(input_type == INPUT_ID_TOUCH)
715 read(dev->fd, &in_ev, sizeof(struct input_event));
716 log.type = MSG_RECORD;
717 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
718 STR_TOUCH, dev->fileName, in_ev.time.tv_sec,
719 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
720 sendDataToHost(&log);
722 else if(input_type == INPUT_ID_KEY)
725 read(dev->fd, &in_ev, sizeof(struct input_event));
726 log.type = MSG_RECORD;
727 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
728 STR_KEY, dev->fileName, in_ev.time.tv_sec,
729 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
730 sendDataToHost(&log);
734 LOGW("unknown input_type\n");
742 #define MAX_EVENTS_NUM 10
743 static int deviceEventHandler(input_dev* dev, int input_type)
748 struct input_event in_ev[MAX_EVENTS_NUM];
749 struct msg_data_t *log;
751 if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
754 // LOGI(">read %s events\n,", input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH);
755 size = read(dev->fd, &in_ev[count], sizeof(*in_ev) );
756 // LOGI("<read %s events : size = %d\n,", input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH,size);
759 } while (count < MAX_EVENTS_NUM && size > 0);
762 LOGI("readed %d %s events\n", count, input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH);
763 log = gen_message_event(in_ev, count, input_type);
764 pseudoSendDataToHost(log);
770 LOGW("unknown input_type\n");
776 // return 0 if normal case
777 // return plus value if non critical error occur
778 // return minus value if critical error occur
779 // return -11 if all target process closed
780 static int targetEventHandler(int epollfd, int index, uint64_t msg)
784 manager.target[index].initial_log = 1;
787 if(msg & EVENT_STOP || msg & EVENT_ERROR)
789 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
790 manager.target[index].socket, manager.target[index].pid, manager.target_count - 1);
792 epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
793 setEmptyTargetSlot(index);
794 if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) // all target client are closed
801 // return 0 if normal case
802 // return plus value if non critical error occur
803 // return minus value if critical error occur
804 static int targetServerHandler(int efd)
807 struct epoll_event ev;
809 int index = getEmptyTargetSlot();
810 if(index == MAX_TARGET_COUNT)
812 LOGW("Max target number(8) reached, no more target can connected\n");
816 manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL);
818 if(manager.target[index].socket >= 0) // accept succeed
821 // set smack attribute for certification
822 fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
823 fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
824 #endif /* LOCALTEST */
826 // send config message to target process
827 log.type = MSG_OPTION;
828 log.length = sprintf(log.data, "%u", manager.config_flag);
829 send(manager.target[index].socket, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_NOSIGNAL);
832 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
833 if(manager.target[index].event_fd == -1)
835 // fail to make event fd
836 LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket);
837 goto TARGET_CONNECT_FAIL;
840 // add event fd to epoll list
842 ev.data.fd = manager.target[index].event_fd;
843 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
845 // fail to add event fd
846 LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket);
847 goto TARGET_CONNECT_FAIL;
850 // make recv thread for target
851 if(makeRecvThread(index) != 0)
853 // fail to make recv thread
854 LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket);
855 epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
856 goto TARGET_CONNECT_FAIL;
859 if(manager.app_launch_timerfd >= 0)
861 epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
862 close(manager.app_launch_timerfd);
863 manager.app_launch_timerfd = -1;
866 LOGI("target connected = %d(running %d target)\n",
867 manager.target[index].socket, manager.target_count + 1);
869 manager.target_count++;
874 LOGE("Failed to accept at target server socket\n");
878 if(manager.target_count == 0) // if this connection is main connection
882 else // if this connection is not main connection then ignore process by error
884 setEmptyTargetSlot(index);
889 // return 0 if normal case
890 // return plus value if non critical error occur
891 // return minus value if critical error occur
892 static int hostServerHandler(int efd)
894 static int hostserverorder = 0;
896 struct epoll_event ev;
898 if(hostserverorder > 1) // control and data socket connected already
901 csocket = accept(manager.host_server_socket, NULL, NULL);
903 if(csocket >= 0) // accept succeed
906 ev.data.fd = csocket;
907 if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
909 // consider as accept fail
910 LOGE("Failed to add socket fd to epoll list\n");
915 if(hostserverorder == 0)
917 manager.host.control_socket = csocket;
919 LOGI("host control socket connected = %d\n", csocket);
923 manager.host.data_socket = csocket;
924 LOGI("host data socket connected = %d\n", csocket);
932 LOGE("Failed to accept from host server socket\n");
938 // return 0 if normal case
939 // return plus value if non critical error occur
940 // return minus value if critical error occur
941 // return -11 if socket closed
943 static int controlSocketHandler(int efd)
950 recv_len = recv(manager.host.control_socket,
953 // error or close request from host
954 if (recv_len == -1 || recv_len == 0)
958 msg.payload = malloc(msg.len);
960 LOGE("Cannot alloc msg payload\n");
961 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
964 // Receive payload (if exists)
965 recv_len = recv(manager.host.control_socket,
967 msg.len, MSG_WAITALL);
969 res = host_message_handler(&msg);
976 // return 0 for normal case
979 int ret = 0; // return value
983 struct epoll_event ev, *events;
985 int numevent; // number of occured events
987 _get_fds(g_key_dev, INPUT_ID_KEY);
988 _get_fds(g_touch_dev, INPUT_ID_TOUCH);
990 // initialize epoll event pool
991 events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
994 LOGE("Out of memory when allocate epoll event pool\n");
998 if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
1000 LOGE("epoll creation error\n");
1005 // add server sockets to epoll event pool
1006 ev.events = EPOLLIN;
1007 ev.data.fd = manager.host_server_socket;
1008 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.host_server_socket, &ev) < 0)
1010 LOGE("Host server socket epoll_ctl error\n");
1014 ev.events = EPOLLIN;
1015 ev.data.fd = manager.target_server_socket;
1016 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target_server_socket, &ev) < 0)
1018 LOGE("Target server socket epoll_ctl error\n");
1023 // add device fds to epoll event pool
1024 ev.events = EPOLLIN;
1025 for(i = 0; g_key_dev[i].fd != ARRAY_END; i++)
1027 if(g_key_dev[i].fd >= 0)
1029 ev.data.fd = g_key_dev[i].fd;
1030 if(epoll_ctl(efd, EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0)
1032 LOGE("keyboard device file epoll_ctl error\n");
1037 ev.events = EPOLLIN;
1038 for(i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
1040 if(g_touch_dev[i].fd >= 0)
1042 ev.data.fd = g_touch_dev[i].fd;
1043 if(epoll_ctl(efd, EPOLL_CTL_ADD, g_touch_dev[i].fd, &ev) < 0)
1045 LOGE("touch device file epoll_ctl error\n");
1053 numevent = epoll_wait(efd, events, EPOLL_SIZE, -1);
1056 LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
1060 for(i = 0; i < numevent; i++)
1062 // check for request from event fd
1063 for(k = 0; k < MAX_TARGET_COUNT; k++)
1065 if(manager.target[k].socket != -1 &&
1066 events[i].data.fd == manager.target[k].event_fd)
1069 recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
1070 if(recvLen != sizeof(uint64_t))
1072 // maybe closed, but ignoring is more safe then removing fd from epoll list
1076 if(-11 == targetEventHandler(efd, k, u))
1078 LOGI("all target process is closed\n");
1086 if(k != MAX_TARGET_COUNT)
1089 // check for request from device fd
1090 for(k = 0; g_touch_dev[k].fd != ARRAY_END; k++)
1092 if(g_touch_dev[k].fd >= 0 &&
1093 events[i].data.fd == g_touch_dev[k].fd)
1095 if(deviceEventHandler(&g_touch_dev[k], INPUT_ID_TOUCH) < 0)
1097 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1105 if(g_touch_dev[k].fd != ARRAY_END)
1108 for(k = 0; g_key_dev[k].fd != ARRAY_END; k++)
1110 if(g_key_dev[k].fd >= 0 &&
1111 events[i].data.fd == g_key_dev[k].fd)
1113 if(deviceEventHandler(&g_key_dev[k], INPUT_ID_KEY) < 0)
1115 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1123 if(g_key_dev[k].fd != ARRAY_END)
1126 // connect request from target
1127 if(events[i].data.fd == manager.target_server_socket)
1129 if(targetServerHandler(efd) < 0) // critical error
1131 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1136 // connect request from host
1137 else if(events[i].data.fd == manager.host_server_socket)
1139 int result = hostServerHandler(efd);
1142 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1147 // control message from host
1148 else if(events[i].data.fd == manager.host.control_socket)
1150 int result = controlSocketHandler(efd);
1151 if(result == -11) // socket close
1153 // close target and host socket and quit
1154 LOGI("host close = %d\n", manager.host.control_socket);
1160 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1165 else if(events[i].data.fd == manager.host.data_socket)
1168 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1170 { // close data socket
1171 epoll_ctl(efd, EPOLL_CTL_DEL, manager.host.data_socket, NULL);
1172 close(manager.host.data_socket);
1173 manager.host.data_socket = -1;
1174 // TODO: finish transfer thread
1177 LOGW("host message from data socket %d\n", recvLen);
1179 // check for application launch timerfd
1180 else if(events[i].data.fd == manager.app_launch_timerfd)
1182 // send to host timeout error message for launching application
1183 terminate_error("Failed to launch application", 1);
1184 epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
1185 close(manager.app_launch_timerfd);
1186 manager.app_launch_timerfd = -1;
1194 LOGW("Unknown socket fd (%d)\n", events[i].data.fd);