[FIX] duplicated events on replay
[platform/core/system/swap-manager.git] / daemon / daemon.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
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>
13  *
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
17  *
18  * http://www.apache.org/licenses/LICENSE-2.0
19  *
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.
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  * - Samsung RnD Institute Russia
29  *
30  */
31 #define __STDC_FORMAT_MACROS
32 #include <stdio.h>
33 #include <stdlib.h>             // for realpath
34 #include <string.h>             // for strtok, strcpy, strncpy
35 #include <limits.h>             // for realpath
36 #include <inttypes.h>
37
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
46 #include <stdbool.h>
47
48 #include <ctype.h>
49
50 #include <attr/xattr.h>         // for fsetxattr
51 #include <sys/smack.h>
52
53 #include <linux/input.h>
54 #include <dirent.h>
55 #include <fcntl.h>
56
57 #include <assert.h>
58
59 #include "daemon.h"
60 #include "sys_stat.h"
61 #include "utils.h"
62 #include "da_protocol.h"
63 #include "da_inst.h"
64 #include "da_data.h"
65 #include "debug.h"
66
67 #define DA_WORK_DIR                     "/home/developer/sdk_tools/da/"
68 #define DA_READELF_PATH                 "/home/developer/sdk_tools/da/readelf"
69 #define SCREENSHOT_DIR                  "/tmp/da"
70
71 #define EPOLL_SIZE                      10
72 #define MAX_APP_LAUNCH_TIME             60
73 #define MAX_CONNECT_TIMEOUT_TIME        5*60
74
75 #define MAX_DEVICE                      10
76 #define MAX_FILENAME                    128
77 #define BUF_SIZE                        1024
78 #define ARRAY_END                       (-11)
79
80 input_dev g_key_dev[MAX_DEVICE];
81 input_dev g_touch_dev[MAX_DEVICE];
82
83 const char *input_key_devices[] = {
84         "gpio-keys",            //device
85         "melfas-touchkey",      //device
86         "Maru Virtio Hwkey",    //virtual
87         NULL                    //array tail
88 };
89
90 const char *input_touch_devices[] = {
91         "sec_touchscreen",              //device
92         "Maru Virtio Touchscreen",      //virtual
93         NULL                            //array tail
94 };
95
96
97 static int check_input(char *inputname, int input_id)
98 {
99         int ret = -1;
100         FILE *cmd_fp = NULL;
101         char buffer[BUF_SIZE];
102         char command[MAX_FILENAME];
103         char **name_arr;
104         size_t bytes_count;
105
106         sprintf(command, "/sys/class/input/%s/device/name", inputname);
107         // run command
108         cmd_fp = fopen(command, "r");
109         if (cmd_fp == NULL)
110                 goto exit;
111
112         buffer[0] = '\0';
113         bytes_count = fread(buffer, 1, BUF_SIZE, cmd_fp);
114         if (bytes_count <= 1) {
115                 LOGE("Failed to read input_id\n");
116                 goto exit;
117         } else {
118                 buffer[bytes_count - 1] = '\0';
119         }
120
121         if (input_id == INPUT_ID_KEY)
122                 name_arr = input_key_devices;
123         else if (input_id == INPUT_ID_TOUCH)
124                 name_arr = input_touch_devices;
125         else
126                 goto exit;
127
128         while (*name_arr != NULL) {
129                 if (strcmp(buffer, *name_arr) == 0) {
130                         ret = 0;
131                         goto exit;
132                 }
133                 name_arr++;
134         }
135
136 exit:
137         if (cmd_fp != NULL)
138                 pclose(cmd_fp);
139         return ret;
140 }
141
142 // get filename and fd of given input type devices
143 static void _get_fds(input_dev *dev, int input_id)
144 {
145         DIR *dp;
146         struct dirent *d;
147         int count = 0;
148
149         dp = opendir("/sys/class/input");
150
151         if (dp == NULL)
152                 goto exit;
153
154         while ((d = readdir(dp)) != NULL) {
155                 if (!strncmp(d->d_name, "event", 5)) {
156                         // start with "event"
157                         // event file
158                         if (!check_input(d->d_name, input_id)) {
159                                 sprintf(dev[count].fileName,
160                                         "/dev/input/%s", d->d_name);
161                                 dev[count].fd = open(dev[count].fileName,
162                                                      O_RDWR | O_NONBLOCK);
163                                 count++;
164                         }
165                 }
166         }
167
168         closedir(dp);
169
170 exit:
171         dev[count].fd = ARRAY_END;      // end of input_dev array
172 }
173
174 //static
175 void _device_write(input_dev *dev, struct input_event *in_ev)
176 {
177         int i;
178         for (i = 0; dev[i].fd != ARRAY_END; i++) {
179                 if (dev[i].fd >= 0) {
180                         write(dev[i].fd, in_ev, sizeof(struct input_event));
181                         LOGI("write(%d, %d, %d)\n",
182                              dev[i].fd, (int)in_ev, sizeof(struct input_event));
183                 }
184         }
185 }
186
187 uint64_t get_total_alloc_size()
188 {
189         int i;
190         uint64_t allocsize = 0;
191
192         for (i = 0; i < MAX_TARGET_COUNT; i++) {
193                 if (manager.target[i].socket != -1 &&
194                     manager.target[i].allocmem > 0)
195                         allocsize += manager.target[i].allocmem;
196         }
197         return allocsize;
198 }
199
200 static int getEmptyTargetSlot()
201 {
202         int i;
203         for (i = 0; i < MAX_TARGET_COUNT; i++) {
204                 if (manager.target[i].socket == -1)
205                         break;
206         }
207
208         return i;
209 }
210
211 static void setEmptyTargetSlot(int index)
212 {
213         if (index >= 0 && index < MAX_TARGET_COUNT) {
214                 manager.target[index].pid = -1;
215                 manager.target[index].recv_thread = -1;
216                 manager.target[index].allocmem = 0;
217                 manager.target[index].initial_log = 0;
218                 if (manager.target[index].event_fd != -1)
219                         close(manager.target[index].event_fd);
220                 manager.target[index].event_fd = -1;
221                 if (manager.target[index].socket != -1)
222                         close(manager.target[index].socket);
223                 manager.target[index].socket = -1;
224         }
225 }
226
227 // =============================================================================
228 // start and terminate control functions
229 // =============================================================================
230
231 //start application launch timer function
232 static int start_app_launch_timer(int apps_count)
233 {
234         int res = 0;
235         struct epoll_event ev;
236
237         assert(apps_count >= 0 && "negative apps count");
238
239         if (apps_count == 0)
240                 return res;
241
242         manager.app_launch_timerfd =
243             timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
244         if (manager.app_launch_timerfd > 0) {
245                 struct itimerspec ctime;
246                 ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME * apps_count;
247                 ctime.it_value.tv_nsec = 0;
248                 ctime.it_interval.tv_sec = 0;
249                 ctime.it_interval.tv_nsec = 0;
250                 if (timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL) < 0) {
251                         LOGE("fail to set app launch timer\n");
252                         close(manager.app_launch_timerfd);
253                         manager.app_launch_timerfd = -1;
254                         res = -1;
255                 } else {
256                         // add event fd to epoll list
257                         ev.events = EPOLLIN;
258                         ev.data.fd = manager.app_launch_timerfd;
259                         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
260                                       manager.app_launch_timerfd, &ev) < 0) {
261                                 // fail to add event fd
262                                 LOGE("fail to add app launch timer fd to epoll list\n");
263                                 close(manager.app_launch_timerfd);
264                                 manager.app_launch_timerfd = -1;
265                                 res = -2;
266                         } else {
267                                 LOGI("application launch time started\n");
268                         }
269                 }
270         } else {
271                 LOGE("cannot create launch timer\n");
272                 res = -3;
273         }
274
275         return res;
276 }
277
278 //stop application launch timer
279 static int stop_app_launch_timer()
280 {
281         if (0 > epoll_ctl(manager.efd, EPOLL_CTL_DEL,
282                           manager.app_launch_timerfd, NULL))
283                 LOGW("fail to EPOLL DEL of app launch timerfd\n");
284         close(manager.app_launch_timerfd);
285         manager.app_launch_timerfd = -1;
286         return 0;
287 }
288
289 static inline void inc_apps_to_run()
290 {
291         manager.apps_to_run++;
292 }
293
294 static inline void dec_apps_to_run()
295 {
296         if (manager.apps_to_run > 0)
297                 manager.apps_to_run--;
298 }
299
300 static inline int get_apps_to_run()
301 {
302         return manager.apps_to_run;
303 }
304
305 int kill_app_by_info(const struct app_info_t *app_info)
306 {
307         int res = 0;
308
309         if (app_info == NULL) {
310                 LOGE("Cannot exec app. app_info is NULL");
311                 return -1;
312         }
313
314         switch (app_info->app_type) {
315         case APP_TYPE_TIZEN:
316                 res = kill_app(app_info->exe_path);
317                 break;
318         case APP_TYPE_RUNNING:
319                 // TODO: nothing, it's running
320                 LOGI("already started\n");
321                 break;
322         case APP_TYPE_COMMON:
323                 res = kill_app(app_info->exe_path);
324                 break;
325         default:
326                 LOGE("Unknown app type %d\n", app_info->app_type);
327                 res = -1;
328                 break;
329         }
330
331         return res;
332 }
333
334 static int exec_app(const struct app_info_t *app_info)
335 {
336         int res = 0;
337
338         if (app_info == NULL) {
339                 LOGE("Cannot exec app. app_info is NULL");
340                 return -1;
341         }
342
343         switch (app_info->app_type) {
344         case APP_TYPE_TIZEN:
345                 if (exec_app_tizen(app_info->app_id, app_info->exe_path)) {
346                         LOGE("Cannot exec tizen app %s\n", app_info->app_id);
347                         res = -1;
348                 } else {
349                         inc_apps_to_run();
350                 }
351                 break;
352         case APP_TYPE_RUNNING:
353                 // TODO: nothing, it's running
354                 LOGI("already started\n");
355                 break;
356         case APP_TYPE_COMMON:
357                 if (exec_app_common(app_info->exe_path)) {
358                         LOGE("Cannot exec common app %s\n", app_info->exe_path);
359                         res = -1;
360                 } else {
361                         inc_apps_to_run();
362                 }
363                 break;
364         default:
365                 LOGE("Unknown app type %d\n", app_info->app_type);
366                 res = -1;
367                 break;
368         }
369
370         LOGI("ret=%d\n", res);
371         return res;
372 }
373
374 int launch_timer_start()
375 {
376         static struct epoll_event ev;
377         int res = 0;
378
379         manager.connect_timeout_timerfd =
380             timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
381         if (manager.connect_timeout_timerfd > 0) {
382                 struct itimerspec ctime;
383                 ctime.it_value.tv_sec = MAX_CONNECT_TIMEOUT_TIME;
384                 ctime.it_value.tv_nsec = 0;
385                 ctime.it_interval.tv_sec = 0;
386                 ctime.it_interval.tv_nsec = 0;
387                 if (timerfd_settime(manager.connect_timeout_timerfd, 0, &ctime, NULL) < 0) {
388                         LOGE("fail to set connect timeout timer\n");
389                         close(manager.connect_timeout_timerfd);
390                         manager.connect_timeout_timerfd = -1;
391                 } else {
392                         // add event fd to epoll list
393                         ev.events = EPOLLIN;
394                         ev.data.fd = manager.connect_timeout_timerfd;
395                         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
396                                       manager.connect_timeout_timerfd, &ev) < 0)
397                         {
398                                 // fail to add event fd
399                                 LOGE("fail to add app connection timeout timer fd to epoll list\n");
400                                 close(manager.connect_timeout_timerfd);
401                                 manager.connect_timeout_timerfd = -1;
402                         } else {
403                                 LOGI("connection timeout timer started\n");
404                         }
405                 }
406         } else {
407                 LOGE("cannot create connection timeout timer\n");
408         }
409
410         LOGI("ret=%d\n", res);
411         return res;
412 }
413
414 static void epoll_add_input_events();
415 static void epoll_del_input_events();
416
417 int prepare_profiling()
418 {
419         struct app_list_t *app = NULL;
420         const struct app_info_t *app_info = NULL;
421
422         app_info = app_info_get_first(&app);
423         if (app_info == NULL) {
424                 LOGE("No app info found\n");
425                 return -1;
426         }
427
428         //all apps
429         while (app_info != NULL) {
430                 if (kill_app_by_info(app_info) != 0) {
431                         LOGE("kill app failed\n");
432                         return -1;
433                 }
434                 app_info = app_info_get_next(&app);
435         }
436         //init rw for systeminfo
437         //init recv send network systeminfo
438         sys_stat_prepare();
439         return 0;
440
441 }
442
443 int start_profiling()
444 {
445         struct app_list_t *app = NULL;
446         const struct app_info_t *app_info = NULL;
447         int res = 0;
448
449         app_info = app_info_get_first(&app);
450         if (app_info == NULL) {
451                 LOGE("No app info found\n");
452                 return -1;
453         }
454         // remove previous screen capture files
455         remove_indir(SCREENSHOT_DIR);
456         if (mkdir(SCREENSHOT_DIR, 0777) == -1 && errno != EEXIST)
457                 LOGW("Failed to create directory for screenshot : %s\n",
458                      strerror(errno));
459
460         smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
461
462         if (samplingStart() < 0) {
463                 LOGE("Cannot start sampling\n");
464                 res = -1;
465                 goto exit;
466         }
467
468         if (IS_OPT_SET(FL_RECORDING))
469                 epoll_add_input_events();
470
471         while (app_info != NULL) {
472                 if (exec_app(app_info)) {
473                         LOGE("Cannot exec app\n");
474                         res = -1;
475                         goto recording_stop;
476                 }
477                 app_info = app_info_get_next(&app);
478         }
479
480         if (start_app_launch_timer(get_apps_to_run()) < 0) {
481                 res = -1;
482                 goto recording_stop;
483         }
484
485         goto exit;
486
487  recording_stop:
488         if (IS_OPT_SET(FL_RECORDING))
489                 epoll_del_input_events();
490         samplingStop();
491
492  exit:
493         LOGI("return %d\n", res);
494         return res;
495 }
496
497 void stop_profiling(void)
498 {
499         if (IS_OPT_SET(FL_RECORDING))
500                 epoll_del_input_events();
501         samplingStop();
502 }
503
504 static void reconfigure_recording(struct conf_t conf)
505 {
506         uint64_t old_features = prof_session.conf.use_features0;
507         uint64_t new_features = conf.use_features0;
508         uint64_t to_enable = (new_features ^ old_features) & new_features;
509         uint64_t to_disable = (new_features ^ old_features) & old_features;
510
511         if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) {
512                 epoll_del_input_events();
513                 prof_session.conf.use_features0 &= ~FL_RECORDING;
514         }
515
516         if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) {
517                 epoll_add_input_events();
518                 prof_session.conf.use_features0 |= FL_RECORDING;
519         }
520
521 }
522
523 int reconfigure(struct conf_t conf)
524 {
525         reconfigure_recording(conf);
526
527         samplingStop();
528         memcpy(&prof_session.conf, &conf, sizeof(conf));
529         if (samplingStart() < 0) {
530                 LOGE("Cannot start sampling\n");
531                 return -1;
532         }
533
534         return 0;
535 }
536
537 // just send stop message to all target process
538 static void terminate_all_target()
539 {
540         int i;
541         ssize_t sendlen;
542         msg_target_t sendlog;
543
544         sendlog.type = MSG_STOP;
545         sendlog.length = 0;
546
547         for (i = 0; i < MAX_TARGET_COUNT; i++) {
548                 if (manager.target[i].socket != -1) {
549                         sendlen = send(manager.target[i].socket, &sendlog,
550                                        sizeof(sendlog.type) +
551                                        sizeof(sendlog.length), MSG_NOSIGNAL);
552                         if (sendlen != -1) {
553                                 LOGI("TERMINATE send exit msg (socket %d) "
554                                      "by terminate_all_target()\n",
555                                      manager.target[i].socket);
556                         }
557                 }
558         }
559 }
560
561 // terminate all target and wait for threads
562 void terminate_all()
563 {
564         int i;
565         terminate_all_target();
566
567         // wait for all other thread exit
568         for (i = 0; i < MAX_TARGET_COUNT; i++) {
569                 if (manager.target[i].recv_thread != -1) {
570                         LOGI("join recv thread [%d] is started\n", i);
571                         pthread_join(manager.target[i].recv_thread, NULL);
572                         LOGI("join recv thread %d. done\n", i);
573                 }
574         }
575 }
576
577 // terminate all profiling by critical error
578 // TODO: don't send data to host
579 static void terminate_error(char *errstr, int send_to_host)
580 {
581         LOGE("termination all with err '%s'\n", errstr);
582         struct msg_data_t *msg = NULL;
583         if (send_to_host != 0) {
584                 msg = gen_message_error(errstr);
585                 if (msg) {
586                         write_to_buf(msg);
587                         free_msg_data(msg);
588                 } else {
589                         LOGI("cannot generate error message\n");
590                 }
591         }
592         terminate_all();
593 }
594
595 #define MAX_EVENTS_NUM 10
596 static int deviceEventHandler(input_dev *dev, int input_type)
597 {
598         int ret = 0;
599         ssize_t size = 0;
600         int count = 0;
601         struct input_event in_ev[MAX_EVENTS_NUM];
602         struct msg_data_t *log;
603
604         if (input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY) {
605                 do {
606                         size = read(dev->fd, &in_ev[count], sizeof(*in_ev));
607                         if (size > 0)
608                                 count++;
609                 } while (count < MAX_EVENTS_NUM && size > 0);
610
611                 if (count) {
612                         LOGI("read %d %s events\n",
613                              count,
614                              input_type == INPUT_ID_KEY ? STR_KEY : STR_TOUCH);
615                         log = gen_message_event(in_ev, count, input_type);
616                         printBuf((char *)log, MSG_DATA_HDR_LEN + log->len);
617                         write_to_buf(log);
618                         free_msg_data(log);
619                 }
620         } else {
621                 LOGW("unknown input_type\n");
622                 ret = 1;        // it is not error
623         }
624         return ret;
625 }
626
627 static int target_event_pid_handler(int index, uint64_t msg)
628 {
629         struct app_list_t *app = NULL;
630         struct app_info_t *app_info = NULL;
631         if (index == 0) {       // main application
632                 app_info = app_info_get_first(&app);
633                 if (app_info == NULL) {
634                         LOGE("No app info found\n");
635                         return -1;
636                 }
637
638                 while (app_info != NULL) {
639                         if (is_same_app_process(app_info->exe_path,
640                                                 manager.target[index].pid))
641                                 break;
642                         app_info = app_info_get_next(&app);
643                 }
644
645                 if (app_info == NULL) {
646                         LOGE("pid %d not found in app list\n",
647                              manager.target[index].pid);
648                         return -1;
649                 }
650
651                 if (start_replay() != 0) {
652                         LOGE("Cannot start replay thread\n");
653                         return -1;
654                 }
655         }
656         manager.target[index].initial_log = 1;
657         return 0;
658 }
659
660 static int target_event_stop_handler(int epollfd, int index, uint64_t msg)
661 {
662         LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
663              manager.target[index].socket, manager.target[index].pid,
664              manager.target_count - 1);
665
666         if (index == 0)         // main application
667                 stop_replay();
668
669         if (0 > epoll_ctl(epollfd, EPOLL_CTL_DEL,
670                           manager.target[index].event_fd, NULL))
671                 LOGW("fail to EPOLL DEL of event fd(%d)\n", index);
672
673         setEmptyTargetSlot(index);
674         // all target client are closed
675         if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) {
676                 LOGI("all targets are stopped\n");
677                 if (stop_all() != ERR_NO)
678                         LOGE("Stop failed\n");
679                 return -11;
680         }
681
682         return 0;
683 }
684
685 // return 0 if normal case
686 // return plus value if non critical error occur
687 // return minus value if critical error occur
688 // return -11 if all target process closed
689 static int target_event_handler(int epollfd, int index, uint64_t msg)
690 {
691         int err = 0;
692         if (msg & EVENT_PID)
693                 err = target_event_pid_handler(index, msg);
694         if (err)
695                 return err;
696
697         if (msg & EVENT_STOP || msg & EVENT_ERROR)
698                 err = target_event_stop_handler(epollfd, index, msg);
699
700         return err;
701 }
702
703 /**
704  * return 0 if normal case
705  * return plus value if non critical error occur
706  * return minus value if critical error occur
707  */
708 static int targetServerHandler(int efd)
709 {
710         msg_target_t log;
711         struct epoll_event ev;
712
713         int index = getEmptyTargetSlot();
714         if (index == MAX_TARGET_COUNT) {
715                 LOGW("Max target number(8) reached, no more target can connected\n");
716                 return 1;
717         }
718
719         manager.target[index].socket =
720             accept(manager.target_server_socket, NULL, NULL);
721
722         if (manager.target[index].socket >= 0) {
723                 /* accept succeed */
724                 fd_setup_smack_attributes(manager.target[index].socket);
725
726                 /* send config message to target process */
727                 log.type = MSG_OPTION;
728                 log.length = sprintf(log.data, "%llu",
729                                      prof_session.conf.use_features0);
730                 if (0 > send(manager.target[index].socket, &log,
731                              sizeof(log.type) + sizeof(log.length) + log.length,
732                              MSG_NOSIGNAL))
733                         LOGE("fail to send data to target index(%d)\n", index);
734
735                 // make event fd
736                 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
737                 if (manager.target[index].event_fd == -1) {
738                         // fail to make event fd
739                         LOGE("fail to make event fd for socket (%d)\n",
740                              manager.target[index].socket);
741                         goto TARGET_CONNECT_FAIL;
742                 }
743
744                 // add event fd to epoll list
745                 ev.events = EPOLLIN;
746                 ev.data.fd = manager.target[index].event_fd;
747                 if (epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0) {
748                         // fail to add event fd
749                         LOGE("fail to add event fd to epoll list for socket (%d)\n",
750                              manager.target[index].socket);
751                         goto TARGET_CONNECT_FAIL;
752                 }
753
754                 // make recv thread for target
755                 if (makeRecvThread(index) != 0) {
756                         // fail to make recv thread
757                         LOGE("fail to make recv thread for socket (%d)\n",
758                              manager.target[index].socket);
759                         if (0 > epoll_ctl(efd, EPOLL_CTL_DEL,
760                                           manager.target[index].event_fd, NULL))
761                                 LOGW("fail to EPOLL DEL of event fd(%d)\n", index);
762                         goto TARGET_CONNECT_FAIL;
763                 }
764
765                 dec_apps_to_run();
766
767                 if ((manager.app_launch_timerfd > 0) && (get_apps_to_run() == 0)) {
768                         if (stop_app_launch_timer() < 0)
769                                 LOGE("cannot stop app launch timer\n");
770                 }
771
772                 LOGI("target connected = %d(running %d target)\n",
773                      manager.target[index].socket, manager.target_count + 1);
774
775                 manager.target_count++;
776                 return 0;
777         } else {
778                 // accept error
779                 LOGE("Failed to accept at target server socket\n");
780         }
781
782  TARGET_CONNECT_FAIL:
783         if (manager.target_count == 0) {
784                 // if this connection is main connection
785                 return -1;
786         } else {
787                 // if this connection is not main connection then ignore process by error
788                 setEmptyTargetSlot(index);
789                 return 1;
790         }
791 }
792
793 // return 0 if normal case
794 // return plus value if non critical error occur
795 // return minus value if critical error occur
796 static int hostServerHandler(int efd)
797 {
798         static int hostserverorder = 0;
799         int csocket;
800         struct epoll_event ev;
801
802         if (hostserverorder > 1)        // control and data socket connected already
803                 return 1;               // ignore
804
805         csocket = accept(manager.host_server_socket, NULL, NULL);
806
807         if (csocket >= 0) {
808                 // accept succeed
809                 ev.events = EPOLLIN;
810                 ev.data.fd = csocket;
811                 if (epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0) {
812                         // consider as accept fail
813                         LOGE("Failed to add socket fd to epoll list\n");
814                         close(csocket);
815                         return -1;
816                 }
817
818                 if (hostserverorder == 0) {
819                         manager.host.control_socket = csocket;
820                         unlink_portfile();
821                         LOGI("host control socket connected = %d\n", csocket);
822                 } else {
823                         manager.host.data_socket = csocket;
824                         LOGI("host data socket connected = %d\n", csocket);
825                 }
826
827                 hostserverorder++;
828                 return 0;
829         } else {
830                 // accept error
831                 LOGE("Failed to accept from host server socket\n");
832                 return -1;
833         }
834 }
835
836 // return plus value if non critical error occur
837 // return minus value if critical error occur
838 // return -11 if socket closed
839
840 static int controlSocketHandler(int efd)
841 {
842         ssize_t recv_len;
843         struct msg_t msg_head;
844         struct msg_t *msg;
845         int res = 0;
846
847         if (manager.connect_timeout_timerfd >= 0) {
848                 LOGI("release connect timeout timer\n");
849                 if (0 > epoll_ctl(efd, EPOLL_CTL_DEL,
850                                   manager.connect_timeout_timerfd, NULL))
851                         LOGW("fail to EPOLL DEL of timeout timer fd\n");
852                 close(manager.connect_timeout_timerfd);
853                 manager.connect_timeout_timerfd = -1;
854         }
855         // Receive header
856         recv_len = recv(manager.host.control_socket,
857                         &msg_head, MSG_CMD_HDR_LEN, 0);
858         // error or close request from host
859         if (recv_len == -1 || recv_len == 0)
860                 return -11;
861         else {
862                 msg = malloc(MSG_CMD_HDR_LEN + msg_head.len);
863                 if (!msg) {
864                         LOGE("Cannot alloc msg\n");
865                         sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
866                         return -1;
867                 }
868                 msg->id = msg_head.id;
869                 msg->len = msg_head.len;
870                 if (msg->len > 0) {
871                         // Receive payload (if exists)
872                         recv_len = recv(manager.host.control_socket,
873                                         msg->payload, msg->len, MSG_WAITALL);
874                         if (recv_len == -1)
875                                 return -11;
876                 }
877                 printBuf((char *)msg, MSG_CMD_HDR_LEN + msg->len);
878                 res = host_message_handler(msg);
879                 free(msg);
880         }
881
882         return res;
883 }
884
885 static void epoll_add_input_events()
886 {
887         struct epoll_event ev;
888         int i;
889
890         // add device fds to epoll event pool
891         ev.events = EPOLLIN;
892         for (i = 0; g_key_dev[i].fd != ARRAY_END; i++) {
893                 if (g_key_dev[i].fd >= 0) {
894                         ev.data.fd = g_key_dev[i].fd;
895                         if (epoll_ctl(manager.efd,
896                                       EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0
897                                       && errno != EEXIST)
898                                 LOGE("keyboard device file epoll_ctl error: %s\n", strerror(errno));
899                 }
900         }
901
902         ev.events = EPOLLIN;
903         for (i = 0; g_touch_dev[i].fd != ARRAY_END; i++) {
904                 if (g_touch_dev[i].fd >= 0) {
905                         ev.data.fd = g_touch_dev[i].fd;
906                         if (epoll_ctl(manager.efd,
907                                       EPOLL_CTL_ADD,
908                                       g_touch_dev[i].fd, &ev) < 0
909                                       && errno != EEXIST)
910                                 LOGE("touch device file epoll_ctl error: %s\n", strerror(errno));
911                 }
912         }
913 }
914
915 static void epoll_del_input_events()
916 {
917         int i;
918
919         // remove device fds from epoll event pool
920         for (i = 0; g_key_dev[i].fd != ARRAY_END; i++)
921                 if (g_key_dev[i].fd >= 0)
922                         if (epoll_ctl(manager.efd,
923                                       EPOLL_CTL_DEL, g_key_dev[i].fd, NULL) < 0)
924                                 LOGE("keyboard device file epoll_ctl error: %s\n", strerror(errno));
925
926         for (i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
927                 if (g_touch_dev[i].fd >= 0)
928                         if (epoll_ctl(manager.efd,
929                                       EPOLL_CTL_DEL,
930                                       g_touch_dev[i].fd, NULL) < 0)
931                                 LOGE("touch device file epoll_ctl error: %s\n", strerror(errno));
932 }
933
934 static bool initialize_epoll_events(void)
935 {
936         struct epoll_event ev;
937
938         if ((manager.efd = epoll_create1(0)) < 0) {
939                 LOGE("epoll creation error\n");
940                 return false;
941         }
942         // add server sockets to epoll event pool
943         ev.events = EPOLLIN;
944         ev.data.fd = manager.host_server_socket;
945         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
946                       manager.host_server_socket, &ev) < 0) {
947                 LOGE("Host server socket epoll_ctl error\n");
948                 return false;
949         }
950         ev.events = EPOLLIN;
951         ev.data.fd = manager.target_server_socket;
952         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
953                       manager.target_server_socket, &ev) < 0) {
954                 LOGE("Target server socket epoll_ctl error\n");
955                 return false;
956         }
957         return true;
958 }
959
960 // return 0 for normal case
961 int daemonLoop()
962 {
963         int return_value = 0;
964         struct epoll_event *events = malloc(EPOLL_SIZE * sizeof(*events));
965
966         _get_fds(g_key_dev, INPUT_ID_KEY);
967         if (g_key_dev[0].fd == ARRAY_END) {
968                 LOGE("No key devices found.\n");
969                 return_value = -1;
970                 goto END_EVENT;
971         }
972         _get_fds(g_touch_dev, INPUT_ID_TOUCH);
973         if (g_touch_dev[0].fd == ARRAY_END) {
974                 LOGE("No touch devices found.\n");
975                 return_value = -1;
976                 goto END_EVENT;
977         }
978
979         if (!events) {
980                 LOGE("Out of memory when allocate epoll event pool\n");
981                 return_value = -1;
982                 goto END_EVENT;
983         }
984         if (!initialize_epoll_events()) {
985                 return_value = -1;
986                 goto END_EFD;
987         }
988
989         if (launch_timer_start() < 0) {
990                 LOGE("Launch timer start failed\n");
991                 return_value = -1;
992                 goto END_EFD;
993         }
994
995         init_prof_session(&prof_session);
996
997         // handler loop
998         while (1) {
999                 int i, k;
1000                 ssize_t recvLen;
1001                 // number of occured events
1002                 int numevent = epoll_wait(manager.efd, events, EPOLL_SIZE, -1);
1003                 if (numevent <= 0) {
1004                         LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
1005                         continue;
1006                 }
1007
1008                 for (i = 0; i < numevent; i++) {
1009                         // check for request from event fd
1010                         for (k = 0; k < MAX_TARGET_COUNT; k++) {
1011                                 if (manager.target[k].socket != -1 &&
1012                                     events[i].data.fd == manager.target[k].event_fd) {
1013                                         uint64_t u;
1014                                         recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
1015                                         if (recvLen != sizeof(uint64_t)) {
1016                                                 // maybe closed, but ignoring is more safe then
1017                                                 // removing fd from epoll list
1018                                         } else {
1019                                                 if (-11 == target_event_handler(manager.efd, k, u)) {
1020                                                         LOGI("all target process is closed\n");
1021                                                         continue;
1022                                                 }
1023                                         }
1024                                         break;
1025                                 }
1026                         }
1027
1028                         if (k != MAX_TARGET_COUNT)
1029                                 continue;
1030
1031                         // check for request from device fd
1032                         for (k = 0; g_touch_dev[k].fd != ARRAY_END; k++) {
1033                                 if (g_touch_dev[k].fd >= 0 &&
1034                                     events[i].data.fd == g_touch_dev[k].fd) {
1035                                         if (deviceEventHandler(&g_touch_dev[k],
1036                                             INPUT_ID_TOUCH) < 0) {
1037                                                 LOGE("Internal DA framework error, "
1038                                                      "Please re-run the profiling (touch dev)\n");
1039                                                 continue;
1040                                         }
1041                                         break;
1042                                 }
1043                         }
1044
1045                         if (g_touch_dev[k].fd != ARRAY_END)
1046                                 continue;
1047
1048                         for (k = 0; g_key_dev[k].fd != ARRAY_END; k++) {
1049                                 if (g_key_dev[k].fd >= 0 &&
1050                                     events[i].data.fd == g_key_dev[k].fd) {
1051                                         if (deviceEventHandler(&g_key_dev[k], INPUT_ID_KEY) < 0) {
1052                                                 LOGE("Internal DA framework error, "
1053                                                      "Please re-run the profiling (key dev)\n");
1054                                                 continue;
1055                                         }
1056                                         break;
1057                                 }
1058                         }
1059
1060                         if (g_key_dev[k].fd != ARRAY_END)
1061                                 continue;
1062
1063                         // connect request from target
1064                         if (events[i].data.fd == manager.target_server_socket) {
1065                                 if (targetServerHandler(manager.efd) < 0) {
1066                                         // critical error
1067                                         terminate_error("Internal DA framework error, "
1068                                                         "Please re-run the profiling "
1069                                                         "(targetServerHandler)\n", 1);
1070                                         continue;
1071                                 }
1072                         } else if (events[i].data.fd == manager.host_server_socket) {
1073                         // connect request from host
1074                                 int result = hostServerHandler(manager.efd);
1075                                 if (result < 0) {
1076                                         LOGE("Internal DA framework error (hostServerHandler)\n");
1077                                         continue;
1078                                 }
1079                         } else if (events[i].data.fd == manager.host.control_socket) {
1080                         // control message from host
1081                                 int result = controlSocketHandler(manager.efd);
1082                                 if (result == -11) {
1083                                         // socket close
1084                                         //if the host disconnected.
1085                                         //In all other cases daemon must report an error and continue the loop
1086                                         //close connect_timeoutt and host socket and quit
1087                                         LOGI("Connection closed. Termination. (%d)\n",
1088                                               manager.host.control_socket);
1089                                         return_value = 0;
1090                                         goto END_EFD;
1091                                 } else if (result < 0) {
1092                                         LOGE("Control socket handler.\n");
1093                                 }
1094                         } else if (events[i].data.fd == manager.host.data_socket) {
1095                                 char recvBuf[32];
1096                                 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1097                                 if (recvLen == 0) {
1098                                         // close data socket
1099                                         if (0 > epoll_ctl(manager.efd,
1100                                                           EPOLL_CTL_DEL,
1101                                                           manager.host.data_socket,
1102                                                           NULL))
1103                                                 LOGW("fail to EPOLL DEL of host data socket\n");
1104                                         close(manager.host.data_socket);
1105                                         manager.host.data_socket = -1;
1106                                         // TODO: finish transfer thread
1107                                 }
1108
1109                                 LOGI("host message from data socket %d\n",
1110                                      recvLen);
1111                         } else if (events[i].data.fd == manager.app_launch_timerfd) {
1112                                 // check for application launch timerfd
1113                                 // send to host timeout error message for launching application
1114                                 LOGE("Failed to launch application\n");
1115                                 if (stop_app_launch_timer() < 0)
1116                                         LOGE("cannot stop app launch timer\n");
1117                                 continue;
1118                         } else if (events[i].data.fd == manager.connect_timeout_timerfd) {
1119                                 // check for connection timeout timerfd
1120                                 // send to host timeout error message for launching application
1121                                 terminate_error("no incoming connections", 1);
1122                                 if (0 > epoll_ctl(manager.efd, EPOLL_CTL_DEL,
1123                                                   manager.connect_timeout_timerfd,
1124                                                   NULL))
1125                                         LOGW("fail to EPOLL DEL of timeout timer fd\n");
1126                                 close(manager.connect_timeout_timerfd);
1127                                 manager.connect_timeout_timerfd = -1;
1128                                 LOGE("No connection in %d sec. shutdown.\n",
1129                                      MAX_CONNECT_TIMEOUT_TIME);
1130                                 goto END_EFD;
1131                         } else {
1132                                 // unknown socket
1133                                 // never happened
1134                                 LOGW("Unknown socket fd (%d)\n",
1135                                      events[i].data.fd);
1136                         }
1137                 }
1138         }
1139
1140  END_EFD:
1141         LOGI("close efd\n");
1142         close(manager.efd);
1143  END_EVENT:
1144         free(events);
1145         return return_value;
1146 }