[FIX] launch and kill tizen application
[platform/core/system/swap-manager.git] / daemon / daemon.c
1 /*
2 *  DA manager
3 *
4 * Copyright (c) 2000 - 2011 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
12  * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 * Contributors:
25 * - S-Core Co., Ltd
26 *
27 */ 
28
29 #include <stdio.h>
30 #include <stdlib.h>                     // for realpath
31 #include <string.h>                     // for strtok, strcpy, strncpy
32 #include <limits.h>                     // for realpath
33
34 #include <errno.h>                      // for errno
35 #include <sys/types.h>          // for accept, mkdir, opendir, readdir
36 #include <sys/socket.h>         // for accept
37 #include <sys/stat.h>           // for mkdir
38 #include <sys/eventfd.h>        // for eventfd
39 #include <sys/epoll.h>          // for epoll apis
40 #include <sys/timerfd.h>        // for timerfd
41 #include <unistd.h>                     // for access, sleep
42
43 #ifndef LOCALTEST
44 #include <attr/xattr.h>         // for fsetxattr
45 #include <sys/smack.h>
46 #endif
47
48 #include <linux/input.h>
49 #include <dirent.h>
50 #include <fcntl.h>
51 #include "daemon.h"
52 #include "sys_stat.h"
53 #include "utils.h"
54 #include "da_protocol.h"
55 #define DA_WORK_DIR                             "/home/developer/sdk_tools/da/"
56 #define DA_READELF_PATH                 "/home/developer/sdk_tools/da/readelf"
57 #define SCREENSHOT_DIR                  "/tmp/da"
58
59 #define EPOLL_SIZE                              10
60 #define MAX_CONNECT_SIZE                12
61 #define MAX_APP_LAUNCH_TIME             6
62
63 #define INPUT_ID_TOUCH                  0
64 #define INPUT_ID_KEY                    1       
65 #define STR_TOUCH                               "TOUCH"
66 #define STR_KEY                                 "KEY"
67 #define INPUT_ID_STR_KEY                "ID_INPUT_KEY=1"
68 #define INPUT_ID_STR_TOUCH              "ID_INPUT_TOUCHSCREEN=1"
69 #define INPUT_ID_STR_KEYBOARD   "ID_INPUT_KEYBOARD=1"
70 #define INPUT_ID_STR_TABLET             "ID_INPUT_TABLET=1"
71
72 #define MAX_DEVICE                              10
73 #define MAX_FILENAME                    128
74 #define BUF_SIZE                                1024
75 #define ARRAY_END                               (-11)
76
77 typedef struct _input_dev
78 {
79         int fd;
80         char fileName[MAX_FILENAME];
81 } input_dev;
82
83 input_dev g_key_dev[MAX_DEVICE];
84 input_dev g_touch_dev[MAX_DEVICE];
85
86 // return bytes size of readed data
87 // return 0 if no data readed or error occurred
88 static int _file_read(FILE* fp, char *buffer, int size)
89 {
90         int ret = 0;
91
92         if(fp != NULL && size > 0)
93         {
94                 ret = fread((void*)buffer, sizeof(char), size, fp);
95         }
96         else
97         {
98                 // fp is null
99                 if(size > 0)
100                         buffer[0] = '\0';
101
102                 ret = 0;        // error case
103         }
104
105         return ret;
106 }
107
108 // get input id of given input device
109 static int get_input_id(char* inputname)
110 {
111         static int query_cmd_type = 0;  // 1 if /lib/udev/input_id, 2 if udevadm
112         FILE* cmd_fp = NULL;
113         char buffer[BUF_SIZE];
114         char command[MAX_FILENAME];
115         int ret = -1;
116
117         // determine input_id query command
118         if(unlikely(query_cmd_type == 0))
119         {
120                 if(access("/lib/udev/input_id", F_OK) == 0)             // there is /lib/udev/input_id
121                 {
122                         query_cmd_type = 1;
123                 }
124                 else    // there is not /lib/udev/input_id
125                 {
126                         query_cmd_type = 2;
127                 }
128         }
129
130         // make command string
131         if(query_cmd_type == 1)
132         {
133                 sprintf(command, "/lib/udev/input_id /class/input/%s", inputname);
134         }
135         else
136         {
137                 sprintf(command, "udevadm info --name=input/%s --query=property", inputname);
138         }
139
140         // run command
141         cmd_fp = popen(command, "r");
142         _file_read(cmd_fp, buffer, BUF_SIZE);
143
144         // determine input id
145         if(strstr(buffer, INPUT_ID_STR_KEY))                    // key
146         {
147                 ret = INPUT_ID_KEY;
148         }
149         else if(strstr(buffer, INPUT_ID_STR_TOUCH))             // touch
150         {
151                 ret = INPUT_ID_TOUCH;
152         }
153         else if(strstr(buffer, INPUT_ID_STR_KEYBOARD))  // keyboard
154         {
155                 ret = INPUT_ID_KEY;
156         }
157         else if(strstr(buffer, INPUT_ID_STR_TABLET))    // touch (emulator)
158         {
159                 ret = INPUT_ID_TOUCH;
160         }
161
162         if(cmd_fp != NULL)
163                 pclose(cmd_fp);
164         return ret;
165 }
166
167 // get filename and fd of given input type devices
168 static void _get_fds(input_dev *dev, int input_id)
169 {
170         DIR *dp;
171         struct dirent *d;
172         int count = 0;
173
174         dp = opendir("/sys/class/input");
175
176         if(dp != NULL)
177         {
178                 while((d = readdir(dp)) != NULL)
179                 {
180                         if(!strncmp(d->d_name, "event", 5))     // start with "event"
181                         {
182                                 // event file
183                                 if(input_id == get_input_id(d->d_name))
184                                 {
185                                         sprintf(dev[count].fileName, "/dev/input/%s", d->d_name);
186                                         dev[count].fd = open(dev[count].fileName, O_RDWR | O_NONBLOCK);
187                                         count++;
188                                 }
189                         }
190                 }
191
192                 closedir(dp);
193         }
194         dev[count].fd = ARRAY_END;      // end of input_dev array
195 }
196
197 static void _device_write(input_dev *dev, struct input_event* in_ev)
198 {
199         int i;
200         for(i = 0; dev[i].fd != ARRAY_END; i++)
201         {
202                 if(dev[i].fd >= 0)
203                         write(dev[i].fd, in_ev, sizeof(struct input_event));
204         }
205 }
206
207 long long get_total_alloc_size()
208 {
209         int i;
210         long long allocsize = 0;
211
212         for(i = 0; i < MAX_TARGET_COUNT; i++)
213         {
214                 if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0)
215                         allocsize += manager.target[i].allocmem;
216         }
217         return allocsize;
218 }
219
220 static int getEmptyTargetSlot()
221 {
222         int i;
223         for(i = 0; i < MAX_TARGET_COUNT; i++)
224         {
225                 if(manager.target[i].socket == -1)
226                         break;
227         }
228
229         return i;
230 }
231
232 static void setEmptyTargetSlot(int index)
233 {
234         if(index >= 0 && index < MAX_TARGET_COUNT)
235         {
236                 manager.target[index].pid = -1;
237                 manager.target[index].recv_thread = -1;
238                 manager.target[index].allocmem = 0;
239                 manager.target[index].starttime = 0;
240                 manager.target[index].initial_log = 0;
241                 if(manager.target[index].event_fd != -1)
242                         close(manager.target[index].event_fd);
243                 manager.target[index].event_fd = -1;
244                 if(manager.target[index].socket != -1)
245                         close(manager.target[index].socket);
246                 manager.target[index].socket = -1;
247         }
248 }
249
250 // ======================================================================================
251 // send functions to host
252 // ======================================================================================
253
254 int pseudoSendDataToHost(struct msg_data_t* log)
255 {
256         struct timeval time;
257         uint32_t total_len = MSG_DATA_HDR_LEN;
258
259 /*      char *buf = malloc(total_len+log->len);
260         char *p = buf;
261         memset(p,0,total_len);
262
263         pack_int(p,log->id);
264         pack_int(p,log->seq_num);
265         pack_int(p,log->sec);
266         pack_int(p,log->usec);
267
268         pack_int(p,log->len);
269
270         memcpy(p,log->payload,log->len);
271         */
272         printBuf(log,total_len+log->len);
273         if (event_fd >0){
274                 write(event_fd, log, total_len+log->len);
275         }
276 /*      free(buf);*/
277
278         return 0;
279 }
280
281 int sendDataToHost(msg_t* log)
282 {
283         if (manager.host.data_socket != -1)
284         {
285                 char logstr[DA_MSG_MAX];
286                 int loglen;
287
288                 if(log->length != 0)
289                         loglen = sprintf(logstr, "%d|%d|%s\n", log->type, log->length + 1, log->data);
290                 else
291                         loglen = sprintf(logstr, "%d|%d|\n", log->type, log->length + 1);
292
293 //              loglen = sprintf(logstr, "%d|%s\n", log->type, log->data);
294
295                 pthread_mutex_lock(&(manager.host.data_socket_mutex));
296                 send(manager.host.data_socket, logstr, loglen, MSG_NOSIGNAL);
297                 pthread_mutex_unlock(&(manager.host.data_socket_mutex));
298                 return 0;
299         }
300         else
301                 return 1;
302 }
303
304 // msgstr can be NULL
305 static int sendACKStrToHost(enum HostMessageType resp, char* msgstr)
306 {
307         if (manager.host.control_socket != -1)
308         {
309                 char logstr[DA_MSG_MAX];
310                 int loglen;
311
312                 if(msgstr != NULL)
313                         loglen = sprintf(logstr, "%d|%d|%s", (int)resp, strlen(msgstr), msgstr);
314                 else
315                         loglen = sprintf(logstr, "%d|0|", (int)resp);
316
317                 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
318                 return 0;
319         }
320         else
321                 return 1;
322 }
323
324
325
326 static int sendACKCodeToHost(enum HostMessageType resp, int msgcode)
327 {
328         // FIXME:
329         //disabled string protocol
330         return 0;
331         if (manager.host.control_socket != -1)
332         {
333                 char codestr[16];
334                 char logstr[DA_MSG_MAX];
335                 int loglen, codelen;
336
337                 codelen = sprintf(codestr, "%d", msgcode);
338                 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr);
339
340                 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
341                 return 0;
342         }
343         else
344                 return 1;
345 }
346
347 // ========================================================================================
348 // start and terminate control functions
349 // ========================================================================================
350
351 int startProfiling(long launchflag)
352 {
353         const struct app_info_t *app_info = &prof_session.app_info;
354
355         // remove previous screen capture files
356         remove_indir(SCREENSHOT_DIR);
357         mkdir(SCREENSHOT_DIR, 0777);
358 #ifndef LOCALTEST
359         smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
360 #endif
361         manager.config_flag = launchflag;
362
363         if (samplingStart() < 0)
364                 return -1;
365
366         switch (app_info->app_type) {
367         case APP_TYPE_TIZEN:
368                 if (exec_app_tizen(app_info->app_id, app_info->exe_path)) {
369                         LOGE("Cannot exec tizen app %s\n", app_info->app_id);
370                         samplingStop();
371                         return -1;
372                 }
373                 break;
374         case APP_TYPE_RUNNING:
375                 // TODO: nothing, it's running
376                 break;
377         case APP_TYPE_COMMON:
378                 if (exec_app_common(app_info->exe_path)) {
379                         LOGE("Cannot exec common app %s\n", app_info->exe_path);
380                         samplingStop();
381                         return -1;
382                 }
383                 break;
384         default:
385                 LOGE("Unknown app type %d\n", app_info->app_type);
386                 samplingStop();
387                 return -1;
388                 break;
389         }
390
391         return 0;
392 }
393
394 // terminate single target
395 // just send stop message to target process
396 static void terminate_target(int index)
397 {
398         ssize_t sendlen;
399         msg_t sendlog;
400         sendlog.type = MSG_STOP;
401         sendlog.length = 0;
402
403         if(manager.target[index].socket != -1)
404         {
405                 // result of sending to disconnected socket is not expected
406                 sendlen = send(manager.target[index].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
407                 if(sendlen != -1)
408                 {
409                         LOGI("TERMINATE send exit msg (socket %d) by terminate_target()\n", manager.target[index].socket);
410                 }
411         }
412 }
413
414 // just send stop message to all target process
415 static void terminate_all_target()
416 {
417         int i;
418         ssize_t sendlen;
419         msg_t sendlog;
420
421         sendlog.type = MSG_STOP;
422         sendlog.length = 0;
423
424         for (i = 0; i < MAX_TARGET_COUNT; i++)
425         {
426                 if(manager.target[i].socket != -1)
427                 {
428                         sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
429                         if(sendlen != -1)
430                         {
431                                 LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket);
432                         }
433                 }
434         }
435 }
436
437 // terminate all target and wait for threads
438 void terminate_all()
439 {
440         int i;
441         terminate_all_target();
442         samplingStop();
443
444         // wait for all other thread exit
445         for(i = 0; i < MAX_TARGET_COUNT; i++)
446         {
447                 if(manager.target[i].recv_thread != -1)
448                 {
449                         pthread_join(manager.target[i].recv_thread, NULL);
450                 }
451         }
452 }
453
454 // terminate all profiling by critical error
455 static void terminate_error(char* errstr, int sendtohost)
456 {
457         msg_t log;
458
459         LOGE("TERMINATE ERROR: %s\n", errstr);
460         if(sendtohost)
461         {
462                 log.type = MSG_ERROR;
463                 log.length = sprintf(log.data, "%s", errstr);
464                 sendDataToHost(&log);
465         }
466
467         terminate_all();
468 }
469
470 // ===========================================================================================
471 // message parsing and handling functions
472 // ===========================================================================================
473
474 static int parseDeviceMessage(msg_t* log)
475 {
476         char eventType[MAX_FILENAME];
477         struct input_event in_ev;
478         int i, index;
479
480         if(log == NULL)
481                 return -1;
482
483         eventType[0] = '\0';
484         in_ev.type = 0;
485         in_ev.code = 0;
486         in_ev.value = 0;
487
488         index = 0;
489         for(i = 0; i < log->length; i++)
490         {
491                 if(log->data[i] == '\n')
492                         break;
493
494                 if(log->data[i] == '`') // meet separate
495                 {
496                         i++;
497                         index++;
498                         continue;
499                 }
500
501                 if(index == 0)          // parse eventType
502                 {
503                         eventType[i] = log->data[i];
504                         eventType[i+1] = '\0';
505                 }
506                 else if(index == 1)     // parse in_ev.type
507                 {
508                         in_ev.type = in_ev.type * 10 + (log->data[i] - '0');
509                 }
510                 else if(index == 2)     // parse in_ev.code
511                 {
512                         in_ev.code = in_ev.code * 10 + (log->data[i] - '0');
513                 }
514                 else if(index == 3)     // parse in_ev.value
515                 {
516                         in_ev.value = in_ev.value * 10 + (log->data[i] - '0');
517                 }
518         }
519
520         if(index != 3)
521                 return -1;      // parse error
522
523         if(0 == strncmp(eventType, STR_TOUCH, strlen(STR_TOUCH)))
524         {
525                 _device_write(g_touch_dev, &in_ev);
526         }
527         else if(0 == strncmp(eventType, STR_KEY, strlen(STR_KEY)))
528         {
529                 _device_write(g_key_dev, &in_ev);
530         }
531
532         return 0;
533 }
534
535 // return 0 if normal case
536 // return plus value if non critical error occur
537 // return minus value if critical error occur
538 static int _hostMessageHandler(int efd,struct msg_t* log)
539 {
540 /*      int ret = 0; */
541         
542 /*      long flag = 0; */
543 /*      char *barloc, *tmploc; */
544 /*      char execPath[PATH_MAX]; */
545
546 /*      if (log == NULL) */
547 /*              return 1; */
548
549 /*      switch (log->type) */
550 /*      { */
551 /*      case MSG_REPLAY: */
552 /*              sendACKStrToHost(MSG_OK, NULL); */
553 /*              parseDeviceMessage(log); */
554 /*              break; */
555 /*      case MSG_VERSION: */
556 /*              if(strcmp(PROTOCOL_VERSION, log->data) != 0) */
557 /*              { */
558 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_PROTOCOL_VERSION); */
559 /*              } */
560 /*              else */
561 /*              { */
562 /*                      sendACKStrToHost(MSG_OK, NULL); */
563 /*              } */
564 /*              break; */
565 /*      case MSG_START: */
566 /*              LOGI("MSG_START handling : %s\n", log->data); */
567 /*              if(log->length == 0) */
568 /*              { */
569 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */
570 /*                      return -1;              // wrong message format */
571 /*              } */
572
573 /*              // parsing for host start status */
574 /*              tmploc  = log->data; */
575 /*              barloc = strchr(tmploc, '|'); */
576 /*              if(barloc == NULL) */
577 /*              { */
578 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */
579 /*                      return -1;              // wrong message format */
580 /*              } */
581
582 /*              // parsing for target launch option flag */
583 /*              tmploc = barloc + 1; */
584 /*              barloc = strchr(tmploc, '|'); */
585 /*              if(barloc != NULL) */
586 /*              { */
587 /*                      while(tmploc < barloc) */
588 /*                      { */
589 /*                              flag = (flag * 10) + (*tmploc - '0'); */
590 /*                              tmploc++; */
591 /*                      } */
592 /*              } */
593 /*              else */
594 /*              { */
595 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */
596 /*                      return -1;      // wrong message format */
597 /*              } */
598 /*              LOGI("launch flag : %lx\n", flag); */
599
600 /*              // parsing for application package name */
601 /*              tmploc = barloc + 1; */
602 /*              strcpy(manager.appPath, tmploc); */
603
604 /*              get_executable(manager.appPath, execPath, PATH_MAX); // get exact app executable file name */
605 /*              LOGI("executable app path %s\n", manager.appPath); */
606
607 /* #ifdef RUN_APP_LOADER */
608 /*              kill_app(manager.appPath); */
609 /* #else */
610 /*              kill_app(execPath); */
611 /* #endif */
612
613 /*              { */
614 /*                      char command[PATH_MAX]; */
615 /*                      struct epoll_event ev; */
616
617 /*                      //save app install path */
618 /*                      mkdir(DA_WORK_DIR, 0775); */
619 /*                      sprintf(command, */
620 /*                                      "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH, */
621 /*                                      execPath, DA_INSTALL_PATH); */
622 /*                      LOGI("appInstallCommand %s\n", command); */
623 /*                      system(command); */
624
625 /*                      sprintf(command, */
626 /*                                      "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH, */
627 /*                                      execPath, DA_BUILD_OPTION); */
628 /*                      LOGI("appInstallCommand %s\n", command); */
629 /*                      system(command); */
630
631 /*                      if(startProfiling(flag) < 0) */
632 /*                      { */
633 /*                              sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING); */
634 /*                              return -1; */
635 /*                      } */
636
637 /*                      manager.app_launch_timerfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC); */
638 /*                      if(manager.app_launch_timerfd > 0) */
639 /*                      { */
640 /*                              struct itimerspec ctime; */
641 /*                              ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME; */
642 /*                              ctime.it_value.tv_nsec = 0; */
643 /*                              ctime.it_interval.tv_sec = 0; */
644 /*                              ctime.it_interval.tv_nsec = 0; */
645 /*                              if(0 > timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL)) */
646 /*                              { */
647 /*                                      LOGE("fail to set app launch timer\n"); */
648 /*                                      close(manager.app_launch_timerfd); */
649 /*                                      manager.app_launch_timerfd = -1; */
650 /*                              } */
651 /*                              else */
652 /*                              { */
653 /*                                      // add event fd to epoll list */
654 /*                                      ev.events = EPOLLIN; */
655 /*                                      ev.data.fd = manager.app_launch_timerfd; */
656 /*                                      if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.app_launch_timerfd, &ev) < 0) */
657 /*                                      { */
658 /*                                              // fail to add event fd */
659 /*                                              LOGE("fail to add app launch timer fd to epoll list\n"); */
660 /*                                              close(manager.app_launch_timerfd); */
661 /*                                              manager.app_launch_timerfd = -1; */
662 /*                                      } */
663 /*                              } */
664 /*                      } */
665 /*              } */
666 /*              sendACKStrToHost(MSG_OK, NULL); */
667 /*              break; */
668 /*      case MSG_STOP: */
669 /*              LOGI("MSG_STOP handling\n"); */
670 /*              sendACKStrToHost(MSG_OK, NULL); */
671 /*              terminate_all(); */
672 /*              break; */
673 /*      case MSG_OPTION: */
674 /*              if(log->length > 0) */
675 /*              { */
676 /*                      int i; */
677 /*                      msg_t sendlog; */
678 /*                      manager.config_flag = atoi(log->data); */
679 /*                      sendACKStrToHost(MSG_OK, NULL); */
680
681 /*                      LOGI("MSG_OPTION : str(%s), flag(%x)\n", log->data, manager.config_flag); */
682
683 /*                      sendlog.type = MSG_OPTION; */
684 /*                      sendlog.length = sprintf(sendlog.data, "%u", manager.config_flag); */
685
686 /*                      for(i = 0; i < MAX_TARGET_COUNT; i++) */
687 /*                      { */
688 /*                              if(manager.target[i].socket != -1) */
689 /*                              { */
690 /*                                      send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length, MSG_NOSIGNAL); */
691 /*                              } */
692 /*                      } */
693 /*              } */
694 /*              else */
695 /*              { */
696 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */
697 /*                      ret = 1; */
698 /*              } */
699 /*              break; */
700 /*      case MSG_ISALIVE: */
701 /*              sendACKStrToHost(MSG_OK, NULL); */
702 /*              break; */
703 /*      default: */
704 /*              LOGW("Unknown msg\n"); */
705 /*              sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_TYPE); */
706 /*              ret = 1; */
707 /*              break; */
708 /*      } */
709 /*      return ret; */
710 }
711
712 // ========================================================================================
713 // socket and event_fd handling functions
714 // ========================================================================================
715
716 // return 0 if normal case
717 // return plus value if non critical error occur
718 // return minus value if critical error occur
719 static int deviceEventHandler(input_dev* dev, int input_type)
720 {
721         int ret = 0;
722         struct input_event in_ev;
723         msg_t log;
724
725         if(input_type == INPUT_ID_TOUCH)
726         {
727                 //touch read
728                 read(dev->fd, &in_ev, sizeof(struct input_event));
729                 log.type = MSG_RECORD;
730                 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
731                                 STR_TOUCH, dev->fileName, in_ev.time.tv_sec,
732                                 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
733                 sendDataToHost(&log);
734         }
735         else if(input_type == INPUT_ID_KEY)
736         {
737                 //key read
738                 read(dev->fd, &in_ev, sizeof(struct input_event));
739                 log.type = MSG_RECORD;
740                 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
741                                 STR_KEY, dev->fileName, in_ev.time.tv_sec,
742                                 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
743                 sendDataToHost(&log);
744         }
745         else
746         {
747                 LOGW("unknown input_type\n");
748                 ret = 1;
749         }
750
751         return ret;
752 }
753
754 #define MAX_EVENTS_NUM 10
755 static int deviceEventHandlerNew(input_dev* dev, int input_type)
756 {
757         int ret = 0;
758         ssize_t size = 0;
759         int count = 0;
760         struct input_event in_ev[MAX_EVENTS_NUM];
761         struct msg_data_t *log;
762
763         if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
764         {
765                 do {
766 //                      LOGI(">read %s events\n,", input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH);
767                         size = read(dev->fd, &in_ev[count], sizeof(*in_ev) );
768 //                      LOGI("<read %s events : size = %d\n,", input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH,size);
769                         if (size >0)
770                                 count++;
771                 } while (count < MAX_EVENTS_NUM && size > 0);
772
773                 if(count != 0){
774                         LOGI("readed %d %s events\n", count, input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH);
775                         log = gen_message_event(in_ev,count,input_type);
776                         pseudoSendDataToHost(log);
777                         reset_data_msg(log);
778                 }
779         }
780         else
781         {
782                 LOGW("unknown input_type\n");
783                 ret = 1;
784         }
785 /*
786         if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
787         {
788
789                 if (size = read(dev->fd, &in_ev, sizeof(in_ev) ) !=0 )
790                 {
791                         LOGI("readed %d touch events\n,", 1);
792                         gen_message_event(&log,&in_ev,1,input_type);
793                         pseudoSendDataToHost(&log);
794                 }
795         }
796         else
797         {
798                 LOGW("unknown input_type\n");
799                 ret = 1;
800         }
801 */
802         return ret;
803 }
804
805 // return 0 if normal case
806 // return plus value if non critical error occur
807 // return minus value if critical error occur
808 // return -11 if all target process closed
809 static int targetEventHandler(int epollfd, int index, uint64_t msg)
810 {
811         if(msg & EVENT_PID)
812         {
813                 manager.target[index].initial_log = 1;
814         }
815
816         if(msg & EVENT_STOP || msg & EVENT_ERROR)
817         {
818                 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
819                                 manager.target[index].socket, manager.target[index].pid, manager.target_count - 1);
820
821                 terminate_target(index);
822                 epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
823                 setEmptyTargetSlot(index);
824                 if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) // all target client are closed
825                         return -11;
826         }
827
828         return 0;
829 }
830
831 // return 0 if normal case
832 // return plus value if non critical error occur
833 // return minus value if critical error occur
834 static int targetServerHandler(int efd)
835 {
836         msg_t log;
837         struct epoll_event ev;
838
839         int index = getEmptyTargetSlot();
840         if(index == MAX_TARGET_COUNT)
841         {
842                 LOGW("Max target number(8) reached, no more target can connected\n");
843                 return 1;
844         }
845
846         manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL);
847
848         if(manager.target[index].socket >= 0)   // accept succeed
849         {
850 #ifndef LOCALTEST
851                 // set smack attribute for certification
852                 fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
853                 fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
854 #endif /* LOCALTEST */
855
856                 // send config message to target process
857                 log.type = MSG_OPTION;
858                 log.length = sprintf(log.data, "%u", manager.config_flag);
859                 send(manager.target[index].socket, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_NOSIGNAL);
860
861                 // make event fd
862                 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
863                 if(manager.target[index].event_fd == -1)
864                 {
865                         // fail to make event fd
866                         LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket);
867                         goto TARGET_CONNECT_FAIL;
868                 }
869
870                 // add event fd to epoll list
871                 ev.events = EPOLLIN;
872                 ev.data.fd = manager.target[index].event_fd;
873                 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
874                 {
875                         // fail to add event fd
876                         LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket);
877                         goto TARGET_CONNECT_FAIL;
878                 }
879
880                 // make recv thread for target
881                 if(makeRecvThread(index) != 0)
882                 {
883                         // fail to make recv thread
884                         LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket);
885                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
886                         goto TARGET_CONNECT_FAIL;
887                 }
888
889                 if(manager.app_launch_timerfd >= 0)
890                 {
891                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
892                         close(manager.app_launch_timerfd);
893                         manager.app_launch_timerfd = -1;
894                 }
895
896                 LOGI("target connected = %d(running %d target)\n",
897                                 manager.target[index].socket, manager.target_count + 1);
898
899                 manager.target_count++;
900                 return 0;
901         }
902         else    // accept error
903         {
904                 LOGE("Failed to accept at target server socket\n");
905         }
906
907 TARGET_CONNECT_FAIL:
908         if(manager.target_count == 0)   // if this connection is main connection
909         {
910                 return -1;
911         }
912         else    // if this connection is not main connection then ignore process by error
913         {
914                 setEmptyTargetSlot(index);
915                 return 1;
916         }
917 }
918
919 // return 0 if normal case
920 // return plus value if non critical error occur
921 // return minus value if critical error occur
922 static int hostServerHandler(int efd)
923 {
924         static int hostserverorder = 0;
925         int csocket;
926         struct epoll_event ev;
927
928         if(hostserverorder > 1) // control and data socket connected already
929                 return 1;                       // ignore
930
931         csocket = accept(manager.host_server_socket, NULL, NULL);
932
933         if(csocket >= 0)                // accept succeed
934         {
935                 ev.events = EPOLLIN;
936                 ev.data.fd = csocket;
937                 if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
938                 {
939                         // consider as accept fail
940                         LOGE("Failed to add socket fd to epoll list\n");
941                         close(csocket);
942                         return -1;
943                 }
944
945                 if(hostserverorder == 0)
946                 {
947                         manager.host.control_socket = csocket;
948                         unlink_portfile();
949                         LOGI("host control socket connected = %d\n", csocket);
950                 }
951                 else
952                 {
953                         manager.host.data_socket = csocket;
954                         LOGI("host data socket connected = %d\n", csocket);
955                 }
956
957                 hostserverorder++;
958                 return 0;
959         }
960         else    // accept error
961         {
962                 LOGE("Failed to accept from host server socket\n");
963                 return -1;
964         }
965 }
966
967
968 //TODO del it or move to debug section
969 void printBuf (char * buf, int len)
970 {
971         int i,j;
972         char local_buf[3*16 + 2*16 + 1];
973         char * p1, * p2;
974         LOGI("BUFFER:\n");
975         for ( i = 0; i < len/16 + 1; i++)
976         {
977                 memset(local_buf, ' ', 5*16);
978                 p1 = local_buf;
979                 p2 = local_buf + 3*17;
980                 for ( j = 0; j < 16; j++)
981                         if (i*16+j < len )
982                         {
983                                 sprintf(p1, "%02X ",(unsigned char) *buf);
984                                 p1+=3;
985                                 if (isprint( *buf)){
986                                         sprintf(p2, "%c ",(int)*buf);
987                                 }else{
988                                         sprintf(p2,". ");
989                                 }
990                                 p2+=2;
991                                 buf++;
992                         }
993                 *p1 = ' ';
994                 *p2 = '\0';
995                 LOGI("%s\n",local_buf);
996         }
997 }
998
999 // return 0 if normal case
1000 // return plus value if non critical error occur
1001 // return minus value if critical error occur
1002 // return -11 if socket closed
1003
1004 static int controlSocketHandler(int efd)
1005 {
1006         ssize_t recvLen;
1007         char recvBuf[DA_MSG_MAX];
1008         msg_t log;
1009
1010         // host log format xxx|length|str
1011         recvLen = recv(manager.host.control_socket, recvBuf, DA_MSG_MAX, 0);
1012
1013         if (recvLen > 0)
1014         {
1015                 recvBuf[recvLen] = '\0';
1016                 printBuf(recvBuf,recvLen);
1017                 LOGI("host sent control msg str(%s)\n", recvBuf);
1018                 if(parseHostMessage(&log, recvBuf) < 0)
1019                 {
1020                         // error to parse host message
1021                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
1022                         return 1;
1023                 }
1024
1025                 // host msg command handling
1026                 return hostMessageHandle(&log);
1027         }
1028         else    // close request from HOST
1029         {
1030                 return -11;
1031         }
1032 }
1033
1034 // return 0 for normal case
1035 int daemonLoop()
1036 {
1037         int                     ret = 0;                                // return value
1038         int                     i, k;
1039         ssize_t         recvLen;
1040
1041         struct epoll_event ev, *events;
1042         int efd;                // epoll fd
1043         int numevent;   // number of occured events
1044
1045         _get_fds(g_key_dev, INPUT_ID_KEY);
1046         _get_fds(g_touch_dev, INPUT_ID_TOUCH);
1047
1048         // initialize epoll event pool
1049         events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
1050         if(events == NULL)
1051         {
1052                 LOGE("Out of memory when allocate epoll event pool\n");
1053                 ret = -1;
1054                 goto END_RETURN;
1055         }
1056         if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
1057         {
1058                 LOGE("epoll creation error\n");
1059                 ret = -1;
1060                 goto END_EVENT;
1061         }
1062
1063         // add server sockets to epoll event pool
1064         ev.events = EPOLLIN;
1065         ev.data.fd = manager.host_server_socket;
1066         if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.host_server_socket, &ev) < 0)
1067         {
1068                 LOGE("Host server socket epoll_ctl error\n");
1069                 ret = -1;
1070                 goto END_EFD;
1071         }
1072         ev.events = EPOLLIN;
1073         ev.data.fd = manager.target_server_socket;
1074         if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target_server_socket, &ev) < 0)
1075         {
1076                 LOGE("Target server socket epoll_ctl error\n");
1077                 ret = -1;
1078                 goto END_EFD;
1079         }
1080
1081         // add device fds to epoll event pool
1082         ev.events = EPOLLIN;
1083         for(i = 0; g_key_dev[i].fd != ARRAY_END; i++)
1084         {
1085                 if(g_key_dev[i].fd >= 0)
1086                 {
1087                         ev.data.fd = g_key_dev[i].fd;
1088                         if(epoll_ctl(efd, EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0)
1089                         {
1090                                 LOGE("keyboard device file epoll_ctl error\n");
1091                         }
1092                 }
1093         }
1094
1095         ev.events = EPOLLIN;
1096         for(i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
1097         {
1098                 if(g_touch_dev[i].fd >= 0)
1099                 {
1100                         ev.data.fd = g_touch_dev[i].fd;
1101                         if(epoll_ctl(efd, EPOLL_CTL_ADD, g_touch_dev[i].fd, &ev) < 0)
1102                         {
1103                                 LOGE("touch device file epoll_ctl error\n");
1104                         }
1105                 }
1106         }
1107
1108         // handler loop
1109         while (1)
1110         {
1111                 numevent = epoll_wait(efd, events, EPOLL_SIZE, -1);
1112                 if(numevent <= 0)
1113                 {
1114                         LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
1115                         continue;
1116                 }
1117
1118                 for(i = 0; i < numevent; i++)
1119                 {
1120                         // check for request from event fd
1121                         for(k = 0; k < MAX_TARGET_COUNT; k++)
1122                         {
1123                                 if(manager.target[k].socket != -1 &&
1124                                                 events[i].data.fd == manager.target[k].event_fd)
1125                                 {
1126                                         uint64_t u;
1127                                         recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
1128                                         if(recvLen != sizeof(uint64_t))
1129                                         {
1130                                                 // maybe closed, but ignoring is more safe then removing fd from epoll list
1131                                         }
1132                                         else
1133                                         {
1134                                                 if(-11 == targetEventHandler(efd, k, u))
1135                                                 {
1136                                                         LOGI("all target process is closed\n");
1137                                                         terminate_all();
1138                                                         ret = 0;
1139                                                         goto END_EFD;
1140                                                 }
1141                                         }
1142                                         break;
1143                                 }
1144                         }
1145
1146                         if(k != MAX_TARGET_COUNT)
1147                                 continue;
1148
1149                         // check for request from device fd
1150                         for(k = 0; g_touch_dev[k].fd != ARRAY_END; k++)
1151                         {
1152                                 if(g_touch_dev[k].fd >= 0 && 
1153                                                 events[i].data.fd == g_touch_dev[k].fd)
1154                                 {
1155                                         if(deviceEventHandlerNew(&g_touch_dev[k], INPUT_ID_TOUCH) < 0)
1156                                         {
1157                                                 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1158                                                 ret = -1;
1159                                                 goto END_EFD;
1160                                         }
1161                                         break;
1162                                 }
1163                         }
1164
1165                         if(g_touch_dev[k].fd != ARRAY_END)
1166                                 continue;
1167
1168                         for(k = 0; g_key_dev[k].fd != ARRAY_END; k++)
1169                         {
1170                                 if(g_key_dev[k].fd >= 0 && 
1171                                                 events[i].data.fd == g_key_dev[k].fd)
1172                                 {
1173                                         if(deviceEventHandlerNew(&g_key_dev[k], INPUT_ID_KEY) < 0)
1174                                         {
1175                                                 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1176                                                 ret = -1;
1177                                                 goto END_EFD;
1178                                         }
1179                                         break;
1180                                 }
1181                         }
1182
1183                         if(g_key_dev[k].fd != ARRAY_END)
1184                                 continue;
1185
1186                         // connect request from target
1187                         if(events[i].data.fd == manager.target_server_socket)
1188                         {
1189                                 if(targetServerHandler(efd) < 0)        // critical error
1190                                 {
1191                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1192                                         ret = -1;
1193                                         goto END_EFD;
1194                                 }
1195                         }
1196                         // connect request from host
1197                         else if(events[i].data.fd == manager.host_server_socket)
1198                         {
1199                                 int result = hostServerHandler(efd);
1200                                 if(result < 0)
1201                                 {
1202                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1203                                         ret = -1;
1204                                         goto END_EFD;
1205                                 }
1206                         }
1207                         // control message from host
1208                         else if(events[i].data.fd == manager.host.control_socket)
1209                         {
1210                                 int result = controlSocketHandler(efd);
1211                                 if(result == -11)       // socket close
1212                                 {
1213                                         // close target and host socket and quit
1214                                         LOGI("host close = %d\n", manager.host.control_socket);
1215                                         terminate_all();
1216                                         ret = 0;
1217                                         goto END_EFD;
1218                                 }
1219                                 else if(result < 0)
1220                                 {
1221                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1222                                         ret = -1;
1223                                         goto END_EFD;
1224                                 }
1225                         }
1226                         else if(events[i].data.fd == manager.host.data_socket)
1227                         {
1228                                 char recvBuf[32];
1229                                 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1230                                 if(recvLen == 0)
1231                                 {       // close data socket
1232                                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.host.data_socket, NULL);
1233                                         close(manager.host.data_socket);
1234                                         manager.host.data_socket = -1;
1235                                 }
1236         
1237                                 LOGW("host message from data socket %d\n", recvLen);
1238                         }
1239                         // check for application launch timerfd
1240                         else if(events[i].data.fd == manager.app_launch_timerfd)
1241                         {
1242                                 // send to host timeout error message for launching application
1243                                 terminate_error("Failed to launch application", 1);
1244                                 epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
1245                                 close(manager.app_launch_timerfd);
1246                                 manager.app_launch_timerfd = -1;
1247                                 ret = -1;
1248                                 goto END_EFD;
1249                         }
1250                         // unknown socket
1251                         else
1252                         {
1253                                 // never happened
1254                                 LOGW("Unknown socket fd (%d)\n", events[i].data.fd);
1255                         }
1256                 }
1257         }
1258
1259 END_EFD:
1260         close(efd);
1261 END_EVENT:
1262         free(events);
1263 END_RETURN:
1264         return ret;
1265 }