[FIX] HOST_BUILD define chage to LOCALTEST
[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         /* uint32_t total_len = MSG_DATA_HDR_LEN; */
257
258         /* char *buf = malloc(total_len+log->len); */
259         /* char *p = buf; */
260         /* memset(p,0,total_len); */
261
262         /* pack_int(p,log->id); */
263         /* pack_int(p,log->seq_num); */
264         /* pack_time(p,log->time); */
265         /* pack_int(p,log->len); */
266
267         /* memcpy(p,log->payload,log->len); */
268         /* printBuf(buf,total_len+log->len); */
269         /* if (event_fd >0){ */
270         /*      write(event_fd, buf, total_len+log->len); */
271         /* } */
272         /* free(buf); */
273
274         return 0;
275 }
276
277 int sendDataToHost(msg_t* log)
278 {
279         if (manager.host.data_socket != -1)
280         {
281                 char logstr[DA_MSG_MAX];
282                 int loglen;
283
284                 if(log->length != 0)
285                         loglen = sprintf(logstr, "%d|%d|%s\n", log->type, log->length + 1, log->data);
286                 else
287                         loglen = sprintf(logstr, "%d|%d|\n", log->type, log->length + 1);
288
289 //              loglen = sprintf(logstr, "%d|%s\n", log->type, log->data);
290
291                 pthread_mutex_lock(&(manager.host.data_socket_mutex));
292                 send(manager.host.data_socket, logstr, loglen, MSG_NOSIGNAL);
293                 pthread_mutex_unlock(&(manager.host.data_socket_mutex));
294                 return 0;
295         }
296         else
297                 return 1;
298 }
299
300 // msgstr can be NULL
301 static int sendACKStrToHost(enum HostMessageType resp, char* msgstr)
302 {
303         if (manager.host.control_socket != -1)
304         {
305                 char logstr[DA_MSG_MAX];
306                 int loglen;
307
308                 if(msgstr != NULL)
309                         loglen = sprintf(logstr, "%d|%d|%s", (int)resp, strlen(msgstr), msgstr);
310                 else
311                         loglen = sprintf(logstr, "%d|0|", (int)resp);
312
313                 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
314                 return 0;
315         }
316         else
317                 return 1;
318 }
319
320
321
322 static int sendACKCodeToHost(enum HostMessageType resp, int msgcode)
323 {
324         // FIXME:
325         //disabled string protocol
326         return 0;
327         if (manager.host.control_socket != -1)
328         {
329                 char codestr[16];
330                 char logstr[DA_MSG_MAX];
331                 int loglen, codelen;
332
333                 codelen = sprintf(codestr, "%d", msgcode);
334                 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr);
335
336                 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
337                 return 0;
338         }
339         else
340                 return 1;
341 }
342
343 // ========================================================================================
344 // start and terminate control functions
345 // ========================================================================================
346
347 static int startProfiling(long launchflag)
348 {
349         char execPath[PATH_MAX];
350
351         // remove previous screen capture files
352         remove_indir(SCREENSHOT_DIR);
353         mkdir(SCREENSHOT_DIR, 0777);
354 #ifndef LOCALTEST
355         smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
356 #endif
357         manager.config_flag = launchflag;
358
359 #ifdef RUN_APP_LOADER
360         strcpy(execPath, manager.appPath);
361 #else
362         get_executable(manager.appPath, execPath, PATH_MAX);
363 #endif
364         if(samplingStart() < 0)
365                 return -1;
366
367         if(exec_app(execPath, get_app_type(manager.appPath)) == 0)
368         {
369                 samplingStop();
370                 return -1;
371         }
372
373         LOGI("Timer Started\n");
374
375         return 0;
376 }
377
378 // terminate single target
379 // just send stop message to target process
380 static void terminate_target(int index)
381 {
382         ssize_t sendlen;
383         msg_t sendlog;
384         sendlog.type = MSG_STOP;
385         sendlog.length = 0;
386
387         if(manager.target[index].socket != -1)
388         {
389                 // result of sending to disconnected socket is not expected
390                 sendlen = send(manager.target[index].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
391                 if(sendlen != -1)
392                 {
393                         LOGI("TERMINATE send exit msg (socket %d) by terminate_target()\n", manager.target[index].socket);
394                 }
395         }
396 }
397
398 // just send stop message to all target process
399 static void terminate_all_target()
400 {
401         int i;
402         ssize_t sendlen;
403         msg_t sendlog;
404
405         sendlog.type = MSG_STOP;
406         sendlog.length = 0;
407
408         for (i = 0; i < MAX_TARGET_COUNT; i++)
409         {
410                 if(manager.target[i].socket != -1)
411                 {
412                         sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
413                         if(sendlen != -1)
414                         {
415                                 LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket);
416                         }
417                 }
418         }
419 }
420
421 // terminate all target and wait for threads
422 static void terminate_all()
423 {
424         int i;
425         terminate_all_target();
426         samplingStop();
427
428         // wait for all other thread exit
429         for(i = 0; i < MAX_TARGET_COUNT; i++)
430         {
431                 if(manager.target[i].recv_thread != -1)
432                 {
433                         pthread_join(manager.target[i].recv_thread, NULL);
434                 }
435         }
436 }
437
438 // terminate all profiling by critical error
439 static void terminate_error(char* errstr, int sendtohost)
440 {
441         msg_t log;
442
443         LOGE("TERMINATE ERROR: %s\n", errstr);
444         if(sendtohost)
445         {
446                 log.type = MSG_ERROR;
447                 log.length = sprintf(log.data, "%s", errstr);
448                 sendDataToHost(&log);
449         }
450
451         terminate_all();
452 }
453
454 // ===========================================================================================
455 // message parsing and handling functions
456 // ===========================================================================================
457
458 static int parseDeviceMessage(msg_t* log)
459 {
460         char eventType[MAX_FILENAME];
461         struct input_event in_ev;
462         int i, index;
463
464         if(log == NULL)
465                 return -1;
466
467         eventType[0] = '\0';
468         in_ev.type = 0;
469         in_ev.code = 0;
470         in_ev.value = 0;
471
472         index = 0;
473         for(i = 0; i < log->length; i++)
474         {
475                 if(log->data[i] == '\n')
476                         break;
477
478                 if(log->data[i] == '`') // meet separate
479                 {
480                         i++;
481                         index++;
482                         continue;
483                 }
484
485                 if(index == 0)          // parse eventType
486                 {
487                         eventType[i] = log->data[i];
488                         eventType[i+1] = '\0';
489                 }
490                 else if(index == 1)     // parse in_ev.type
491                 {
492                         in_ev.type = in_ev.type * 10 + (log->data[i] - '0');
493                 }
494                 else if(index == 2)     // parse in_ev.code
495                 {
496                         in_ev.code = in_ev.code * 10 + (log->data[i] - '0');
497                 }
498                 else if(index == 3)     // parse in_ev.value
499                 {
500                         in_ev.value = in_ev.value * 10 + (log->data[i] - '0');
501                 }
502         }
503
504         if(index != 3)
505                 return -1;      // parse error
506
507         if(0 == strncmp(eventType, STR_TOUCH, strlen(STR_TOUCH)))
508         {
509                 _device_write(g_touch_dev, &in_ev);
510         }
511         else if(0 == strncmp(eventType, STR_KEY, strlen(STR_KEY)))
512         {
513                 _device_write(g_key_dev, &in_ev);
514         }
515
516         return 0;
517 }
518
519 // return 0 if normal case
520 // return plus value if non critical error occur
521 // return minus value if critical error occur
522 static int _hostMessageHandler(int efd,struct msg_t* log)
523 {
524 /*      int ret = 0; */
525         
526 /*      long flag = 0; */
527 /*      char *barloc, *tmploc; */
528 /*      char execPath[PATH_MAX]; */
529
530 /*      if (log == NULL) */
531 /*              return 1; */
532
533 /*      switch (log->type) */
534 /*      { */
535 /*      case MSG_REPLAY: */
536 /*              sendACKStrToHost(MSG_OK, NULL); */
537 /*              parseDeviceMessage(log); */
538 /*              break; */
539 /*      case MSG_VERSION: */
540 /*              if(strcmp(PROTOCOL_VERSION, log->data) != 0) */
541 /*              { */
542 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_PROTOCOL_VERSION); */
543 /*              } */
544 /*              else */
545 /*              { */
546 /*                      sendACKStrToHost(MSG_OK, NULL); */
547 /*              } */
548 /*              break; */
549 /*      case MSG_START: */
550 /*              LOGI("MSG_START handling : %s\n", log->data); */
551 /*              if(log->length == 0) */
552 /*              { */
553 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */
554 /*                      return -1;              // wrong message format */
555 /*              } */
556
557 /*              // parsing for host start status */
558 /*              tmploc  = log->data; */
559 /*              barloc = strchr(tmploc, '|'); */
560 /*              if(barloc == NULL) */
561 /*              { */
562 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */
563 /*                      return -1;              // wrong message format */
564 /*              } */
565
566 /*              // parsing for target launch option flag */
567 /*              tmploc = barloc + 1; */
568 /*              barloc = strchr(tmploc, '|'); */
569 /*              if(barloc != NULL) */
570 /*              { */
571 /*                      while(tmploc < barloc) */
572 /*                      { */
573 /*                              flag = (flag * 10) + (*tmploc - '0'); */
574 /*                              tmploc++; */
575 /*                      } */
576 /*              } */
577 /*              else */
578 /*              { */
579 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT); */
580 /*                      return -1;      // wrong message format */
581 /*              } */
582 /*              LOGI("launch flag : %lx\n", flag); */
583
584 /*              // parsing for application package name */
585 /*              tmploc = barloc + 1; */
586 /*              strcpy(manager.appPath, tmploc); */
587
588 /*              get_executable(manager.appPath, execPath, PATH_MAX); // get exact app executable file name */
589 /*              LOGI("executable app path %s\n", manager.appPath); */
590
591 /* #ifdef RUN_APP_LOADER */
592 /*              kill_app(manager.appPath); */
593 /* #else */
594 /*              kill_app(execPath); */
595 /* #endif */
596
597 /*              { */
598 /*                      char command[PATH_MAX]; */
599 /*                      struct epoll_event ev; */
600
601 /*                      //save app install path */
602 /*                      mkdir(DA_WORK_DIR, 0775); */
603 /*                      sprintf(command, */
604 /*                                      "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH, */
605 /*                                      execPath, DA_INSTALL_PATH); */
606 /*                      LOGI("appInstallCommand %s\n", command); */
607 /*                      system(command); */
608
609 /*                      sprintf(command, */
610 /*                                      "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH, */
611 /*                                      execPath, DA_BUILD_OPTION); */
612 /*                      LOGI("appInstallCommand %s\n", command); */
613 /*                      system(command); */
614
615 /*                      if(startProfiling(flag) < 0) */
616 /*                      { */
617 /*                              sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING); */
618 /*                              return -1; */
619 /*                      } */
620
621 /*                      manager.app_launch_timerfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC); */
622 /*                      if(manager.app_launch_timerfd > 0) */
623 /*                      { */
624 /*                              struct itimerspec ctime; */
625 /*                              ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME; */
626 /*                              ctime.it_value.tv_nsec = 0; */
627 /*                              ctime.it_interval.tv_sec = 0; */
628 /*                              ctime.it_interval.tv_nsec = 0; */
629 /*                              if(0 > timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL)) */
630 /*                              { */
631 /*                                      LOGE("fail to set app launch timer\n"); */
632 /*                                      close(manager.app_launch_timerfd); */
633 /*                                      manager.app_launch_timerfd = -1; */
634 /*                              } */
635 /*                              else */
636 /*                              { */
637 /*                                      // add event fd to epoll list */
638 /*                                      ev.events = EPOLLIN; */
639 /*                                      ev.data.fd = manager.app_launch_timerfd; */
640 /*                                      if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.app_launch_timerfd, &ev) < 0) */
641 /*                                      { */
642 /*                                              // fail to add event fd */
643 /*                                              LOGE("fail to add app launch timer fd to epoll list\n"); */
644 /*                                              close(manager.app_launch_timerfd); */
645 /*                                              manager.app_launch_timerfd = -1; */
646 /*                                      } */
647 /*                              } */
648 /*                      } */
649 /*              } */
650 /*              sendACKStrToHost(MSG_OK, NULL); */
651 /*              break; */
652 /*      case MSG_STOP: */
653 /*              LOGI("MSG_STOP handling\n"); */
654 /*              sendACKStrToHost(MSG_OK, NULL); */
655 /*              terminate_all(); */
656 /*              break; */
657 /*      case MSG_OPTION: */
658 /*              if(log->length > 0) */
659 /*              { */
660 /*                      int i; */
661 /*                      msg_t sendlog; */
662 /*                      manager.config_flag = atoi(log->data); */
663 /*                      sendACKStrToHost(MSG_OK, NULL); */
664
665 /*                      LOGI("MSG_OPTION : str(%s), flag(%x)\n", log->data, manager.config_flag); */
666
667 /*                      sendlog.type = MSG_OPTION; */
668 /*                      sendlog.length = sprintf(sendlog.data, "%u", manager.config_flag); */
669
670 /*                      for(i = 0; i < MAX_TARGET_COUNT; i++) */
671 /*                      { */
672 /*                              if(manager.target[i].socket != -1) */
673 /*                              { */
674 /*                                      send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length, MSG_NOSIGNAL); */
675 /*                              } */
676 /*                      } */
677 /*              } */
678 /*              else */
679 /*              { */
680 /*                      sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA); */
681 /*                      ret = 1; */
682 /*              } */
683 /*              break; */
684 /*      case MSG_ISALIVE: */
685 /*              sendACKStrToHost(MSG_OK, NULL); */
686 /*              break; */
687 /*      default: */
688 /*              LOGW("Unknown msg\n"); */
689 /*              sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_TYPE); */
690 /*              ret = 1; */
691 /*              break; */
692 /*      } */
693 /*      return ret; */
694 }
695
696 // ========================================================================================
697 // socket and event_fd handling functions
698 // ========================================================================================
699
700 // return 0 if normal case
701 // return plus value if non critical error occur
702 // return minus value if critical error occur
703 static int deviceEventHandler(input_dev* dev, int input_type)
704 {
705         int ret = 0;
706         struct input_event in_ev;
707         msg_t log;
708
709         if(input_type == INPUT_ID_TOUCH)
710         {
711                 //touch read
712                 read(dev->fd, &in_ev, sizeof(struct input_event));
713                 log.type = MSG_RECORD;
714                 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
715                                 STR_TOUCH, dev->fileName, in_ev.time.tv_sec,
716                                 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
717                 sendDataToHost(&log);
718         }
719         else if(input_type == INPUT_ID_KEY)
720         {
721                 //key read
722                 read(dev->fd, &in_ev, sizeof(struct input_event));
723                 log.type = MSG_RECORD;
724                 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
725                                 STR_KEY, dev->fileName, in_ev.time.tv_sec,
726                                 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
727                 sendDataToHost(&log);
728         }
729         else
730         {
731                 LOGW("unknown input_type\n");
732                 ret = 1;
733         }
734
735         return ret;
736 }
737
738 #define MAX_EVENTS_NUM 10
739 static int deviceEventHandlerNew(input_dev* dev, int input_type)
740 {
741         int ret = 0;
742         ssize_t size = 0;
743         int count = 0;
744         struct input_event in_ev[MAX_EVENTS_NUM];
745         struct msg_data_t log;
746
747         if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
748         {
749                 do {
750 //                      LOGI(">read %s events\n,", input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH);
751                         size = read(dev->fd, &in_ev[count], sizeof(*in_ev) );
752 //                      LOGI("<read %s events : size = %d\n,", input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH,size);
753                         if (size >0)
754                                 count++;
755                 } while (count < MAX_EVENTS_NUM && size > 0);
756
757                 if(count != 0){
758                         LOGI("readed %d %s events\n,", count, input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH);
759                         /* gen_message_event(&log,&in_ev[0],count,input_type); */
760                         pseudoSendDataToHost(&log);
761                         reset_data_msg(&log);
762                 }
763         }
764         else
765         {
766                 LOGW("unknown input_type\n");
767                 ret = 1;
768         }
769 /*
770         if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
771         {
772
773                 if (size = read(dev->fd, &in_ev, sizeof(in_ev) ) !=0 )
774                 {
775                         LOGI("readed %d touch events\n,", 1);
776                         gen_message_event(&log,&in_ev,1,input_type);
777                         pseudoSendDataToHost(&log);
778                 }
779         }
780         else
781         {
782                 LOGW("unknown input_type\n");
783                 ret = 1;
784         }
785 */
786         return ret;
787 }
788
789 // return 0 if normal case
790 // return plus value if non critical error occur
791 // return minus value if critical error occur
792 // return -11 if all target process closed
793 static int targetEventHandler(int epollfd, int index, uint64_t msg)
794 {
795         msg_t log;
796
797         if(msg & EVENT_PID)
798         {
799                 if(index == 0)          // assume index 0 is main application process
800                 {
801                         int base_address;
802                         char tempBuff[DA_MSG_MAX];
803                         char tempBuff2[DA_MSG_MAX];
804                         char tempPath[PATH_MAX];
805
806                         get_executable(manager.appPath, tempPath, PATH_MAX);
807                         if(realpath(tempPath, tempBuff) == NULL)
808                         {
809                                 LOGW("Failed to get realpath of app\n");
810                                 strcpy(tempBuff, tempPath);
811                         }
812
813                         sprintf(tempPath, "/proc/%d/maps", manager.target[index].pid);
814                         sprintf(tempBuff2, "cat %s | grep %s | cut -d\"-\" -f1 > %s",
815                                         tempPath, tempBuff, DA_BASE_ADDRESS);
816                         LOGI("base address command is %s\n", tempBuff2);
817
818                         do {
819                                 if(access(tempPath, F_OK) != 0)
820                                         return -1;
821                                 if(is_same_app_process(manager.appPath, manager.target[index].pid) == 0)
822                                         return -1;
823
824                                 system(tempBuff2);
825                                 if(get_app_base_address(&base_address) == 1)
826                                         break;
827                                 sleep(0);
828                         } while(1);
829
830                         tempPath[0] = '\0';
831                         get_app_install_path(tempPath, PATH_MAX);
832
833 #ifndef LOCALTEST
834                         get_device_info(tempBuff, DA_MSG_MAX);
835 #endif
836
837                         log.type = MSG_DEVICE;
838                         if (strlen(tempPath) > 0)
839                         {
840                                 get_executable(manager.appPath, tempBuff2, DA_MSG_MAX);
841                                 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,%s/%s", tempBuff,
842                                                 manager.target[index].pid, manager.target[index].starttime,
843                                                 is_app_built_pie(), base_address, get_app_type(manager.appPath),
844                                                 tempPath, get_app_name(tempBuff2));
845                         }
846                         else
847                         {
848                                 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,", tempBuff,
849                                                 manager.target[index].pid, manager.target[index].starttime,
850                                                 is_app_built_pie(), base_address, get_app_type(manager.appPath));
851                         }
852
853                         LOGI("%s\n", log.data);
854                 }
855                 else
856                 {
857                         log.type = MSG_PID;
858                         log.length = sprintf(log.data, "%d`,%Lu", manager.target[index].pid, manager.target[index].starttime);
859                 }
860
861                 sendDataToHost(&log);
862                 manager.target[index].initial_log = 1;
863         }
864
865         if(msg & EVENT_STOP || msg & EVENT_ERROR)
866         {
867                 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
868                                 manager.target[index].socket, manager.target[index].pid, manager.target_count - 1);
869
870                 terminate_target(index);
871                 epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
872                 setEmptyTargetSlot(index);
873                 if (0 == __sync_sub_and_fetch(&manager.target_count, 1))        // all target client are closed
874                 {
875                         log.type = MSG_TERMINATE;
876                         log.length = 0;
877                         log.data[0] = '\0';
878                         sendDataToHost(&log);
879                         return -11;
880                 }
881         }
882
883         return 0;
884 }
885
886 // return 0 if normal case
887 // return plus value if non critical error occur
888 // return minus value if critical error occur
889 static int targetServerHandler(int efd)
890 {
891         msg_t log;
892         struct epoll_event ev;
893
894         int index = getEmptyTargetSlot();
895         if(index == MAX_TARGET_COUNT)
896         {
897                 LOGW("Max target number(8) reached, no more target can connected\n");
898                 return 1;
899         }
900
901         manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL);
902
903         if(manager.target[index].socket >= 0)   // accept succeed
904         {
905 #ifndef LOCALTEST
906                 // set smack attribute for certification
907                 fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
908                 fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
909 #endif /* LOCALTEST */
910
911                 // send config message to target process
912                 log.type = MSG_OPTION;
913                 log.length = sprintf(log.data, "%u", manager.config_flag);
914                 send(manager.target[index].socket, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_NOSIGNAL);
915
916                 // make event fd
917                 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
918                 if(manager.target[index].event_fd == -1)
919                 {
920                         // fail to make event fd
921                         LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket);
922                         goto TARGET_CONNECT_FAIL;
923                 }
924
925                 // add event fd to epoll list
926                 ev.events = EPOLLIN;
927                 ev.data.fd = manager.target[index].event_fd;
928                 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
929                 {
930                         // fail to add event fd
931                         LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket);
932                         goto TARGET_CONNECT_FAIL;
933                 }
934
935                 // make recv thread for target
936                 if(makeRecvThread(index) != 0)
937                 {
938                         // fail to make recv thread
939                         LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket);
940                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
941                         goto TARGET_CONNECT_FAIL;
942                 }
943
944                 if(manager.app_launch_timerfd >= 0)
945                 {
946                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
947                         close(manager.app_launch_timerfd);
948                         manager.app_launch_timerfd = -1;
949                 }
950
951                 LOGI("target connected = %d(running %d target)\n",
952                                 manager.target[index].socket, manager.target_count + 1);
953
954                 manager.target_count++;
955                 return 0;
956         }
957         else    // accept error
958         {
959                 LOGE("Failed to accept at target server socket\n");
960         }
961
962 TARGET_CONNECT_FAIL:
963         if(manager.target_count == 0)   // if this connection is main connection
964         {
965                 return -1;
966         }
967         else    // if this connection is not main connection then ignore process by error
968         {
969                 setEmptyTargetSlot(index);
970                 return 1;
971         }
972 }
973
974 // return 0 if normal case
975 // return plus value if non critical error occur
976 // return minus value if critical error occur
977 static int hostServerHandler(int efd)
978 {
979         static int hostserverorder = 0;
980         int csocket;
981         struct epoll_event ev;
982
983         if(hostserverorder > 1) // control and data socket connected already
984                 return 1;                       // ignore
985
986         csocket = accept(manager.host_server_socket, NULL, NULL);
987
988         if(csocket >= 0)                // accept succeed
989         {
990                 ev.events = EPOLLIN;
991                 ev.data.fd = csocket;
992                 if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
993                 {
994                         // consider as accept fail
995                         LOGE("Failed to add socket fd to epoll list\n");
996                         close(csocket);
997                         return -1;
998                 }
999
1000                 if(hostserverorder == 0)
1001                 {
1002                         manager.host.control_socket = csocket;
1003                         unlink_portfile();
1004                         LOGI("host control socket connected = %d\n", csocket);
1005                 }
1006                 else
1007                 {
1008                         manager.host.data_socket = csocket;
1009                         LOGI("host data socket connected = %d\n", csocket);
1010                 }
1011
1012                 hostserverorder++;
1013                 return 0;
1014         }
1015         else    // accept error
1016         {
1017                 LOGE("Failed to accept from host server socket\n");
1018                 return -1;
1019         }
1020 }
1021
1022
1023 //TODO del it or move to debug section
1024 void printBuf (char * buf, int len)
1025 {
1026         int i,j;
1027         char local_buf[3*16 + 2*16 + 1];
1028         char * p1, * p2;
1029         LOGI("BUFFER:\n");
1030         for ( i = 0; i < len/16 + 1; i++)
1031         {
1032                 memset(local_buf, ' ', 5*16);
1033                 p1 = local_buf;
1034                 p2 = local_buf + 3*17;
1035                 for ( j = 0; j < 16; j++)
1036                         if (i*16+j < len )
1037                         {
1038                                 sprintf(p1, "%02X ",(unsigned char) *buf);
1039                                 p1+=3;
1040                                 if (isprint( *buf)){
1041                                         sprintf(p2, "%c ",(int)*buf);
1042                                 }else{
1043                                         sprintf(p2,". ");
1044                                 }
1045                                 p2+=2;
1046                                 buf++;
1047                         }
1048                 *p1 = ' ';
1049                 *p2 = '\0';
1050                 LOGI("%s\n",local_buf);
1051         }
1052 }
1053
1054 // return 0 if normal case
1055 // return plus value if non critical error occur
1056 // return minus value if critical error occur
1057 // return -11 if socket closed
1058
1059 static int controlSocketHandler(int efd)
1060 {
1061         ssize_t recvLen;
1062         char recvBuf[DA_MSG_MAX];
1063         msg_t log;
1064
1065         // host log format xxx|length|str
1066         recvLen = recv(manager.host.control_socket, recvBuf, DA_MSG_MAX, 0);
1067
1068         if (recvLen > 0)
1069         {
1070                 recvBuf[recvLen] = '\0';
1071                 printBuf(recvBuf,recvLen);
1072                 LOGI("host sent control msg str(%s)\n", recvBuf);
1073                 if(parseHostMessage(&log, recvBuf) < 0)
1074                 {
1075                         // error to parse host message
1076                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
1077                         return 1;
1078                 }
1079
1080                 // host msg command handling
1081                 return hostMessageHandle(&log);
1082         }
1083         else    // close request from HOST
1084         {
1085                 return -11;
1086         }
1087 }
1088
1089 // return 0 for normal case
1090 int daemonLoop()
1091 {
1092         int                     ret = 0;                                // return value
1093         int                     i, k;
1094         ssize_t         recvLen;
1095
1096         struct epoll_event ev, *events;
1097         int efd;                // epoll fd
1098         int numevent;   // number of occured events
1099
1100         _get_fds(g_key_dev, INPUT_ID_KEY);
1101         _get_fds(g_touch_dev, INPUT_ID_TOUCH);
1102
1103         // initialize epoll event pool
1104         events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
1105         if(events == NULL)
1106         {
1107                 LOGE("Out of memory when allocate epoll event pool\n");
1108                 ret = -1;
1109                 goto END_RETURN;
1110         }
1111         if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
1112         {
1113                 LOGE("epoll creation error\n");
1114                 ret = -1;
1115                 goto END_EVENT;
1116         }
1117
1118         // add server sockets to epoll event pool
1119         ev.events = EPOLLIN;
1120         ev.data.fd = manager.host_server_socket;
1121         if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.host_server_socket, &ev) < 0)
1122         {
1123                 LOGE("Host server socket epoll_ctl error\n");
1124                 ret = -1;
1125                 goto END_EFD;
1126         }
1127         ev.events = EPOLLIN;
1128         ev.data.fd = manager.target_server_socket;
1129         if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target_server_socket, &ev) < 0)
1130         {
1131                 LOGE("Target server socket epoll_ctl error\n");
1132                 ret = -1;
1133                 goto END_EFD;
1134         }
1135
1136         // add device fds to epoll event pool
1137         ev.events = EPOLLIN;
1138         for(i = 0; g_key_dev[i].fd != ARRAY_END; i++)
1139         {
1140                 if(g_key_dev[i].fd >= 0)
1141                 {
1142                         ev.data.fd = g_key_dev[i].fd;
1143                         if(epoll_ctl(efd, EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0)
1144                         {
1145                                 LOGE("keyboard device file epoll_ctl error\n");
1146                         }
1147                 }
1148         }
1149
1150         ev.events = EPOLLIN;
1151         for(i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
1152         {
1153                 if(g_touch_dev[i].fd >= 0)
1154                 {
1155                         ev.data.fd = g_touch_dev[i].fd;
1156                         if(epoll_ctl(efd, EPOLL_CTL_ADD, g_touch_dev[i].fd, &ev) < 0)
1157                         {
1158                                 LOGE("touch device file epoll_ctl error\n");
1159                         }
1160                 }
1161         }
1162
1163         // handler loop
1164         while (1)
1165         {
1166                 numevent = epoll_wait(efd, events, EPOLL_SIZE, -1);
1167                 if(numevent <= 0)
1168                 {
1169                         LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
1170                         continue;
1171                 }
1172
1173                 for(i = 0; i < numevent; i++)
1174                 {
1175                         // check for request from event fd
1176                         for(k = 0; k < MAX_TARGET_COUNT; k++)
1177                         {
1178                                 if(manager.target[k].socket != -1 &&
1179                                                 events[i].data.fd == manager.target[k].event_fd)
1180                                 {
1181                                         uint64_t u;
1182                                         recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
1183                                         if(recvLen != sizeof(uint64_t))
1184                                         {
1185                                                 // maybe closed, but ignoring is more safe then removing fd from epoll list
1186                                         }
1187                                         else
1188                                         {
1189                                                 if(-11 == targetEventHandler(efd, k, u))
1190                                                 {
1191                                                         LOGI("all target process is closed\n");
1192                                                         terminate_all();
1193                                                         ret = 0;
1194                                                         goto END_EFD;
1195                                                 }
1196                                         }
1197                                         break;
1198                                 }
1199                         }
1200
1201                         if(k != MAX_TARGET_COUNT)
1202                                 continue;
1203
1204                         // check for request from device fd
1205                         for(k = 0; g_touch_dev[k].fd != ARRAY_END; k++)
1206                         {
1207                                 if(g_touch_dev[k].fd >= 0 && 
1208                                                 events[i].data.fd == g_touch_dev[k].fd)
1209                                 {
1210                                         if(deviceEventHandlerNew(&g_touch_dev[k], INPUT_ID_TOUCH) < 0)
1211                                         {
1212                                                 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1213                                                 ret = -1;
1214                                                 goto END_EFD;
1215                                         }
1216                                         break;
1217                                 }
1218                         }
1219
1220                         if(g_touch_dev[k].fd != ARRAY_END)
1221                                 continue;
1222
1223                         for(k = 0; g_key_dev[k].fd != ARRAY_END; k++)
1224                         {
1225                                 if(g_key_dev[k].fd >= 0 && 
1226                                                 events[i].data.fd == g_key_dev[k].fd)
1227                                 {
1228                                         if(deviceEventHandlerNew(&g_key_dev[k], INPUT_ID_KEY) < 0)
1229                                         {
1230                                                 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1231                                                 ret = -1;
1232                                                 goto END_EFD;
1233                                         }
1234                                         break;
1235                                 }
1236                         }
1237
1238                         if(g_key_dev[k].fd != ARRAY_END)
1239                                 continue;
1240
1241                         // connect request from target
1242                         if(events[i].data.fd == manager.target_server_socket)
1243                         {
1244                                 if(targetServerHandler(efd) < 0)        // critical error
1245                                 {
1246                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1247                                         ret = -1;
1248                                         goto END_EFD;
1249                                 }
1250                         }
1251                         // connect request from host
1252                         else if(events[i].data.fd == manager.host_server_socket)
1253                         {
1254                                 int result = hostServerHandler(efd);
1255                                 if(result < 0)
1256                                 {
1257                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1258                                         ret = -1;
1259                                         goto END_EFD;
1260                                 }
1261                         }
1262                         // control message from host
1263                         else if(events[i].data.fd == manager.host.control_socket)
1264                         {
1265                                 int result = controlSocketHandler(efd);
1266                                 if(result == -11)       // socket close
1267                                 {
1268                                         // close target and host socket and quit
1269                                         LOGI("host close = %d\n", manager.host.control_socket);
1270                                         terminate_all();
1271                                         ret = 0;
1272                                         goto END_EFD;
1273                                 }
1274                                 else if(result < 0)
1275                                 {
1276                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1277                                         ret = -1;
1278                                         goto END_EFD;
1279                                 }
1280                         }
1281                         else if(events[i].data.fd == manager.host.data_socket)
1282                         {
1283                                 char recvBuf[32];
1284                                 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1285                                 if(recvLen == 0)
1286                                 {       // close data socket
1287                                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.host.data_socket, NULL);
1288                                         close(manager.host.data_socket);
1289                                         manager.host.data_socket = -1;
1290                                 }
1291         
1292                                 LOGW("host message from data socket %d\n", recvLen);
1293                         }
1294                         // check for application launch timerfd
1295                         else if(events[i].data.fd == manager.app_launch_timerfd)
1296                         {
1297                                 // send to host timeout error message for launching application
1298                                 terminate_error("Failed to launch application", 1);
1299                                 epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
1300                                 close(manager.app_launch_timerfd);
1301                                 manager.app_launch_timerfd = -1;
1302                                 ret = -1;
1303                                 goto END_EFD;
1304                         }
1305                         // unknown socket
1306                         else
1307                         {
1308                                 // never happened
1309                                 LOGW("Unknown socket fd (%d)\n", events[i].data.fd);
1310                         }
1311                 }
1312         }
1313
1314 END_EFD:
1315         close(efd);
1316 END_EVENT:
1317         free(events);
1318 END_RETURN:
1319         return ret;
1320 }