976ee0bf31b877d10b463cfb68fce86d580855f7
[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 #ifndef LOCALTEST
51 #include <attr/xattr.h>         // for fsetxattr
52 #include <sys/smack.h>
53 #endif
54
55 #include <linux/input.h>
56 #include <dirent.h>
57 #include <fcntl.h>
58 #include "daemon.h"
59 #include "sys_stat.h"
60 #include "utils.h"
61 #include "da_protocol.h"
62 #include "da_inst.h"
63 #include "da_data.h"
64 #include "debug.h"
65
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"
69
70 #define EPOLL_SIZE                      10
71 #define MAX_APP_LAUNCH_TIME             60
72 #define MAX_CONNECT_TIMEOUT_TIME        5*60
73
74 #define MAX_DEVICE                      10
75 #define MAX_FILENAME                    128
76 #define BUF_SIZE                        1024
77 #define ARRAY_END                       (-11)
78
79 input_dev g_key_dev[MAX_DEVICE];
80 input_dev g_touch_dev[MAX_DEVICE];
81
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)
85 {
86         int ret = 0;
87
88         if (fp != NULL && size > 0) {
89                 ret = fread((void *)buffer, sizeof(char), size, fp);
90                 buffer[ret] = '\0';
91         } else {
92                 // fp is null
93                 if (size > 0)
94                         buffer[0] = '\0';
95                 ret = 0;        // error case
96         }
97
98         return ret;
99 }
100
101 // get input id of given input device
102 static int get_input_id(char *inputname)
103 {
104         static int query_cmd_type = 0;  // 1 if /lib/udev/input_id, 2 if udevadm
105         FILE *cmd_fp = NULL;
106         char buffer[BUF_SIZE];
107         char command[MAX_FILENAME];
108         int ret = -1;
109
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
114                         query_cmd_type = 1;
115                 } else {
116                         // there is not /lib/udev/input_id
117                         query_cmd_type = 2;
118                 }
119         }
120         // make command string
121         if (query_cmd_type == 1) {
122                 sprintf(command, "/lib/udev/input_id /class/input/%s",
123                         inputname);
124         } else {
125                 sprintf(command,
126                         "udevadm info --name=input/%s --query=property",
127                         inputname);
128         }
129
130         // run command
131         cmd_fp = popen(command, "r");
132         if (_file_read(cmd_fp, buffer, BUF_SIZE) < 0) {
133                 LOGE("Failed to read input_id\n");
134                 if (cmd_fp != NULL)
135                         pclose(cmd_fp);
136                 return ret;
137         }
138         // determine input id
139         if (strstr(buffer, INPUT_ID_STR_KEY)) {
140                 // key
141                 ret = INPUT_ID_KEY;
142         } else if (strstr(buffer, INPUT_ID_STR_TOUCH)) {
143                 // touch
144                 ret = INPUT_ID_TOUCH;
145         } else if (strstr(buffer, INPUT_ID_STR_KEYBOARD)) {
146                 // keyboard
147                 ret = INPUT_ID_KEY;
148         } else if (strstr(buffer, INPUT_ID_STR_TABLET)) {
149                 // touch (emulator)
150                 ret = INPUT_ID_TOUCH;
151         }
152
153         if (cmd_fp != NULL)
154                 pclose(cmd_fp);
155         return ret;
156 }
157
158 // get filename and fd of given input type devices
159 static void _get_fds(input_dev *dev, int input_id)
160 {
161         DIR *dp;
162         struct dirent *d;
163         int count = 0;
164
165         dp = opendir("/sys/class/input");
166
167         if (dp != NULL) {
168                 while ((d = readdir(dp)) != NULL) {
169                         if (!strncmp(d->d_name, "event", 5)) {
170                                 // start with "event"
171                                 // event file
172                                 if (input_id == get_input_id(d->d_name)) {
173                                         sprintf(dev[count].fileName,
174                                                 "/dev/input/%s", d->d_name);
175                                         dev[count].fd =
176                                             open(dev[count].fileName,
177                                                  O_RDWR | O_NONBLOCK);
178                                         count++;
179                                 }
180                         }
181                 }
182
183                 closedir(dp);
184         }
185         dev[count].fd = ARRAY_END;      // end of input_dev array
186 }
187
188 //static
189 void _device_write(input_dev *dev, struct input_event *in_ev)
190 {
191         int i;
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));
197                 }
198         }
199 }
200
201 uint64_t get_total_alloc_size()
202 {
203         int i;
204         uint64_t allocsize = 0;
205
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;
210         }
211         return allocsize;
212 }
213
214 static int getEmptyTargetSlot()
215 {
216         int i;
217         for (i = 0; i < MAX_TARGET_COUNT; i++) {
218                 if (manager.target[i].socket == -1)
219                         break;
220         }
221
222         return i;
223 }
224
225 static void setEmptyTargetSlot(int index)
226 {
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;
238         }
239 }
240
241 // =============================================================================
242 // start and terminate control functions
243 // =============================================================================
244
245 //start application launch timer function
246 static int start_app_launch_timer()
247 {
248         int res = 0;
249         struct epoll_event ev;
250
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;
263                         res = -1;
264                 } else {
265                         // add event fd to epoll list
266                         ev.events = EPOLLIN;
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;
274                                 res = -2;
275                         } else {
276                                 LOGI("application launch time started\n");
277                         }
278                 }
279         } else {
280                 LOGE("cannot create launch timer\n");
281                 res = -3;
282         }
283
284         return res;
285 }
286
287 //stop application launch timer
288 static int stop_app_launch_timer()
289 {
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;
295         return 0;
296 }
297
298 int kill_app_by_info(const struct app_info_t *app_info)
299 {
300         int res = 0;
301
302         if (app_info == NULL) {
303                 LOGE("Cannot exec app. app_info is NULL");
304                 return -1;
305         }
306
307         switch (app_info->app_type) {
308         case APP_TYPE_TIZEN:
309                 res = kill_app(app_info->exe_path);
310                 break;
311         case APP_TYPE_RUNNING:
312                 // TODO: nothing, it's running
313                 LOGI("already started\n");
314                 break;
315         case APP_TYPE_COMMON:
316                 res = kill_app(app_info->exe_path);
317                 break;
318         default:
319                 LOGE("Unknown app type %d\n", app_info->app_type);
320                 res = -1;
321                 break;
322         }
323
324         return res;
325 }
326
327 static int exec_app(const struct app_info_t *app_info)
328 {
329         int res = 0;
330
331         if (app_info == NULL) {
332                 LOGE("Cannot exec app. app_info is NULL");
333                 return -1;
334         }
335
336         switch (app_info->app_type) {
337         case APP_TYPE_TIZEN:
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);
340                         res = -1;
341                 }
342                 break;
343         case APP_TYPE_RUNNING:
344                 // TODO: nothing, it's running
345                 LOGI("already started\n");
346                 break;
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);
350                         res = -1;
351                 }
352                 break;
353         default:
354                 LOGE("Unknown app type %d\n", app_info->app_type);
355                 res = -1;
356                 break;
357         }
358
359         if (res == 0 && app_info->app_type != APP_TYPE_RUNNING)
360                 if (start_app_launch_timer() < 0)
361                         res = -1;
362
363         LOGI("ret=%d\n", res);
364         return res;
365 }
366
367 int launch_timer_start()
368 {
369         static struct epoll_event ev;
370         int res = 0;
371
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;
384                 } else {
385                         // add event fd to epoll list
386                         ev.events = EPOLLIN;
387                         ev.data.fd = manager.connect_timeout_timerfd;
388                         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
389                                       manager.connect_timeout_timerfd, &ev) < 0)
390                         {
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;
395                         } else {
396                                 LOGI("connection timeout timer started\n");
397                         }
398                 }
399         } else {
400                 LOGE("cannot create connection timeout timer\n");
401         }
402
403         LOGI("ret=%d\n", res);
404         return res;
405 }
406
407 static void epoll_add_input_events();
408 static void epoll_del_input_events();
409
410 int prepare_profiling()
411 {
412         struct app_list_t *app = NULL;
413         const struct app_info_t *app_info = NULL;
414
415         app_info = app_info_get_first(&app);
416         if (app_info == NULL) {
417                 LOGE("No app info found\n");
418                 return -1;
419         }
420
421         //all apps
422         while (app_info != NULL) {
423                 if (kill_app_by_info(app_info) != 0) {
424                         LOGE("kill app failed\n");
425                         return -1;
426                 }
427                 app_info = app_info_get_next(&app);
428         }
429         //init rw for systeminfo
430         //init recv send network systeminfo
431         sys_stat_prepare();
432         return 0;
433
434 }
435
436 int start_profiling()
437 {
438         struct app_list_t *app = NULL;
439         const struct app_info_t *app_info = NULL;
440         int res = 0;
441
442         app_info = app_info_get_first(&app);
443         if (app_info == NULL) {
444                 LOGE("No app info found\n");
445                 return -1;
446         }
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",
451                      strerror(errno));
452
453 #ifndef LOCALTEST
454         smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
455 #endif
456
457         if (samplingStart() < 0) {
458                 LOGE("Cannot start sampling\n");
459                 res = -1;
460                 goto exit;
461         }
462
463         if (IS_OPT_SET(FL_RECORDING))
464                 epoll_add_input_events();
465
466         if (exec_app(app_info)) {
467                 LOGE("Cannot exec app\n");
468                 res = -1;
469                 goto recording_stop;
470         }
471
472         goto exit;
473
474  recording_stop:
475         if (IS_OPT_SET(FL_RECORDING))
476                 epoll_del_input_events();
477         samplingStop();
478
479  exit:
480         LOGI("return %d\n", res);
481         return res;
482 }
483
484 void stop_profiling(void)
485 {
486         if (IS_OPT_SET(FL_RECORDING))
487                 epoll_del_input_events();
488         samplingStop();
489 }
490
491 static void reconfigure_recording(struct conf_t conf)
492 {
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;
497
498         if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) {
499                 epoll_del_input_events();
500                 prof_session.conf.use_features0 &= ~FL_RECORDING;
501         }
502
503         if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) {
504                 epoll_add_input_events();
505                 prof_session.conf.use_features0 |= FL_RECORDING;
506         }
507
508 }
509
510 int reconfigure(struct conf_t conf)
511 {
512         reconfigure_recording(conf);
513
514         samplingStop();
515         memcpy(&prof_session.conf, &conf, sizeof(conf));
516         if (samplingStart() < 0) {
517                 LOGE("Cannot start sampling\n");
518                 return -1;
519         }
520
521         return 0;
522 }
523
524 // just send stop message to all target process
525 static void terminate_all_target()
526 {
527         int i;
528         ssize_t sendlen;
529         msg_target_t sendlog;
530
531         sendlog.type = MSG_STOP;
532         sendlog.length = 0;
533
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);
539                         if (sendlen != -1) {
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);
544                                 break;
545                         }
546                 }
547         }
548 }
549
550 // terminate all target and wait for threads
551 void terminate_all()
552 {
553         int i;
554         terminate_all_target();
555
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);
562                 }
563         }
564 }
565
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)
569 {
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);
574                 if (msg) {
575                         write_to_buf(msg);
576                         free_msg_data(msg);
577                 } else {
578                         LOGI("cannot generate error message\n");
579                 }
580         }
581         terminate_all();
582 }
583
584 #define MAX_EVENTS_NUM 10
585 static int deviceEventHandler(input_dev *dev, int input_type)
586 {
587         int ret = 0;
588         ssize_t size = 0;
589         int count = 0;
590         struct input_event in_ev[MAX_EVENTS_NUM];
591         struct msg_data_t *log;
592
593         if (input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY) {
594                 do {
595                         size = read(dev->fd, &in_ev[count], sizeof(*in_ev));
596                         if (size > 0)
597                                 count++;
598                 } while (count < MAX_EVENTS_NUM && size > 0);
599
600                 if (count) {
601                         LOGI("read %d %s events\n",
602                              count,
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);
606                         write_to_buf(log);
607                         free_msg_data(log);
608                 }
609         } else {
610                 LOGW("unknown input_type\n");
611                 ret = 1;        // it is not error
612         }
613         return ret;
614 }
615
616 static int target_event_pid_handler(int index, uint64_t msg)
617 {
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");
624                         return -1;
625                 }
626
627                 while (app_info != NULL) {
628                         if (is_same_app_process(app_info->exe_path,
629                                                 manager.target[index].pid))
630                                 break;
631                         app_info = app_info_get_next(&app);
632                 }
633
634                 if (app_info == NULL) {
635                         LOGE("pid %d not found in app list\n",
636                              manager.target[index].pid);
637                         return -1;
638                 }
639
640                 if (start_replay() != 0) {
641                         LOGE("Cannot start replay thread\n");
642                         return -1;
643                 }
644         }
645         manager.target[index].initial_log = 1;
646         return 0;
647 }
648
649 static int target_event_stop_handler(int epollfd, int index, uint64_t msg)
650 {
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);
654
655         if (index == 0)         // main application
656                 stop_replay();
657
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);
661
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");
668                 return -11;
669         }
670
671         return 0;
672 }
673
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)
679 {
680         int err = 0;
681         if (msg & EVENT_PID)
682                 err = target_event_pid_handler(index, msg);
683         if (err)
684                 return err;
685
686         if (msg & EVENT_STOP || msg & EVENT_ERROR)
687                 err = target_event_stop_handler(epollfd, index, msg);
688
689         return err;
690 }
691
692 /**
693  * return 0 if normal case
694  * return plus value if non critical error occur
695  * return minus value if critical error occur
696  */
697 static int targetServerHandler(int efd)
698 {
699         msg_target_t log;
700         struct epoll_event ev;
701
702         int index = getEmptyTargetSlot();
703         if (index == MAX_TARGET_COUNT) {
704                 LOGW("Max target number(8) reached, no more target can connected\n");
705                 return 1;
706         }
707
708         manager.target[index].socket =
709             accept(manager.target_server_socket, NULL, NULL);
710
711         if (manager.target[index].socket >= 0) {
712                 /* accept succeed */
713                 fd_setup_smack_attributes(manager.target[index].socket);
714
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,
721                              MSG_NOSIGNAL))
722                         LOGE("fail to send data to target index(%d)\n", index);
723
724                 // make event fd
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;
731                 }
732
733                 // add event fd to epoll list
734                 ev.events = EPOLLIN;
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;
741                 }
742
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;
752                 }
753
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");
758                 }
759
760                 LOGI("target connected = %d(running %d target)\n",
761                      manager.target[index].socket, manager.target_count + 1);
762
763                 manager.target_count++;
764                 return 0;
765         } else {
766                 // accept error
767                 LOGE("Failed to accept at target server socket\n");
768         }
769
770  TARGET_CONNECT_FAIL:
771         if (manager.target_count == 0) {
772                 // if this connection is main connection
773                 return -1;
774         } else {
775                 // if this connection is not main connection then ignore process by error
776                 setEmptyTargetSlot(index);
777                 return 1;
778         }
779 }
780
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)
785 {
786         static int hostserverorder = 0;
787         int csocket;
788         struct epoll_event ev;
789
790         if (hostserverorder > 1)        // control and data socket connected already
791                 return 1;               // ignore
792
793         csocket = accept(manager.host_server_socket, NULL, NULL);
794
795         if (csocket >= 0) {
796                 // accept succeed
797                 ev.events = EPOLLIN;
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");
802                         close(csocket);
803                         return -1;
804                 }
805
806                 if (hostserverorder == 0) {
807                         manager.host.control_socket = csocket;
808                         unlink_portfile();
809                         LOGI("host control socket connected = %d\n", csocket);
810                 } else {
811                         manager.host.data_socket = csocket;
812                         LOGI("host data socket connected = %d\n", csocket);
813                 }
814
815                 hostserverorder++;
816                 return 0;
817         } else {
818                 // accept error
819                 LOGE("Failed to accept from host server socket\n");
820                 return -1;
821         }
822 }
823
824 // return plus value if non critical error occur
825 // return minus value if critical error occur
826 // return -11 if socket closed
827
828 static int controlSocketHandler(int efd)
829 {
830         ssize_t recv_len;
831         struct msg_t msg_head;
832         struct msg_t *msg;
833         int res = 0;
834
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;
842         }
843         // Receive header
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)
848                 return -11;
849         else {
850                 msg = malloc(MSG_CMD_HDR_LEN + msg_head.len);
851                 if (!msg) {
852                         LOGE("Cannot alloc msg\n");
853                         sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
854                         return -1;
855                 }
856                 msg->id = msg_head.id;
857                 msg->len = msg_head.len;
858                 if (msg->len > 0) {
859                         // Receive payload (if exists)
860                         recv_len = recv(manager.host.control_socket,
861                                         msg->payload, msg->len, MSG_WAITALL);
862                         if (recv_len == -1)
863                                 return -11;
864                 }
865                 printBuf((char *)msg, MSG_CMD_HDR_LEN + msg->len);
866                 res = host_message_handler(msg);
867                 free(msg);
868         }
869
870         return res;
871 }
872
873 static void epoll_add_input_events()
874 {
875         struct epoll_event ev;
876         int i;
877
878         // add device fds to epoll event pool
879         ev.events = EPOLLIN;
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
885                                       && errno != EEXIST)
886                                 LOGE("keyboard device file epoll_ctl error: %s\n", strerror(errno));
887                 }
888         }
889
890         ev.events = EPOLLIN;
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,
895                                       EPOLL_CTL_ADD,
896                                       g_touch_dev[i].fd, &ev) < 0
897                                       && errno != EEXIST)
898                                 LOGE("touch device file epoll_ctl error: %s\n", strerror(errno));
899                 }
900         }
901 }
902
903 static void epoll_del_input_events()
904 {
905         int i;
906
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));
913
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,
917                                       EPOLL_CTL_DEL,
918                                       g_touch_dev[i].fd, NULL) < 0)
919                                 LOGE("touch device file epoll_ctl error: %s\n", strerror(errno));
920 }
921
922 static bool initialize_epoll_events(void)
923 {
924         struct epoll_event ev;
925
926         if ((manager.efd = epoll_create1(0)) < 0) {
927                 LOGE("epoll creation error\n");
928                 return false;
929         }
930         // add server sockets to epoll event pool
931         ev.events = EPOLLIN;
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");
936                 return false;
937         }
938         ev.events = EPOLLIN;
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");
943                 return false;
944         }
945         return true;
946 }
947
948 // return 0 for normal case
949 int daemonLoop()
950 {
951         int return_value = 0;
952         struct epoll_event *events = malloc(EPOLL_SIZE * sizeof(*events));
953
954         _get_fds(g_key_dev, INPUT_ID_KEY);
955         _get_fds(g_touch_dev, INPUT_ID_TOUCH);
956
957         if (!events) {
958                 LOGE("Out of memory when allocate epoll event pool\n");
959                 return_value = -1;
960                 goto END_EVENT;
961         }
962         if (!initialize_epoll_events()) {
963                 return_value = -1;
964                 goto END_EFD;
965         }
966
967         if (launch_timer_start() < 0) {
968                 LOGE("Launch timer start failed\n");
969                 return_value = -1;
970                 goto END_EFD;
971         }
972
973         init_prof_session(&prof_session);
974
975         // handler loop
976         while (1) {
977                 int i, k;
978                 ssize_t recvLen;
979                 // number of occured events
980                 int numevent = epoll_wait(manager.efd, events, EPOLL_SIZE, -1);
981                 if (numevent <= 0) {
982                         LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
983                         continue;
984                 }
985
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) {
991                                         uint64_t u;
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
996                                         } else {
997                                                 if (-11 == target_event_handler(manager.efd, k, u)) {
998                                                         LOGI("all target process is closed\n");
999                                                         continue;
1000                                                 }
1001                                         }
1002                                         break;
1003                                 }
1004                         }
1005
1006                         if (k != MAX_TARGET_COUNT)
1007                                 continue;
1008
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");
1017                                                 continue;
1018                                         }
1019                                         break;
1020                                 }
1021                         }
1022
1023                         if (g_touch_dev[k].fd != ARRAY_END)
1024                                 continue;
1025
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");
1032                                                 continue;
1033                                         }
1034                                         break;
1035                                 }
1036                         }
1037
1038                         if (g_key_dev[k].fd != ARRAY_END)
1039                                 continue;
1040
1041                         // connect request from target
1042                         if (events[i].data.fd == manager.target_server_socket) {
1043                                 if (targetServerHandler(manager.efd) < 0) {
1044                                         // critical error
1045                                         terminate_error("Internal DA framework error, "
1046                                                         "Please re-run the profiling "
1047                                                         "(targetServerHandler)\n", 1);
1048                                         continue;
1049                                 }
1050                         } else if (events[i].data.fd == manager.host_server_socket) {
1051                         // connect request from host
1052                                 int result = hostServerHandler(manager.efd);
1053                                 if (result < 0) {
1054                                         LOGE("Internal DA framework error (hostServerHandler)\n");
1055                                         continue;
1056                                 }
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) {
1061                                         // socket close
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);
1067                                         return_value = 0;
1068                                         goto END_EFD;
1069                                 } else if (result < 0) {
1070                                         LOGE("Control socket handler.\n");
1071                                 }
1072                         } else if (events[i].data.fd == manager.host.data_socket) {
1073                                 char recvBuf[32];
1074                                 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1075                                 if (recvLen == 0) {
1076                                         // close data socket
1077                                         if (0 > epoll_ctl(manager.efd,
1078                                                           EPOLL_CTL_DEL,
1079                                                           manager.host.data_socket,
1080                                                           NULL))
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
1085                                 }
1086
1087                                 LOGI("host message from data socket %d\n",
1088                                      recvLen);
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");
1095                                 continue;
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,
1102                                                   NULL))
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);
1108                                 goto END_EFD;
1109                         } else {
1110                                 // unknown socket
1111                                 // never happened
1112                                 LOGW("Unknown socket fd (%d)\n",
1113                                      events[i].data.fd);
1114                         }
1115                 }
1116         }
1117
1118  END_EFD:
1119         LOGI("close efd\n");
1120         close(manager.efd);
1121  END_EVENT:
1122         free(events);
1123         return return_value;
1124 }