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