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