4 * Copyright (c) 2000 - 2013 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>
11 * Cherepanov Vitaliy <v.cherepanov@samsung.com>
12 * Nikita Kalyazin <n.kalyazin@samsung.com>
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
18 * http://www.apache.org/licenses/LICENSE-2.0
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
28 * - Samsung RnD Institute Russia
31 #define __STDC_FORMAT_MACROS
33 #include <stdlib.h> // for realpath
34 #include <string.h> // for strtok, strcpy, strncpy
35 #include <limits.h> // for realpath
38 #include <errno.h> // for errno
39 #include <sys/types.h> // for accept, mkdir, opendir, readdir
40 #include <sys/socket.h> // for accept
41 #include <sys/stat.h> // for mkdir
42 #include <sys/eventfd.h> // for eventfd
43 #include <sys/epoll.h> // for epoll apis
44 #include <sys/timerfd.h> // for timerfd
45 #include <unistd.h> // for access, sleep
51 #include <attr/xattr.h> // for fsetxattr
52 #include <sys/smack.h>
55 #include <linux/input.h>
61 #include "da_protocol.h"
66 #define DA_WORK_DIR "/home/developer/sdk_tools/da/"
67 #define DA_READELF_PATH "/home/developer/sdk_tools/da/readelf"
68 #define SCREENSHOT_DIR "/tmp/da"
71 #define MAX_APP_LAUNCH_TIME 60
72 #define MAX_CONNECT_TIMEOUT_TIME 5*60
75 #define MAX_FILENAME 128
77 #define ARRAY_END (-11)
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) {
89 ret = fread((void *)buffer, sizeof(char), size, fp);
95 ret = 0; // error case
101 // get input id of given input device
102 static int get_input_id(char *inputname)
104 static int query_cmd_type = 0; // 1 if /lib/udev/input_id, 2 if udevadm
106 char buffer[BUF_SIZE];
107 char command[MAX_FILENAME];
110 // determine input_id query command
111 if (unlikely(query_cmd_type == 0)) {
112 if (access("/lib/udev/input_id", F_OK) == 0) {
113 // there is /lib/udev/input_id
116 // there is not /lib/udev/input_id
120 // make command string
121 if (query_cmd_type == 1) {
122 sprintf(command, "/lib/udev/input_id /class/input/%s",
126 "udevadm info --name=input/%s --query=property",
131 cmd_fp = popen(command, "r");
132 if (_file_read(cmd_fp, buffer, BUF_SIZE) < 0) {
133 LOGE("Failed to read input_id\n");
138 // determine input id
139 if (strstr(buffer, INPUT_ID_STR_KEY)) {
142 } else if (strstr(buffer, INPUT_ID_STR_TOUCH)) {
144 ret = INPUT_ID_TOUCH;
145 } else if (strstr(buffer, INPUT_ID_STR_KEYBOARD)) {
148 } else if (strstr(buffer, INPUT_ID_STR_TABLET)) {
150 ret = INPUT_ID_TOUCH;
158 // get filename and fd of given input type devices
159 static void _get_fds(input_dev *dev, int input_id)
165 dp = opendir("/sys/class/input");
168 while ((d = readdir(dp)) != NULL) {
169 if (!strncmp(d->d_name, "event", 5)) {
170 // start with "event"
172 if (input_id == get_input_id(d->d_name)) {
173 sprintf(dev[count].fileName,
174 "/dev/input/%s", d->d_name);
176 open(dev[count].fileName,
177 O_RDWR | O_NONBLOCK);
185 dev[count].fd = ARRAY_END; // end of input_dev array
189 void _device_write(input_dev *dev, struct input_event *in_ev)
192 for (i = 0; dev[i].fd != ARRAY_END; i++) {
193 if (dev[i].fd >= 0) {
194 write(dev[i].fd, in_ev, sizeof(struct input_event));
195 LOGI("write(%d, %d, %d)\n",
196 dev[i].fd, (int)in_ev, sizeof(struct input_event));
201 uint64_t get_total_alloc_size()
204 uint64_t allocsize = 0;
206 for (i = 0; i < MAX_TARGET_COUNT; i++) {
207 if (manager.target[i].socket != -1 &&
208 manager.target[i].allocmem > 0)
209 allocsize += manager.target[i].allocmem;
214 static int getEmptyTargetSlot()
217 for (i = 0; i < MAX_TARGET_COUNT; i++) {
218 if (manager.target[i].socket == -1)
225 static void setEmptyTargetSlot(int index)
227 if (index >= 0 && index < MAX_TARGET_COUNT) {
228 manager.target[index].pid = -1;
229 manager.target[index].recv_thread = -1;
230 manager.target[index].allocmem = 0;
231 manager.target[index].initial_log = 0;
232 if (manager.target[index].event_fd != -1)
233 close(manager.target[index].event_fd);
234 manager.target[index].event_fd = -1;
235 if (manager.target[index].socket != -1)
236 close(manager.target[index].socket);
237 manager.target[index].socket = -1;
241 // =============================================================================
242 // start and terminate control functions
243 // =============================================================================
245 //start application launch timer function
246 static int start_app_launch_timer()
249 struct epoll_event ev;
251 manager.app_launch_timerfd =
252 timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
253 if (manager.app_launch_timerfd > 0) {
254 struct itimerspec ctime;
255 ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME;
256 ctime.it_value.tv_nsec = 0;
257 ctime.it_interval.tv_sec = 0;
258 ctime.it_interval.tv_nsec = 0;
259 if (timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL) < 0) {
260 LOGE("fail to set app launch timer\n");
261 close(manager.app_launch_timerfd);
262 manager.app_launch_timerfd = -1;
265 // add event fd to epoll list
267 ev.data.fd = manager.app_launch_timerfd;
268 if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
269 manager.app_launch_timerfd, &ev) < 0) {
270 // fail to add event fd
271 LOGE("fail to add app launch timer fd to epoll list\n");
272 close(manager.app_launch_timerfd);
273 manager.app_launch_timerfd = -1;
276 LOGI("application launch time started\n");
280 LOGE("cannot create launch timer\n");
287 //stop application launch timer
288 static int stop_app_launch_timer()
290 if (0 > epoll_ctl(manager.efd, EPOLL_CTL_DEL,
291 manager.app_launch_timerfd, NULL))
292 LOGW("fail to EPOLL DEL of app launch timerfd\n");
293 close(manager.app_launch_timerfd);
294 manager.app_launch_timerfd = -1;
298 int kill_app_by_info(const struct app_info_t *app_info)
302 if (app_info == NULL) {
303 LOGE("Cannot exec app. app_info is NULL");
307 switch (app_info->app_type) {
309 res = kill_app(app_info->exe_path);
311 case APP_TYPE_RUNNING:
312 // TODO: nothing, it's running
313 LOGI("already started\n");
315 case APP_TYPE_COMMON:
316 res = kill_app(app_info->exe_path);
319 LOGE("Unknown app type %d\n", app_info->app_type);
327 static int exec_app(const struct app_info_t *app_info)
331 if (app_info == NULL) {
332 LOGE("Cannot exec app. app_info is NULL");
336 switch (app_info->app_type) {
338 if (exec_app_tizen(app_info->app_id, app_info->exe_path)) {
339 LOGE("Cannot exec tizen app %s\n", app_info->app_id);
343 case APP_TYPE_RUNNING:
344 // TODO: nothing, it's running
345 LOGI("already started\n");
347 case APP_TYPE_COMMON:
348 if (exec_app_common(app_info->exe_path)) {
349 LOGE("Cannot exec common app %s\n", app_info->exe_path);
354 LOGE("Unknown app type %d\n", app_info->app_type);
359 if (res == 0 && app_info->app_type != APP_TYPE_RUNNING)
360 if (start_app_launch_timer() < 0)
363 LOGI("ret=%d\n", res);
367 int launch_timer_start()
369 static struct epoll_event ev;
372 manager.connect_timeout_timerfd =
373 timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
374 if (manager.connect_timeout_timerfd > 0) {
375 struct itimerspec ctime;
376 ctime.it_value.tv_sec = MAX_CONNECT_TIMEOUT_TIME;
377 ctime.it_value.tv_nsec = 0;
378 ctime.it_interval.tv_sec = 0;
379 ctime.it_interval.tv_nsec = 0;
380 if (timerfd_settime(manager.connect_timeout_timerfd, 0, &ctime, NULL) < 0) {
381 LOGE("fail to set connect timeout timer\n");
382 close(manager.connect_timeout_timerfd);
383 manager.connect_timeout_timerfd = -1;
385 // add event fd to epoll list
387 ev.data.fd = manager.connect_timeout_timerfd;
388 if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
389 manager.connect_timeout_timerfd, &ev) < 0)
391 // fail to add event fd
392 LOGE("fail to add app connection timeout timer fd to epoll list\n");
393 close(manager.connect_timeout_timerfd);
394 manager.connect_timeout_timerfd = -1;
396 LOGI("connection timeout timer started\n");
400 LOGE("cannot create connection timeout timer\n");
403 LOGI("ret=%d\n", res);
407 static void epoll_add_input_events();
408 static void epoll_del_input_events();
410 int prepare_profiling()
412 struct app_list_t *app = NULL;
413 const struct app_info_t *app_info = NULL;
415 app_info = app_info_get_first(&app);
416 if (app_info == NULL) {
417 LOGE("No app info found\n");
422 while (app_info != NULL) {
423 if (kill_app_by_info(app_info) != 0) {
424 LOGE("kill app failed\n");
427 app_info = app_info_get_next(&app);
429 //init rw for systeminfo
430 //init recv send network systeminfo
436 int start_profiling()
438 struct app_list_t *app = NULL;
439 const struct app_info_t *app_info = NULL;
442 app_info = app_info_get_first(&app);
443 if (app_info == NULL) {
444 LOGE("No app info found\n");
447 // remove previous screen capture files
448 remove_indir(SCREENSHOT_DIR);
449 if (mkdir(SCREENSHOT_DIR, 0777) == -1 && errno != EEXIST)
450 LOGW("Failed to create directory for screenshot : %s\n",
454 smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
457 if (samplingStart() < 0) {
458 LOGE("Cannot start sampling\n");
463 if (IS_OPT_SET(FL_RECORDING))
464 epoll_add_input_events();
466 if (exec_app(app_info)) {
467 LOGE("Cannot exec app\n");
475 if (IS_OPT_SET(FL_RECORDING))
476 epoll_del_input_events();
480 LOGI("return %d\n", res);
484 void stop_profiling(void)
486 if (IS_OPT_SET(FL_RECORDING))
487 epoll_del_input_events();
491 static void reconfigure_recording(struct conf_t conf)
493 uint64_t old_features = prof_session.conf.use_features0;
494 uint64_t new_features = conf.use_features0;
495 uint64_t to_enable = (new_features ^ old_features) & new_features;
496 uint64_t to_disable = (new_features ^ old_features) & old_features;
498 if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) {
499 epoll_del_input_events();
500 prof_session.conf.use_features0 &= ~FL_RECORDING;
503 if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) {
504 epoll_add_input_events();
505 prof_session.conf.use_features0 |= FL_RECORDING;
510 int reconfigure(struct conf_t conf)
512 reconfigure_recording(conf);
515 memcpy(&prof_session.conf, &conf, sizeof(conf));
516 if (samplingStart() < 0) {
517 LOGE("Cannot start sampling\n");
524 // just send stop message to all target process
525 static void terminate_all_target()
529 msg_target_t sendlog;
531 sendlog.type = MSG_STOP;
534 for (i = 0; i < MAX_TARGET_COUNT; i++) {
535 if (manager.target[i].socket != -1) {
536 sendlen = send(manager.target[i].socket, &sendlog,
537 sizeof(sendlog.type) +
538 sizeof(sendlog.length), MSG_NOSIGNAL);
540 // send to only first main target proces
541 LOGI("TERMINATE send exit msg (socket %d) "
542 "by terminate_all_target()\n",
543 manager.target[i].socket);
550 // terminate all target and wait for threads
554 terminate_all_target();
556 // wait for all other thread exit
557 for (i = 0; i < MAX_TARGET_COUNT; i++) {
558 if (manager.target[i].recv_thread != -1) {
559 LOGI("join recv thread [%d] is started\n", i);
560 pthread_join(manager.target[i].recv_thread, NULL);
561 LOGI("join recv thread %d. done\n", i);
566 // terminate all profiling by critical error
567 // TODO: don't send data to host
568 static void terminate_error(char *errstr, int send_to_host)
570 LOGE("termination all with err '%s'\n", errstr);
571 struct msg_data_t *msg = NULL;
572 if (send_to_host != 0) {
573 msg = gen_message_error(errstr);
578 LOGI("cannot generate error message\n");
584 #define MAX_EVENTS_NUM 10
585 static int deviceEventHandler(input_dev *dev, int input_type)
590 struct input_event in_ev[MAX_EVENTS_NUM];
591 struct msg_data_t *log;
593 if (input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY) {
595 size = read(dev->fd, &in_ev[count], sizeof(*in_ev));
598 } while (count < MAX_EVENTS_NUM && size > 0);
601 LOGI("read %d %s events\n",
603 input_type == INPUT_ID_KEY ? STR_KEY : STR_TOUCH);
604 log = gen_message_event(in_ev, count, input_type);
605 printBuf((char *)log, MSG_DATA_HDR_LEN + log->len);
610 LOGW("unknown input_type\n");
611 ret = 1; // it is not error
616 static int target_event_pid_handler(int index, uint64_t msg)
618 struct app_list_t *app = NULL;
619 struct app_info_t *app_info = NULL;
620 if (index == 0) { // main application
621 app_info = app_info_get_first(&app);
622 if (app_info == NULL) {
623 LOGE("No app info found\n");
627 while (app_info != NULL) {
628 if (is_same_app_process(app_info->exe_path,
629 manager.target[index].pid))
631 app_info = app_info_get_next(&app);
634 if (app_info == NULL) {
635 LOGE("pid %d not found in app list\n",
636 manager.target[index].pid);
640 if (start_replay() != 0) {
641 LOGE("Cannot start replay thread\n");
645 manager.target[index].initial_log = 1;
649 static int target_event_stop_handler(int epollfd, int index, uint64_t msg)
651 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
652 manager.target[index].socket, manager.target[index].pid,
653 manager.target_count - 1);
655 if (index == 0) // main application
658 if (0 > epoll_ctl(epollfd, EPOLL_CTL_DEL,
659 manager.target[index].event_fd, NULL))
660 LOGW("fail to EPOLL DEL of event fd(%d)\n", index);
662 setEmptyTargetSlot(index);
663 // all target client are closed
664 if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) {
665 LOGI("all targets are stopped\n");
666 if (stop_all() != ERR_NO)
667 LOGE("Stop failed\n");
674 // return 0 if normal case
675 // return plus value if non critical error occur
676 // return minus value if critical error occur
677 // return -11 if all target process closed
678 static int target_event_handler(int epollfd, int index, uint64_t msg)
682 err = target_event_pid_handler(index, msg);
686 if (msg & EVENT_STOP || msg & EVENT_ERROR)
687 err = target_event_stop_handler(epollfd, index, msg);
693 * return 0 if normal case
694 * return plus value if non critical error occur
695 * return minus value if critical error occur
697 static int targetServerHandler(int efd)
700 struct epoll_event ev;
702 int index = getEmptyTargetSlot();
703 if (index == MAX_TARGET_COUNT) {
704 LOGW("Max target number(8) reached, no more target can connected\n");
708 manager.target[index].socket =
709 accept(manager.target_server_socket, NULL, NULL);
711 if (manager.target[index].socket >= 0) {
713 fd_setup_smack_attributes(manager.target[index].socket);
715 /* send config message to target process */
716 log.type = MSG_OPTION;
717 log.length = sprintf(log.data, "%lu",
718 (unsigned long int)prof_session.conf.use_features0);
719 if (0 > send(manager.target[index].socket, &log,
720 sizeof(log.type) + sizeof(log.length) + log.length,
722 LOGE("fail to send data to target index(%d)\n", index);
725 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
726 if (manager.target[index].event_fd == -1) {
727 // fail to make event fd
728 LOGE("fail to make event fd for socket (%d)\n",
729 manager.target[index].socket);
730 goto TARGET_CONNECT_FAIL;
733 // add event fd to epoll list
735 ev.data.fd = manager.target[index].event_fd;
736 if (epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0) {
737 // fail to add event fd
738 LOGE("fail to add event fd to epoll list for socket (%d)\n",
739 manager.target[index].socket);
740 goto TARGET_CONNECT_FAIL;
743 // make recv thread for target
744 if (makeRecvThread(index) != 0) {
745 // fail to make recv thread
746 LOGE("fail to make recv thread for socket (%d)\n",
747 manager.target[index].socket);
748 if (0 > epoll_ctl(efd, EPOLL_CTL_DEL,
749 manager.target[index].event_fd, NULL))
750 LOGW("fail to EPOLL DEL of event fd(%d)\n", index);
751 goto TARGET_CONNECT_FAIL;
754 if (manager.app_launch_timerfd >= 0) {
755 LOGI("release launch timer\n");
756 if (stop_app_launch_timer() < 0)
757 LOGE("cannot stop app launch timer\n");
760 LOGI("target connected = %d(running %d target)\n",
761 manager.target[index].socket, manager.target_count + 1);
763 manager.target_count++;
767 LOGE("Failed to accept at target server socket\n");
771 if (manager.target_count == 0) {
772 // if this connection is main connection
775 // if this connection is not main connection then ignore process by error
776 setEmptyTargetSlot(index);
781 // return 0 if normal case
782 // return plus value if non critical error occur
783 // return minus value if critical error occur
784 static int hostServerHandler(int efd)
786 static int hostserverorder = 0;
788 struct epoll_event ev;
790 if (hostserverorder > 1) // control and data socket connected already
793 csocket = accept(manager.host_server_socket, NULL, NULL);
798 ev.data.fd = csocket;
799 if (epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0) {
800 // consider as accept fail
801 LOGE("Failed to add socket fd to epoll list\n");
806 if (hostserverorder == 0) {
807 manager.host.control_socket = csocket;
809 LOGI("host control socket connected = %d\n", csocket);
811 manager.host.data_socket = csocket;
812 LOGI("host data socket connected = %d\n", csocket);
819 LOGE("Failed to accept from host server socket\n");
824 // return plus value if non critical error occur
825 // return minus value if critical error occur
826 // return -11 if socket closed
828 static int controlSocketHandler(int efd)
831 struct msg_t msg_head;
835 if (manager.connect_timeout_timerfd >= 0) {
836 LOGI("release connect timeout timer\n");
837 if (0 > epoll_ctl(efd, EPOLL_CTL_DEL,
838 manager.connect_timeout_timerfd, NULL))
839 LOGW("fail to EPOLL DEL of timeout timer fd\n");
840 close(manager.connect_timeout_timerfd);
841 manager.connect_timeout_timerfd = -1;
844 recv_len = recv(manager.host.control_socket,
845 &msg_head, MSG_CMD_HDR_LEN, 0);
846 // error or close request from host
847 if (recv_len == -1 || recv_len == 0)
850 msg = malloc(MSG_CMD_HDR_LEN + msg_head.len);
852 LOGE("Cannot alloc msg\n");
853 sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
856 msg->id = msg_head.id;
857 msg->len = msg_head.len;
859 // Receive payload (if exists)
860 recv_len = recv(manager.host.control_socket,
861 msg->payload, msg->len, MSG_WAITALL);
865 printBuf((char *)msg, MSG_CMD_HDR_LEN + msg->len);
866 res = host_message_handler(msg);
873 static void epoll_add_input_events()
875 struct epoll_event ev;
878 // add device fds to epoll event pool
880 for (i = 0; g_key_dev[i].fd != ARRAY_END; i++) {
881 if (g_key_dev[i].fd >= 0) {
882 ev.data.fd = g_key_dev[i].fd;
883 if (epoll_ctl(manager.efd,
884 EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0
886 LOGE("keyboard device file epoll_ctl error: %s\n", strerror(errno));
891 for (i = 0; g_touch_dev[i].fd != ARRAY_END; i++) {
892 if (g_touch_dev[i].fd >= 0) {
893 ev.data.fd = g_touch_dev[i].fd;
894 if (epoll_ctl(manager.efd,
896 g_touch_dev[i].fd, &ev) < 0
898 LOGE("touch device file epoll_ctl error: %s\n", strerror(errno));
903 static void epoll_del_input_events()
907 // remove device fds from epoll event pool
908 for (i = 0; g_key_dev[i].fd != ARRAY_END; i++)
909 if (g_key_dev[i].fd >= 0)
910 if (epoll_ctl(manager.efd,
911 EPOLL_CTL_DEL, g_key_dev[i].fd, NULL) < 0)
912 LOGE("keyboard device file epoll_ctl error: %s\n", strerror(errno));
914 for (i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
915 if (g_touch_dev[i].fd >= 0)
916 if (epoll_ctl(manager.efd,
918 g_touch_dev[i].fd, NULL) < 0)
919 LOGE("touch device file epoll_ctl error: %s\n", strerror(errno));
922 static bool initialize_epoll_events(void)
924 struct epoll_event ev;
926 if ((manager.efd = epoll_create1(0)) < 0) {
927 LOGE("epoll creation error\n");
930 // add server sockets to epoll event pool
932 ev.data.fd = manager.host_server_socket;
933 if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
934 manager.host_server_socket, &ev) < 0) {
935 LOGE("Host server socket epoll_ctl error\n");
939 ev.data.fd = manager.target_server_socket;
940 if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
941 manager.target_server_socket, &ev) < 0) {
942 LOGE("Target server socket epoll_ctl error\n");
948 // return 0 for normal case
951 int return_value = 0;
952 struct epoll_event *events = malloc(EPOLL_SIZE * sizeof(*events));
954 _get_fds(g_key_dev, INPUT_ID_KEY);
955 _get_fds(g_touch_dev, INPUT_ID_TOUCH);
958 LOGE("Out of memory when allocate epoll event pool\n");
962 if (!initialize_epoll_events()) {
967 if (launch_timer_start() < 0) {
968 LOGE("Launch timer start failed\n");
973 init_prof_session(&prof_session);
979 // number of occured events
980 int numevent = epoll_wait(manager.efd, events, EPOLL_SIZE, -1);
982 LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
986 for (i = 0; i < numevent; i++) {
987 // check for request from event fd
988 for (k = 0; k < MAX_TARGET_COUNT; k++) {
989 if (manager.target[k].socket != -1 &&
990 events[i].data.fd == manager.target[k].event_fd) {
992 recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
993 if (recvLen != sizeof(uint64_t)) {
994 // maybe closed, but ignoring is more safe then
995 // removing fd from epoll list
997 if (-11 == target_event_handler(manager.efd, k, u)) {
998 LOGI("all target process is closed\n");
1006 if (k != MAX_TARGET_COUNT)
1009 // check for request from device fd
1010 for (k = 0; g_touch_dev[k].fd != ARRAY_END; k++) {
1011 if (g_touch_dev[k].fd >= 0 &&
1012 events[i].data.fd == g_touch_dev[k].fd) {
1013 if (deviceEventHandler(&g_touch_dev[k],
1014 INPUT_ID_TOUCH) < 0) {
1015 LOGE("Internal DA framework error, "
1016 "Please re-run the profiling (touch dev)\n");
1023 if (g_touch_dev[k].fd != ARRAY_END)
1026 for (k = 0; g_key_dev[k].fd != ARRAY_END; k++) {
1027 if (g_key_dev[k].fd >= 0 &&
1028 events[i].data.fd == g_key_dev[k].fd) {
1029 if (deviceEventHandler(&g_key_dev[k], INPUT_ID_KEY) < 0) {
1030 LOGE("Internal DA framework error, "
1031 "Please re-run the profiling (key dev)\n");
1038 if (g_key_dev[k].fd != ARRAY_END)
1041 // connect request from target
1042 if (events[i].data.fd == manager.target_server_socket) {
1043 if (targetServerHandler(manager.efd) < 0) {
1045 terminate_error("Internal DA framework error, "
1046 "Please re-run the profiling "
1047 "(targetServerHandler)\n", 1);
1050 } else if (events[i].data.fd == manager.host_server_socket) {
1051 // connect request from host
1052 int result = hostServerHandler(manager.efd);
1054 LOGE("Internal DA framework error (hostServerHandler)\n");
1057 } else if (events[i].data.fd == manager.host.control_socket) {
1058 // control message from host
1059 int result = controlSocketHandler(manager.efd);
1060 if (result == -11) {
1062 //if the host disconnected.
1063 //In all other cases daemon must report an error and continue the loop
1064 //close connect_timeoutt and host socket and quit
1065 LOGI("Connection closed. Termination. (%d)\n",
1066 manager.host.control_socket);
1069 } else if (result < 0) {
1070 LOGE("Control socket handler.\n");
1072 } else if (events[i].data.fd == manager.host.data_socket) {
1074 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1076 // close data socket
1077 if (0 > epoll_ctl(manager.efd,
1079 manager.host.data_socket,
1081 LOGW("fail to EPOLL DEL of host data socket\n");
1082 close(manager.host.data_socket);
1083 manager.host.data_socket = -1;
1084 // TODO: finish transfer thread
1087 LOGI("host message from data socket %d\n",
1089 } else if (events[i].data.fd == manager.app_launch_timerfd) {
1090 // check for application launch timerfd
1091 // send to host timeout error message for launching application
1092 LOGE("Failed to launch application\n");
1093 if (stop_app_launch_timer() < 0)
1094 LOGE("cannot stop app launch timer\n");
1096 } else if (events[i].data.fd == manager.connect_timeout_timerfd) {
1097 // check for connection timeout timerfd
1098 // send to host timeout error message for launching application
1099 terminate_error("no incoming connections", 1);
1100 if (0 > epoll_ctl(manager.efd, EPOLL_CTL_DEL,
1101 manager.connect_timeout_timerfd,
1103 LOGW("fail to EPOLL DEL of timeout timer fd\n");
1104 close(manager.connect_timeout_timerfd);
1105 manager.connect_timeout_timerfd = -1;
1106 LOGE("No connection in %d sec. shutdown.\n",
1107 MAX_CONNECT_TIMEOUT_TIME);
1112 LOGW("Unknown socket fd (%d)\n",
1119 LOGI("close efd\n");
1123 return return_value;