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