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