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
44 #include <attr/xattr.h> // for fsetxattr
45 #include <sys/smack.h>
48 #include <linux/input.h>
54 #include "da_protocol.h"
55 #define DA_WORK_DIR "/home/developer/sdk_tools/da/"
56 #define DA_READELF_PATH "/home/developer/sdk_tools/da/readelf"
57 #define SCREENSHOT_DIR "/tmp/da"
60 #define MAX_CONNECT_SIZE 12
61 #define MAX_APP_LAUNCH_TIME 6
63 #define INPUT_ID_TOUCH 0
64 #define INPUT_ID_KEY 1
65 #define STR_TOUCH "TOUCH"
67 #define INPUT_ID_STR_KEY "ID_INPUT_KEY=1"
68 #define INPUT_ID_STR_TOUCH "ID_INPUT_TOUCHSCREEN=1"
69 #define INPUT_ID_STR_KEYBOARD "ID_INPUT_KEYBOARD=1"
70 #define INPUT_ID_STR_TABLET "ID_INPUT_TABLET=1"
73 #define MAX_FILENAME 128
75 #define ARRAY_END (-11)
77 typedef struct _input_dev
80 char fileName[MAX_FILENAME];
83 input_dev g_key_dev[MAX_DEVICE];
84 input_dev g_touch_dev[MAX_DEVICE];
86 // return bytes size of readed data
87 // return 0 if no data readed or error occurred
88 static int _file_read(FILE* fp, char *buffer, int size)
92 if(fp != NULL && size > 0)
94 ret = fread((void*)buffer, sizeof(char), size, fp);
102 ret = 0; // error case
108 // get input id of given input device
109 static int get_input_id(char* inputname)
111 static int query_cmd_type = 0; // 1 if /lib/udev/input_id, 2 if udevadm
113 char buffer[BUF_SIZE];
114 char command[MAX_FILENAME];
117 // determine input_id query command
118 if(unlikely(query_cmd_type == 0))
120 if(access("/lib/udev/input_id", F_OK) == 0) // there is /lib/udev/input_id
124 else // there is not /lib/udev/input_id
130 // make command string
131 if(query_cmd_type == 1)
133 sprintf(command, "/lib/udev/input_id /class/input/%s", inputname);
137 sprintf(command, "udevadm info --name=input/%s --query=property", inputname);
141 cmd_fp = popen(command, "r");
142 _file_read(cmd_fp, buffer, BUF_SIZE);
144 // determine input id
145 if(strstr(buffer, INPUT_ID_STR_KEY)) // key
149 else if(strstr(buffer, INPUT_ID_STR_TOUCH)) // touch
151 ret = INPUT_ID_TOUCH;
153 else if(strstr(buffer, INPUT_ID_STR_KEYBOARD)) // keyboard
157 else if(strstr(buffer, INPUT_ID_STR_TABLET)) // touch (emulator)
159 ret = INPUT_ID_TOUCH;
167 // get filename and fd of given input type devices
168 static void _get_fds(input_dev *dev, int input_id)
174 dp = opendir("/sys/class/input");
178 while((d = readdir(dp)) != NULL)
180 if(!strncmp(d->d_name, "event", 5)) // start with "event"
183 if(input_id == get_input_id(d->d_name))
185 sprintf(dev[count].fileName, "/dev/input/%s", d->d_name);
186 dev[count].fd = open(dev[count].fileName, O_RDWR | O_NONBLOCK);
194 dev[count].fd = ARRAY_END; // end of input_dev array
197 static void _device_write(input_dev *dev, struct input_event* in_ev)
200 for(i = 0; dev[i].fd != ARRAY_END; i++)
203 write(dev[i].fd, in_ev, sizeof(struct input_event));
207 long long get_total_alloc_size()
210 long long allocsize = 0;
212 for(i = 0; i < MAX_TARGET_COUNT; i++)
214 if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0)
215 allocsize += manager.target[i].allocmem;
220 static int getEmptyTargetSlot()
223 for(i = 0; i < MAX_TARGET_COUNT; i++)
225 if(manager.target[i].socket == -1)
232 static void setEmptyTargetSlot(int index)
234 if(index >= 0 && index < MAX_TARGET_COUNT)
236 manager.target[index].pid = -1;
237 manager.target[index].recv_thread = -1;
238 manager.target[index].allocmem = 0;
239 manager.target[index].starttime = 0;
240 manager.target[index].initial_log = 0;
241 if(manager.target[index].event_fd != -1)
242 close(manager.target[index].event_fd);
243 manager.target[index].event_fd = -1;
244 if(manager.target[index].socket != -1)
245 close(manager.target[index].socket);
246 manager.target[index].socket = -1;
250 // ======================================================================================
251 // send functions to host
252 // ======================================================================================
254 int pseudoSendDataToHost(struct msg_data_t* log)
257 uint32_t total_len = MSG_DATA_HDR_LEN;
259 /* char *buf = malloc(total_len+log->len);
261 memset(p,0,total_len);
264 pack_int(p,log->seq_num);
265 pack_int(p,log->sec);
266 pack_int(p,log->usec);
268 pack_int(p,log->len);
270 memcpy(p,log->payload,log->len);
272 printBuf(log,total_len+log->len);
274 write(event_fd, log, total_len+log->len);
281 int sendDataToHost(msg_t* log)
283 if (manager.host.data_socket != -1)
285 char logstr[DA_MSG_MAX];
289 loglen = sprintf(logstr, "%d|%d|%s\n", log->type, log->length + 1, log->data);
291 loglen = sprintf(logstr, "%d|%d|\n", log->type, log->length + 1);
293 // loglen = sprintf(logstr, "%d|%s\n", log->type, log->data);
295 pthread_mutex_lock(&(manager.host.data_socket_mutex));
296 send(manager.host.data_socket, logstr, loglen, MSG_NOSIGNAL);
297 pthread_mutex_unlock(&(manager.host.data_socket_mutex));
304 // msgstr can be NULL
305 static int sendACKStrToHost(enum HostMessageType resp, char* msgstr)
307 if (manager.host.control_socket != -1)
309 char logstr[DA_MSG_MAX];
313 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, strlen(msgstr), msgstr);
315 loglen = sprintf(logstr, "%d|0|", (int)resp);
317 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
326 static int sendACKCodeToHost(enum HostMessageType resp, int msgcode)
329 //disabled string protocol
331 if (manager.host.control_socket != -1)
334 char logstr[DA_MSG_MAX];
337 codelen = sprintf(codestr, "%d", msgcode);
338 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr);
340 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
347 // ========================================================================================
348 // start and terminate control functions
349 // ========================================================================================
351 static int startProfiling(long launchflag)
353 char execPath[PATH_MAX];
355 // remove previous screen capture files
356 remove_indir(SCREENSHOT_DIR);
357 mkdir(SCREENSHOT_DIR, 0777);
359 smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
361 manager.config_flag = launchflag;
363 #ifdef RUN_APP_LOADER
364 strcpy(execPath, manager.appPath);
366 get_executable(manager.appPath, execPath, PATH_MAX);
368 if(samplingStart() < 0)
371 if(exec_app(execPath, get_app_type(manager.appPath)) == 0)
377 LOGI("Timer Started\n");
382 // terminate single target
383 // just send stop message to target process
384 static void terminate_target(int index)
388 sendlog.type = MSG_STOP;
391 if(manager.target[index].socket != -1)
393 // result of sending to disconnected socket is not expected
394 sendlen = send(manager.target[index].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
397 LOGI("TERMINATE send exit msg (socket %d) by terminate_target()\n", manager.target[index].socket);
402 // just send stop message to all target process
403 static void terminate_all_target()
409 sendlog.type = MSG_STOP;
412 for (i = 0; i < MAX_TARGET_COUNT; i++)
414 if(manager.target[i].socket != -1)
416 sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
419 LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket);
425 // terminate all target and wait for threads
426 static void terminate_all()
429 terminate_all_target();
432 // wait for all other thread exit
433 for(i = 0; i < MAX_TARGET_COUNT; i++)
435 if(manager.target[i].recv_thread != -1)
437 pthread_join(manager.target[i].recv_thread, NULL);
442 // terminate all profiling by critical error
443 static void terminate_error(char* errstr, int sendtohost)
447 LOGE("TERMINATE ERROR: %s\n", errstr);
450 log.type = MSG_ERROR;
451 log.length = sprintf(log.data, "%s", errstr);
452 sendDataToHost(&log);
458 // ===========================================================================================
459 // message parsing and handling functions
460 // ===========================================================================================
462 static int parseDeviceMessage(msg_t* log)
464 char eventType[MAX_FILENAME];
465 struct input_event in_ev;
477 for(i = 0; i < log->length; i++)
479 if(log->data[i] == '\n')
482 if(log->data[i] == '`') // meet separate
489 if(index == 0) // parse eventType
491 eventType[i] = log->data[i];
492 eventType[i+1] = '\0';
494 else if(index == 1) // parse in_ev.type
496 in_ev.type = in_ev.type * 10 + (log->data[i] - '0');
498 else if(index == 2) // parse in_ev.code
500 in_ev.code = in_ev.code * 10 + (log->data[i] - '0');
502 else if(index == 3) // parse in_ev.value
504 in_ev.value = in_ev.value * 10 + (log->data[i] - '0');
509 return -1; // parse error
511 if(0 == strncmp(eventType, STR_TOUCH, strlen(STR_TOUCH)))
513 _device_write(g_touch_dev, &in_ev);
515 else if(0 == strncmp(eventType, STR_KEY, strlen(STR_KEY)))
517 _device_write(g_key_dev, &in_ev);
523 // return 0 if normal case
524 // return plus value if non critical error occur
525 // return minus value if critical error occur
526 static int _hostMessageHandler(int efd,struct msg_t* log)
531 /* char *barloc, *tmploc; */
532 /* char execPath[PATH_MAX]; */
534 /* if (log == NULL) */
537 /* switch (log->type) */
539 /* case MSG_REPLAY: */
540 /* sendACKStrToHost(MSG_OK, NULL); */
541 /* parseDeviceMessage(log); */
543 /* case MSG_VERSION: */
544 /* if(strcmp(PROTOCOL_VERSION, log->data) != 0) */
546 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_PROTOCOL_VERSION); */
550 /* sendACKStrToHost(MSG_OK, NULL); */
553 /* case MSG_START: */
554 /* LOGI("MSG_START handling : %s\n", log->data); */
555 /* if(log->length == 0) */
557 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */
558 /* return -1; // wrong message format */
561 /* // parsing for host start status */
562 /* tmploc = log->data; */
563 /* barloc = strchr(tmploc, '|'); */
564 /* if(barloc == NULL) */
566 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */
567 /* return -1; // wrong message format */
570 /* // parsing for target launch option flag */
571 /* tmploc = barloc + 1; */
572 /* barloc = strchr(tmploc, '|'); */
573 /* if(barloc != NULL) */
575 /* while(tmploc < barloc) */
577 /* flag = (flag * 10) + (*tmploc - '0'); */
583 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */
584 /* return -1; // wrong message format */
586 /* LOGI("launch flag : %lx\n", flag); */
588 /* // parsing for application package name */
589 /* tmploc = barloc + 1; */
590 /* strcpy(manager.appPath, tmploc); */
592 /* get_executable(manager.appPath, execPath, PATH_MAX); // get exact app executable file name */
593 /* LOGI("executable app path %s\n", manager.appPath); */
595 /* #ifdef RUN_APP_LOADER */
596 /* kill_app(manager.appPath); */
598 /* kill_app(execPath); */
602 /* char command[PATH_MAX]; */
603 /* struct epoll_event ev; */
605 /* //save app install path */
606 /* mkdir(DA_WORK_DIR, 0775); */
607 /* sprintf(command, */
608 /* "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH, */
609 /* execPath, DA_INSTALL_PATH); */
610 /* LOGI("appInstallCommand %s\n", command); */
611 /* system(command); */
613 /* sprintf(command, */
614 /* "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH, */
615 /* execPath, DA_BUILD_OPTION); */
616 /* LOGI("appInstallCommand %s\n", command); */
617 /* system(command); */
619 /* if(startProfiling(flag) < 0) */
621 /* sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING); */
625 /* manager.app_launch_timerfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC); */
626 /* if(manager.app_launch_timerfd > 0) */
628 /* struct itimerspec ctime; */
629 /* ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME; */
630 /* ctime.it_value.tv_nsec = 0; */
631 /* ctime.it_interval.tv_sec = 0; */
632 /* ctime.it_interval.tv_nsec = 0; */
633 /* if(0 > timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL)) */
635 /* LOGE("fail to set app launch timer\n"); */
636 /* close(manager.app_launch_timerfd); */
637 /* manager.app_launch_timerfd = -1; */
641 /* // add event fd to epoll list */
642 /* ev.events = EPOLLIN; */
643 /* ev.data.fd = manager.app_launch_timerfd; */
644 /* if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.app_launch_timerfd, &ev) < 0) */
646 /* // fail to add event fd */
647 /* LOGE("fail to add app launch timer fd to epoll list\n"); */
648 /* close(manager.app_launch_timerfd); */
649 /* manager.app_launch_timerfd = -1; */
654 /* sendACKStrToHost(MSG_OK, NULL); */
657 /* LOGI("MSG_STOP handling\n"); */
658 /* sendACKStrToHost(MSG_OK, NULL); */
659 /* terminate_all(); */
661 /* case MSG_OPTION: */
662 /* if(log->length > 0) */
666 /* manager.config_flag = atoi(log->data); */
667 /* sendACKStrToHost(MSG_OK, NULL); */
669 /* LOGI("MSG_OPTION : str(%s), flag(%x)\n", log->data, manager.config_flag); */
671 /* sendlog.type = MSG_OPTION; */
672 /* sendlog.length = sprintf(sendlog.data, "%u", manager.config_flag); */
674 /* for(i = 0; i < MAX_TARGET_COUNT; i++) */
676 /* if(manager.target[i].socket != -1) */
678 /* send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length, MSG_NOSIGNAL); */
684 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */
688 /* case MSG_ISALIVE: */
689 /* sendACKStrToHost(MSG_OK, NULL); */
692 /* LOGW("Unknown msg\n"); */
693 /* sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_TYPE); */
700 // ========================================================================================
701 // socket and event_fd handling functions
702 // ========================================================================================
704 // return 0 if normal case
705 // return plus value if non critical error occur
706 // return minus value if critical error occur
707 static int deviceEventHandler(input_dev* dev, int input_type)
710 struct input_event in_ev;
713 if(input_type == INPUT_ID_TOUCH)
716 read(dev->fd, &in_ev, sizeof(struct input_event));
717 log.type = MSG_RECORD;
718 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
719 STR_TOUCH, dev->fileName, in_ev.time.tv_sec,
720 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
721 sendDataToHost(&log);
723 else if(input_type == INPUT_ID_KEY)
726 read(dev->fd, &in_ev, sizeof(struct input_event));
727 log.type = MSG_RECORD;
728 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
729 STR_KEY, dev->fileName, in_ev.time.tv_sec,
730 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
731 sendDataToHost(&log);
735 LOGW("unknown input_type\n");
742 #define MAX_EVENTS_NUM 10
743 static int deviceEventHandlerNew(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");
774 if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
777 if (size = read(dev->fd, &in_ev, sizeof(in_ev) ) !=0 )
779 LOGI("readed %d touch events\n,", 1);
780 gen_message_event(&log,&in_ev,1,input_type);
781 pseudoSendDataToHost(&log);
786 LOGW("unknown input_type\n");
793 // return 0 if normal case
794 // return plus value if non critical error occur
795 // return minus value if critical error occur
796 // return -11 if all target process closed
797 static int targetEventHandler(int epollfd, int index, uint64_t msg)
803 if(index == 0) // assume index 0 is main application process
806 char tempBuff[DA_MSG_MAX];
807 char tempBuff2[DA_MSG_MAX];
808 char tempPath[PATH_MAX];
810 get_executable(manager.appPath, tempPath, PATH_MAX);
811 if(realpath(tempPath, tempBuff) == NULL)
813 LOGW("Failed to get realpath of app\n");
814 strcpy(tempBuff, tempPath);
817 sprintf(tempPath, "/proc/%d/maps", manager.target[index].pid);
818 sprintf(tempBuff2, "cat %s | grep %s | cut -d\"-\" -f1 > %s",
819 tempPath, tempBuff, DA_BASE_ADDRESS);
820 LOGI("base address command is %s\n", tempBuff2);
823 if(access(tempPath, F_OK) != 0)
825 if(is_same_app_process(manager.appPath, manager.target[index].pid) == 0)
829 if(get_app_base_address(&base_address) == 1)
835 get_app_install_path(tempPath, PATH_MAX);
838 get_device_info(tempBuff, DA_MSG_MAX);
841 log.type = MSG_DEVICE;
842 if (strlen(tempPath) > 0)
844 get_executable(manager.appPath, tempBuff2, DA_MSG_MAX);
845 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,%s/%s", tempBuff,
846 manager.target[index].pid, manager.target[index].starttime,
847 is_app_built_pie(), base_address, get_app_type(manager.appPath),
848 tempPath, get_app_name(tempBuff2));
852 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,", tempBuff,
853 manager.target[index].pid, manager.target[index].starttime,
854 is_app_built_pie(), base_address, get_app_type(manager.appPath));
857 LOGI("%s\n", log.data);
862 log.length = sprintf(log.data, "%d`,%Lu", manager.target[index].pid, manager.target[index].starttime);
865 sendDataToHost(&log);
866 manager.target[index].initial_log = 1;
869 if(msg & EVENT_STOP || msg & EVENT_ERROR)
871 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
872 manager.target[index].socket, manager.target[index].pid, manager.target_count - 1);
874 terminate_target(index);
875 epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
876 setEmptyTargetSlot(index);
877 if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) // all target client are closed
879 log.type = MSG_TERMINATE;
882 sendDataToHost(&log);
890 // return 0 if normal case
891 // return plus value if non critical error occur
892 // return minus value if critical error occur
893 static int targetServerHandler(int efd)
896 struct epoll_event ev;
898 int index = getEmptyTargetSlot();
899 if(index == MAX_TARGET_COUNT)
901 LOGW("Max target number(8) reached, no more target can connected\n");
905 manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL);
907 if(manager.target[index].socket >= 0) // accept succeed
910 // set smack attribute for certification
911 fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
912 fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
913 #endif /* LOCALTEST */
915 // send config message to target process
916 log.type = MSG_OPTION;
917 log.length = sprintf(log.data, "%u", manager.config_flag);
918 send(manager.target[index].socket, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_NOSIGNAL);
921 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
922 if(manager.target[index].event_fd == -1)
924 // fail to make event fd
925 LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket);
926 goto TARGET_CONNECT_FAIL;
929 // add event fd to epoll list
931 ev.data.fd = manager.target[index].event_fd;
932 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
934 // fail to add event fd
935 LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket);
936 goto TARGET_CONNECT_FAIL;
939 // make recv thread for target
940 if(makeRecvThread(index) != 0)
942 // fail to make recv thread
943 LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket);
944 epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
945 goto TARGET_CONNECT_FAIL;
948 if(manager.app_launch_timerfd >= 0)
950 epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
951 close(manager.app_launch_timerfd);
952 manager.app_launch_timerfd = -1;
955 LOGI("target connected = %d(running %d target)\n",
956 manager.target[index].socket, manager.target_count + 1);
958 manager.target_count++;
963 LOGE("Failed to accept at target server socket\n");
967 if(manager.target_count == 0) // if this connection is main connection
971 else // if this connection is not main connection then ignore process by error
973 setEmptyTargetSlot(index);
978 // return 0 if normal case
979 // return plus value if non critical error occur
980 // return minus value if critical error occur
981 static int hostServerHandler(int efd)
983 static int hostserverorder = 0;
985 struct epoll_event ev;
987 if(hostserverorder > 1) // control and data socket connected already
990 csocket = accept(manager.host_server_socket, NULL, NULL);
992 if(csocket >= 0) // accept succeed
995 ev.data.fd = csocket;
996 if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
998 // consider as accept fail
999 LOGE("Failed to add socket fd to epoll list\n");
1004 if(hostserverorder == 0)
1006 manager.host.control_socket = csocket;
1008 LOGI("host control socket connected = %d\n", csocket);
1012 manager.host.data_socket = csocket;
1013 LOGI("host data socket connected = %d\n", csocket);
1019 else // accept error
1021 LOGE("Failed to accept from host server socket\n");
1027 //TODO del it or move to debug section
1028 void printBuf (char * buf, int len)
1031 char local_buf[3*16 + 2*16 + 1];
1034 for ( i = 0; i < len/16 + 1; i++)
1036 memset(local_buf, ' ', 5*16);
1038 p2 = local_buf + 3*17;
1039 for ( j = 0; j < 16; j++)
1042 sprintf(p1, "%02X ",(unsigned char) *buf);
1044 if (isprint( *buf)){
1045 sprintf(p2, "%c ",(int)*buf);
1054 LOGI("%s\n",local_buf);
1058 // return 0 if normal case
1059 // return plus value if non critical error occur
1060 // return minus value if critical error occur
1061 // return -11 if socket closed
1063 static int controlSocketHandler(int efd)
1066 char recvBuf[DA_MSG_MAX];
1069 // host log format xxx|length|str
1070 recvLen = recv(manager.host.control_socket, recvBuf, DA_MSG_MAX, 0);
1074 recvBuf[recvLen] = '\0';
1075 printBuf(recvBuf,recvLen);
1076 LOGI("host sent control msg str(%s)\n", recvBuf);
1077 if(parseHostMessage(&log, recvBuf) < 0)
1079 // error to parse host message
1080 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
1084 // host msg command handling
1085 return hostMessageHandle(&log);
1087 else // close request from HOST
1093 // return 0 for normal case
1096 int ret = 0; // return value
1100 struct epoll_event ev, *events;
1101 int efd; // epoll fd
1102 int numevent; // number of occured events
1104 _get_fds(g_key_dev, INPUT_ID_KEY);
1105 _get_fds(g_touch_dev, INPUT_ID_TOUCH);
1107 // initialize epoll event pool
1108 events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
1111 LOGE("Out of memory when allocate epoll event pool\n");
1115 if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
1117 LOGE("epoll creation error\n");
1122 // add server sockets to epoll event pool
1123 ev.events = EPOLLIN;
1124 ev.data.fd = manager.host_server_socket;
1125 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.host_server_socket, &ev) < 0)
1127 LOGE("Host server socket epoll_ctl error\n");
1131 ev.events = EPOLLIN;
1132 ev.data.fd = manager.target_server_socket;
1133 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target_server_socket, &ev) < 0)
1135 LOGE("Target server socket epoll_ctl error\n");
1140 // add device fds to epoll event pool
1141 ev.events = EPOLLIN;
1142 for(i = 0; g_key_dev[i].fd != ARRAY_END; i++)
1144 if(g_key_dev[i].fd >= 0)
1146 ev.data.fd = g_key_dev[i].fd;
1147 if(epoll_ctl(efd, EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0)
1149 LOGE("keyboard device file epoll_ctl error\n");
1154 ev.events = EPOLLIN;
1155 for(i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
1157 if(g_touch_dev[i].fd >= 0)
1159 ev.data.fd = g_touch_dev[i].fd;
1160 if(epoll_ctl(efd, EPOLL_CTL_ADD, g_touch_dev[i].fd, &ev) < 0)
1162 LOGE("touch device file epoll_ctl error\n");
1170 numevent = epoll_wait(efd, events, EPOLL_SIZE, -1);
1173 LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
1177 for(i = 0; i < numevent; i++)
1179 // check for request from event fd
1180 for(k = 0; k < MAX_TARGET_COUNT; k++)
1182 if(manager.target[k].socket != -1 &&
1183 events[i].data.fd == manager.target[k].event_fd)
1186 recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
1187 if(recvLen != sizeof(uint64_t))
1189 // maybe closed, but ignoring is more safe then removing fd from epoll list
1193 if(-11 == targetEventHandler(efd, k, u))
1195 LOGI("all target process is closed\n");
1205 if(k != MAX_TARGET_COUNT)
1208 // check for request from device fd
1209 for(k = 0; g_touch_dev[k].fd != ARRAY_END; k++)
1211 if(g_touch_dev[k].fd >= 0 &&
1212 events[i].data.fd == g_touch_dev[k].fd)
1214 if(deviceEventHandlerNew(&g_touch_dev[k], INPUT_ID_TOUCH) < 0)
1216 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1224 if(g_touch_dev[k].fd != ARRAY_END)
1227 for(k = 0; g_key_dev[k].fd != ARRAY_END; k++)
1229 if(g_key_dev[k].fd >= 0 &&
1230 events[i].data.fd == g_key_dev[k].fd)
1232 if(deviceEventHandlerNew(&g_key_dev[k], INPUT_ID_KEY) < 0)
1234 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1242 if(g_key_dev[k].fd != ARRAY_END)
1245 // connect request from target
1246 if(events[i].data.fd == manager.target_server_socket)
1248 if(targetServerHandler(efd) < 0) // critical error
1250 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1255 // connect request from host
1256 else if(events[i].data.fd == manager.host_server_socket)
1258 int result = hostServerHandler(efd);
1261 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1266 // control message from host
1267 else if(events[i].data.fd == manager.host.control_socket)
1269 int result = controlSocketHandler(efd);
1270 if(result == -11) // socket close
1272 // close target and host socket and quit
1273 LOGI("host close = %d\n", manager.host.control_socket);
1280 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1285 else if(events[i].data.fd == manager.host.data_socket)
1288 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1290 { // close data socket
1291 epoll_ctl(efd, EPOLL_CTL_DEL, manager.host.data_socket, NULL);
1292 close(manager.host.data_socket);
1293 manager.host.data_socket = -1;
1296 LOGW("host message from data socket %d\n", recvLen);
1298 // check for application launch timerfd
1299 else if(events[i].data.fd == manager.app_launch_timerfd)
1301 // send to host timeout error message for launching application
1302 terminate_error("Failed to launch application", 1);
1303 epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
1304 close(manager.app_launch_timerfd);
1305 manager.app_launch_timerfd = -1;
1313 LOGW("Unknown socket fd (%d)\n", events[i].data.fd);