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
42 #include <attr/xattr.h> // for fsetxattr
43 #include <linux/input.h>
51 #define DA_WORK_DIR "/home/developer/sdk_tools/da/"
52 #define DA_READELF_PATH "/home/developer/sdk_tools/da/readelf"
53 #define SCREENSHOT_DIR "/tmp/da"
56 #define MAX_CONNECT_SIZE 12
57 #define MAX_APP_LAUNCH_TIME 6
59 #define INPUT_ID_TOUCH 0
60 #define INPUT_ID_KEY 1
61 #define STR_TOUCH "TOUCH"
63 #define INPUT_ID_STR_KEY "ID_INPUT_KEY=1"
64 #define INPUT_ID_STR_TOUCH "ID_INPUT_TOUCHSCREEN=1"
65 #define INPUT_ID_STR_KEYBOARD "ID_INPUT_KEYBOARD=1"
66 #define INPUT_ID_STR_TABLET "ID_INPUT_TABLET=1"
69 #define MAX_FILENAME 128
71 #define ARRAY_END (-11)
73 typedef struct _input_dev
76 char fileName[MAX_FILENAME];
79 input_dev g_key_dev[MAX_DEVICE];
80 input_dev g_touch_dev[MAX_DEVICE];
82 // return bytes size of readed data
83 // return 0 if no data readed or error occurred
84 static int _file_read(FILE* fp, char *buffer, int size)
88 if(fp != NULL && size > 0)
90 ret = fread((void*)buffer, sizeof(char), size, fp);
98 ret = 0; // error case
104 // get input id of given input device
105 static int get_input_id(char* inputname)
107 static int query_cmd_type = 0; // 1 if /lib/udev/input_id, 2 if udevadm
109 char buffer[BUF_SIZE];
110 char command[MAX_FILENAME];
113 // determine input_id query command
114 if(unlikely(query_cmd_type == 0))
116 if(access("/lib/udev/input_id", F_OK) == 0) // there is /lib/udev/input_id
120 else // there is not /lib/udev/input_id
126 // make command string
127 if(query_cmd_type == 1)
129 sprintf(command, "/lib/udev/input_id /class/input/%s", inputname);
133 sprintf(command, "udevadm info --name=input/%s --query=property", inputname);
137 cmd_fp = popen(command, "r");
138 _file_read(cmd_fp, buffer, BUF_SIZE);
140 // determine input id
141 if(strstr(buffer, INPUT_ID_STR_KEY)) // key
145 else if(strstr(buffer, INPUT_ID_STR_TOUCH)) // touch
147 ret = INPUT_ID_TOUCH;
149 else if(strstr(buffer, INPUT_ID_STR_KEYBOARD)) // keyboard
153 else if(strstr(buffer, INPUT_ID_STR_TABLET)) // touch (emulator)
155 ret = INPUT_ID_TOUCH;
163 // get filename and fd of given input type devices
164 static void _get_fds(input_dev *dev, int input_id)
170 dp = opendir("/sys/class/input");
174 while((d = readdir(dp)) != NULL)
176 if(!strncmp(d->d_name, "event", 5)) // start with "event"
179 if(input_id == get_input_id(d->d_name))
181 sprintf(dev[count].fileName, "/dev/input/%s", d->d_name);
182 dev[count].fd = open(dev[count].fileName, O_RDWR);
190 dev[count].fd = ARRAY_END; // end of input_dev array
193 static void _device_write(input_dev *dev, struct input_event* in_ev)
196 for(i = 0; dev[i].fd != ARRAY_END; i++)
199 write(dev[i].fd, in_ev, sizeof(struct input_event));
203 long long get_total_alloc_size()
206 long long allocsize = 0;
208 for(i = 0; i < MAX_TARGET_COUNT; i++)
210 if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0)
211 allocsize += manager.target[i].allocmem;
216 static int getEmptyTargetSlot()
219 for(i = 0; i < MAX_TARGET_COUNT; i++)
221 if(manager.target[i].socket == -1)
228 static void setEmptyTargetSlot(int index)
230 if(index >= 0 && index < MAX_TARGET_COUNT)
232 manager.target[index].pid = -1;
233 manager.target[index].recv_thread = -1;
234 manager.target[index].allocmem = 0;
235 manager.target[index].starttime = 0;
236 manager.target[index].initial_log = 0;
237 if(manager.target[index].event_fd != -1)
238 close(manager.target[index].event_fd);
239 manager.target[index].event_fd = -1;
240 if(manager.target[index].socket != -1)
241 close(manager.target[index].socket);
242 manager.target[index].socket = -1;
246 // ======================================================================================
247 // send functions to host
248 // ======================================================================================
250 int sendDataToHost(msg_t* log)
252 if (manager.host.data_socket != -1)
254 char logstr[DA_MSG_MAX];
258 loglen = sprintf(logstr, "%d|%d|%s\n", log->type, log->length + 1, log->data);
260 loglen = sprintf(logstr, "%d|%d|\n", log->type, log->length + 1);
262 // loglen = sprintf(logstr, "%d|%s\n", log->type, log->data);
264 pthread_mutex_lock(&(manager.host.data_socket_mutex));
265 send(manager.host.data_socket, logstr, loglen, MSG_NOSIGNAL);
266 pthread_mutex_unlock(&(manager.host.data_socket_mutex));
273 // msgstr can be NULL
274 static int sendACKStrToHost(enum HostMessageType resp, char* msgstr)
276 if (manager.host.control_socket != -1)
278 char logstr[DA_MSG_MAX];
282 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, strlen(msgstr), msgstr);
284 loglen = sprintf(logstr, "%d|0|", (int)resp);
286 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
293 static int sendACKCodeToHost(enum HostMessageType resp, int msgcode)
295 if (manager.host.control_socket != -1)
298 char logstr[DA_MSG_MAX];
301 codelen = sprintf(codestr, "%d", msgcode);
302 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr);
304 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
311 // ========================================================================================
312 // start and terminate control functions
313 // ========================================================================================
315 static int startProfiling(long launchflag)
317 char execPath[PATH_MAX];
319 // remove previous screen capture files
320 remove_indir(SCREENSHOT_DIR);
321 mkdir(SCREENSHOT_DIR, 0777);
323 manager.config_flag = launchflag;
325 #ifdef RUN_APP_LOADER
326 strcpy(execPath, manager.appPath);
328 get_executable(manager.appPath, execPath, PATH_MAX);
330 if(samplingStart() < 0)
333 if(exec_app(execPath, get_app_type(manager.appPath)) == 0)
339 LOGI("Timer Started\n");
344 // terminate single target
345 // just send stop message to target process
346 static void terminate_target(int index)
350 sendlog.type = MSG_STOP;
353 if(manager.target[index].socket != -1)
355 // result of sending to disconnected socket is not expected
356 sendlen = send(manager.target[index].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
359 LOGI("TERMINATE send exit msg (socket %d) by terminate_target()\n", manager.target[index].socket);
364 // just send stop message to all target process
365 static void terminate_all_target()
371 sendlog.type = MSG_STOP;
374 for (i = 0; i < MAX_TARGET_COUNT; i++)
376 if(manager.target[i].socket != -1)
378 sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
381 LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket);
387 // terminate all target and wait for threads
388 static void terminate_all()
391 terminate_all_target();
394 // wait for all other thread exit
395 for(i = 0; i < MAX_TARGET_COUNT; i++)
397 if(manager.target[i].recv_thread != -1)
399 pthread_join(manager.target[i].recv_thread, NULL);
404 // terminate all profiling by critical error
405 static void terminate_error(char* errstr, int sendtohost)
409 LOGE("TERMINATE ERROR: %s\n", errstr);
412 log.type = MSG_ERROR;
413 log.length = sprintf(log.data, "%s", errstr);
414 sendDataToHost(&log);
420 // ===========================================================================================
421 // message parsing and handling functions
422 // ===========================================================================================
424 static int parseDeviceMessage(msg_t* log)
426 char eventType[MAX_FILENAME];
427 struct input_event in_ev;
439 for(i = 0; i < log->length; i++)
441 if(log->data[i] == '\n')
444 if(log->data[i] == '`') // meet separate
451 if(index == 0) // parse eventType
453 eventType[i] = log->data[i];
454 eventType[i+1] = '\0';
456 else if(index == 1) // parse in_ev.type
458 in_ev.type = in_ev.type * 10 + (log->data[i] - '0');
460 else if(index == 2) // parse in_ev.code
462 in_ev.code = in_ev.code * 10 + (log->data[i] - '0');
464 else if(index == 3) // parse in_ev.value
466 in_ev.value = in_ev.value * 10 + (log->data[i] - '0');
471 return -1; // parse error
473 if(0 == strncmp(eventType, STR_TOUCH, strlen(STR_TOUCH)))
475 _device_write(g_touch_dev, &in_ev);
477 else if(0 == strncmp(eventType, STR_KEY, strlen(STR_KEY)))
479 _device_write(g_key_dev, &in_ev);
485 // return 0 for normal case
486 // return negative value for error case
487 static int parseHostMessage(msg_t* log, char* msg)
491 int ret = 0; // parsing success
493 if(log == NULL || msg == NULL)
496 // Host message looks like this
497 // MSG_TYPE|MSG_LENGTH|MSG_STRING
498 // MSG_TYPE is always 3 digits number
502 log->type = atoi(msg);
505 for(i = 0; msg[i] != '\0'; i++)
514 log->length = atoi(msg);
526 msglen = strlen(msg);
528 if(msglen == log->length)
530 strcpy(log->data, msg);
531 log->data[log->length] = '\0';
533 // else if(msglen > log->length)
535 // strncpy(log->data, msg, log->length);
536 // log->data[log->length] = '\0';
540 ret = -1; // parsing error
545 ret = -1; // parsing error
551 ret = -1; // parsing error
557 // return 0 if normal case
558 // return plus value if non critical error occur
559 // return minus value if critical error occur
560 static int hostMessageHandler(int efd, msg_t* log)
564 char *barloc, *tmploc;
565 char execPath[PATH_MAX];
573 sendACKStrToHost(MSG_OK, NULL);
574 parseDeviceMessage(log);
577 if(strcmp(PROTOCOL_VERSION, log->data) != 0)
579 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_PROTOCOL_VERSION);
583 sendACKStrToHost(MSG_OK, NULL);
587 LOGI("MSG_START handling : %s\n", log->data);
590 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA);
591 return -1; // wrong message format
594 // parsing for host start status
596 barloc = strchr(tmploc, '|');
599 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
600 return -1; // wrong message format
603 // parsing for target launch option flag
605 barloc = strchr(tmploc, '|');
608 while(tmploc < barloc)
610 flag = (flag * 10) + (*tmploc - '0');
616 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
617 return -1; // wrong message format
619 LOGI("launch flag : %lx\n", flag);
621 // parsing for application package name
623 strcpy(manager.appPath, tmploc);
625 get_executable(manager.appPath, execPath, PATH_MAX); // get exact app executable file name
626 LOGI("executable app path %s\n", manager.appPath);
628 #ifdef RUN_APP_LOADER
629 kill_app(manager.appPath);
635 char command[PATH_MAX];
636 struct epoll_event ev;
638 //save app install path
639 mkdir(DA_WORK_DIR, 0775);
641 "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH,
642 execPath, DA_INSTALL_PATH);
643 LOGI("appInstallCommand %s\n", command);
647 "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH,
648 execPath, DA_BUILD_OPTION);
649 LOGI("appInstallCommand %s\n", command);
652 if(startProfiling(flag) < 0)
654 sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING);
658 manager.app_launch_timerfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
659 if(manager.app_launch_timerfd > 0)
661 struct itimerspec ctime;
662 ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME;
663 ctime.it_value.tv_nsec = 0;
664 ctime.it_interval.tv_sec = 0;
665 ctime.it_interval.tv_nsec = 0;
666 if(0 > timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL))
668 LOGE("fail to set app launch timer\n");
669 close(manager.app_launch_timerfd);
670 manager.app_launch_timerfd = -1;
674 // add event fd to epoll list
676 ev.data.fd = manager.app_launch_timerfd;
677 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.app_launch_timerfd, &ev) < 0)
679 // fail to add event fd
680 LOGE("fail to add app launch timer fd to epoll list\n");
681 close(manager.app_launch_timerfd);
682 manager.app_launch_timerfd = -1;
687 sendACKStrToHost(MSG_OK, NULL);
690 LOGI("MSG_STOP handling\n");
691 sendACKStrToHost(MSG_OK, NULL);
699 manager.config_flag = atoi(log->data);
700 sendACKStrToHost(MSG_OK, NULL);
702 LOGI("MSG_OPTION : str(%s), flag(%x)\n", log->data, manager.config_flag);
704 sendlog.type = MSG_OPTION;
705 sendlog.length = sprintf(sendlog.data, "%u", manager.config_flag);
707 for(i = 0; i < MAX_TARGET_COUNT; i++)
709 if(manager.target[i].socket != -1)
711 send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length, MSG_NOSIGNAL);
717 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA);
722 sendACKStrToHost(MSG_OK, NULL);
725 LOGW("Unknown msg\n");
726 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_TYPE);
734 // ========================================================================================
735 // socket and event_fd handling functions
736 // ========================================================================================
738 // return 0 if normal case
739 // return plus value if non critical error occur
740 // return minus value if critical error occur
741 static int deviceEventHandler(input_dev* dev, int input_type)
744 struct input_event in_ev;
747 if(input_type == INPUT_ID_TOUCH)
750 read(dev->fd, &in_ev, sizeof(struct input_event));
751 log.type = MSG_RECORD;
752 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
753 STR_TOUCH, dev->fileName, in_ev.time.tv_sec,
754 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
755 sendDataToHost(&log);
757 else if(input_type == INPUT_ID_KEY)
760 read(dev->fd, &in_ev, sizeof(struct input_event));
761 log.type = MSG_RECORD;
762 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
763 STR_KEY, dev->fileName, in_ev.time.tv_sec,
764 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
765 sendDataToHost(&log);
769 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)
786 if(index == 0) // assume index 0 is main application process
789 char tempBuff[DA_MSG_MAX];
790 char tempBuff2[DA_MSG_MAX];
791 char tempPath[PATH_MAX];
793 get_executable(manager.appPath, tempPath, PATH_MAX);
794 if(realpath(tempPath, tempBuff) == NULL)
796 LOGW("Failed to get realpath of app\n");
797 strcpy(tempBuff, tempPath);
800 sprintf(tempPath, "/proc/%d/maps", manager.target[index].pid);
801 sprintf(tempBuff2, "cat %s | grep %s | cut -d\"-\" -f1 > %s",
802 tempPath, tempBuff, DA_BASE_ADDRESS);
803 LOGI("base address command is %s\n", tempBuff2);
806 if(access(tempPath, F_OK) != 0)
808 if(is_same_app_process(manager.appPath, manager.target[index].pid) == 0)
812 if(get_app_base_address(&base_address) == 1)
818 get_app_install_path(tempPath, PATH_MAX);
819 get_device_info(tempBuff, DA_MSG_MAX);
820 log.type = MSG_DEVICE;
821 if (strlen(tempPath) > 0)
823 get_executable(manager.appPath, tempBuff2, DA_MSG_MAX);
824 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,%s/%s", tempBuff,
825 manager.target[index].pid, manager.target[index].starttime,
826 is_app_built_pie(), base_address, get_app_type(manager.appPath),
827 tempPath, get_app_name(tempBuff2));
831 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,", tempBuff,
832 manager.target[index].pid, manager.target[index].starttime,
833 is_app_built_pie(), base_address, get_app_type(manager.appPath));
836 LOGI("%s\n", log.data);
841 log.length = sprintf(log.data, "%d`,%Lu", manager.target[index].pid, manager.target[index].starttime);
844 sendDataToHost(&log);
845 manager.target[index].initial_log = 1;
848 if(msg & EVENT_STOP || msg & EVENT_ERROR)
850 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
851 manager.target[index].socket, manager.target[index].pid, manager.target_count - 1);
853 terminate_target(index);
854 epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
855 setEmptyTargetSlot(index);
856 if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) // all target client are closed
858 log.type = MSG_TERMINATE;
861 sendDataToHost(&log);
869 // return 0 if normal case
870 // return plus value if non critical error occur
871 // return minus value if critical error occur
872 static int targetServerHandler(int efd)
875 struct epoll_event ev;
877 int index = getEmptyTargetSlot();
878 if(index == MAX_TARGET_COUNT)
880 LOGW("Max target number(8) reached, no more target can connected\n");
884 manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL);
886 if(manager.target[index].socket >= 0) // accept succeed
888 // set smack attribute for certification
889 fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
890 fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
892 // send config message to target process
893 log.type = MSG_OPTION;
894 log.length = sprintf(log.data, "%u", manager.config_flag);
895 send(manager.target[index].socket, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_NOSIGNAL);
898 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
899 if(manager.target[index].event_fd == -1)
901 // fail to make event fd
902 LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket);
903 goto TARGET_CONNECT_FAIL;
906 // add event fd to epoll list
908 ev.data.fd = manager.target[index].event_fd;
909 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
911 // fail to add event fd
912 LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket);
913 goto TARGET_CONNECT_FAIL;
916 // make recv thread for target
917 if(makeRecvThread(index) != 0)
919 // fail to make recv thread
920 LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket);
921 epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
922 goto TARGET_CONNECT_FAIL;
925 if(manager.app_launch_timerfd >= 0)
927 epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
928 close(manager.app_launch_timerfd);
929 manager.app_launch_timerfd = -1;
932 LOGI("target connected = %d(running %d target)\n",
933 manager.target[index].socket, manager.target_count + 1);
935 manager.target_count++;
940 LOGE("Failed to accept at target server socket\n");
944 if(manager.target_count == 0) // if this connection is main connection
948 else // if this connection is not main connection then ignore process by error
950 setEmptyTargetSlot(index);
955 // return 0 if normal case
956 // return plus value if non critical error occur
957 // return minus value if critical error occur
958 static int hostServerHandler(int efd)
960 static int hostserverorder = 0;
962 struct epoll_event ev;
964 if(hostserverorder > 1) // control and data socket connected already
967 csocket = accept(manager.host_server_socket, NULL, NULL);
969 if(csocket >= 0) // accept succeed
972 ev.data.fd = csocket;
973 if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
975 // consider as accept fail
976 LOGE("Failed to add socket fd to epoll list\n");
981 if(hostserverorder == 0)
983 manager.host.control_socket = csocket;
985 LOGI("host control socket connected = %d\n", csocket);
989 manager.host.data_socket = csocket;
990 LOGI("host data socket connected = %d\n", csocket);
998 LOGE("Failed to accept from host server socket\n");
1003 // return 0 if normal case
1004 // return plus value if non critical error occur
1005 // return minus value if critical error occur
1006 // return -11 if socket closed
1007 static int controlSocketHandler(int efd)
1010 char recvBuf[DA_MSG_MAX];
1013 // host log format xxx|length|str
1014 recvLen = recv(manager.host.control_socket, recvBuf, DA_MSG_MAX, 0);
1018 recvBuf[recvLen] = '\0';
1019 LOGI("host sent control msg str(%s)\n", recvBuf);
1021 if(parseHostMessage(&log, recvBuf) < 0)
1023 // error to parse host message
1024 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
1028 // host msg command handling
1029 return hostMessageHandler(efd, &log);
1031 else // close request from HOST
1037 // return 0 for normal case
1040 int ret = 0; // return value
1044 struct epoll_event ev, *events;
1045 int efd; // epoll fd
1046 int numevent; // number of occured events
1048 _get_fds(g_key_dev, INPUT_ID_KEY);
1049 _get_fds(g_touch_dev, INPUT_ID_TOUCH);
1051 // initialize epoll event pool
1052 events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
1055 LOGE("Out of memory when allocate epoll event pool\n");
1059 if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
1061 LOGE("epoll creation error\n");
1066 // add server sockets to epoll event pool
1067 ev.events = EPOLLIN;
1068 ev.data.fd = manager.host_server_socket;
1069 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.host_server_socket, &ev) < 0)
1071 LOGE("Host server socket epoll_ctl error\n");
1075 ev.events = EPOLLIN;
1076 ev.data.fd = manager.target_server_socket;
1077 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target_server_socket, &ev) < 0)
1079 LOGE("Target server socket epoll_ctl error\n");
1084 // add device fds to epoll event pool
1085 ev.events = EPOLLIN;
1086 for(i = 0; g_key_dev[i].fd != ARRAY_END; i++)
1088 if(g_key_dev[i].fd >= 0)
1090 ev.data.fd = g_key_dev[i].fd;
1091 if(epoll_ctl(efd, EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0)
1093 LOGE("keyboard device file epoll_ctl error\n");
1098 ev.events = EPOLLIN;
1099 for(i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
1101 if(g_touch_dev[i].fd >= 0)
1103 ev.data.fd = g_touch_dev[i].fd;
1104 if(epoll_ctl(efd, EPOLL_CTL_ADD, g_touch_dev[i].fd, &ev) < 0)
1106 LOGE("touch device file epoll_ctl error\n");
1114 numevent = epoll_wait(efd, events, EPOLL_SIZE, -1);
1117 LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
1121 for(i = 0; i < numevent; i++)
1123 // check for request from event fd
1124 for(k = 0; k < MAX_TARGET_COUNT; k++)
1126 if(manager.target[k].socket != -1 &&
1127 events[i].data.fd == manager.target[k].event_fd)
1130 recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
1131 if(recvLen != sizeof(uint64_t))
1133 // maybe closed, but ignoring is more safe then removing fd from epoll list
1137 if(-11 == targetEventHandler(efd, k, u))
1139 LOGI("all target process is closed\n");
1149 if(k != MAX_TARGET_COUNT)
1152 // check for request from device fd
1153 for(k = 0; g_touch_dev[k].fd != ARRAY_END; k++)
1155 if(g_touch_dev[k].fd >= 0 &&
1156 events[i].data.fd == g_touch_dev[k].fd)
1158 if(deviceEventHandler(&g_touch_dev[k], INPUT_ID_TOUCH) < 0)
1160 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1168 if(g_touch_dev[k].fd != ARRAY_END)
1171 for(k = 0; g_key_dev[k].fd != ARRAY_END; k++)
1173 if(g_key_dev[k].fd >= 0 &&
1174 events[i].data.fd == g_key_dev[k].fd)
1176 if(deviceEventHandler(&g_key_dev[k], INPUT_ID_KEY) < 0)
1178 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1186 if(g_key_dev[k].fd != ARRAY_END)
1189 // connect request from target
1190 if(events[i].data.fd == manager.target_server_socket)
1192 if(targetServerHandler(efd) < 0) // critical error
1194 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1199 // connect request from host
1200 else if(events[i].data.fd == manager.host_server_socket)
1202 int result = hostServerHandler(efd);
1205 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1210 // control message from host
1211 else if(events[i].data.fd == manager.host.control_socket)
1213 int result = controlSocketHandler(efd);
1214 if(result == -11) // socket close
1216 // close target and host socket and quit
1217 LOGI("host close = %d\n", manager.host.control_socket);
1224 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1229 else if(events[i].data.fd == manager.host.data_socket)
1232 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1234 { // close data socket
1235 epoll_ctl(efd, EPOLL_CTL_DEL, manager.host.data_socket, NULL);
1236 close(manager.host.data_socket);
1237 manager.host.data_socket = -1;
1240 LOGW("host message from data socket %d\n", recvLen);
1242 // check for application launch timerfd
1243 else if(events[i].data.fd == manager.app_launch_timerfd)
1245 // send to host timeout error message for launching application
1246 terminate_error("Failed to launch application", 1);
1247 epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
1248 close(manager.app_launch_timerfd);
1249 manager.app_launch_timerfd = -1;
1257 LOGW("Unknown socket fd (%d)\n", events[i].data.fd);