Merge branch 'swap_protocol' of ssh://106.109.8.71/srv/git/sdk/dynamic-analysis-manag...
[platform/core/system/swap-manager.git] / daemon / daemon.c
1 /*
2 *  DA manager
3 *
4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: 
7 *
8 * Jaewon Lim <jaewon81.lim@samsung.com>
9 * Woojin Jung <woojin2.jung@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
11
12  * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 * Contributors:
25 * - S-Core Co., Ltd
26 *
27 */ 
28
29 #include <stdio.h>
30 #include <stdlib.h>                     // for realpath
31 #include <string.h>                     // for strtok, strcpy, strncpy
32 #include <limits.h>                     // for realpath
33
34 #include <errno.h>                      // for errno
35 #include <sys/types.h>          // for accept, mkdir, opendir, readdir
36 #include <sys/socket.h>         // for accept
37 #include <sys/stat.h>           // for mkdir
38 #include <sys/eventfd.h>        // for eventfd
39 #include <sys/epoll.h>          // for epoll apis
40 #include <sys/timerfd.h>        // for timerfd
41 #include <unistd.h>                     // for access, sleep
42
43 #include <ctype.h>
44
45 #ifndef LOCALTEST
46 #include <attr/xattr.h>         // for fsetxattr
47 #include <sys/smack.h>
48 #endif
49
50 #include <linux/input.h>
51 #include <dirent.h>
52 #include <fcntl.h>
53 #include "daemon.h"
54 #include "sys_stat.h"
55 #include "utils.h"
56 #include "da_protocol.h"
57 #include "da_data.h"
58 #include "debug.h"
59
60 #define DA_WORK_DIR                             "/home/developer/sdk_tools/da/"
61 #define DA_READELF_PATH                 "/home/developer/sdk_tools/da/readelf"
62 #define SCREENSHOT_DIR                  "/tmp/da"
63
64 #define EPOLL_SIZE                              10
65 #define MAX_CONNECT_SIZE                12
66 #define MAX_APP_LAUNCH_TIME             6
67
68 #define MAX_DEVICE                              10
69 #define MAX_FILENAME                    128
70 #define BUF_SIZE                                1024
71 #define ARRAY_END                               (-11)
72
73 input_dev g_key_dev[MAX_DEVICE];
74 input_dev g_touch_dev[MAX_DEVICE];
75
76 // return bytes size of readed data
77 // return 0 if no data readed or error occurred
78 static int _file_read(FILE* fp, char *buffer, int size)
79 {
80         int ret = 0;
81
82         if(fp != NULL && size > 0)
83         {
84                 ret = fread((void*)buffer, sizeof(char), size, fp);
85         }
86         else
87         {
88                 // fp is null
89                 if(size > 0)
90                         buffer[0] = '\0';
91
92                 ret = 0;        // error case
93         }
94
95         return ret;
96 }
97
98 // get input id of given input device
99 static int get_input_id(char* inputname)
100 {
101         static int query_cmd_type = 0;  // 1 if /lib/udev/input_id, 2 if udevadm
102         FILE* cmd_fp = NULL;
103         char buffer[BUF_SIZE];
104         char command[MAX_FILENAME];
105         int ret = -1;
106
107         // determine input_id query command
108         if(unlikely(query_cmd_type == 0))
109         {
110                 if(access("/lib/udev/input_id", F_OK) == 0)             // there is /lib/udev/input_id
111                 {
112                         query_cmd_type = 1;
113                 }
114                 else    // there is not /lib/udev/input_id
115                 {
116                         query_cmd_type = 2;
117                 }
118         }
119
120         // make command string
121         if(query_cmd_type == 1)
122         {
123                 sprintf(command, "/lib/udev/input_id /class/input/%s", inputname);
124         }
125         else
126         {
127                 sprintf(command, "udevadm info --name=input/%s --query=property", inputname);
128         }
129
130         // run command
131         cmd_fp = popen(command, "r");
132         _file_read(cmd_fp, buffer, BUF_SIZE);
133
134         // determine input id
135         if(strstr(buffer, INPUT_ID_STR_KEY))                    // key
136         {
137                 ret = INPUT_ID_KEY;
138         }
139         else if(strstr(buffer, INPUT_ID_STR_TOUCH))             // touch
140         {
141                 ret = INPUT_ID_TOUCH;
142         }
143         else if(strstr(buffer, INPUT_ID_STR_KEYBOARD))  // keyboard
144         {
145                 ret = INPUT_ID_KEY;
146         }
147         else if(strstr(buffer, INPUT_ID_STR_TABLET))    // touch (emulator)
148         {
149                 ret = INPUT_ID_TOUCH;
150         }
151
152         if(cmd_fp != NULL)
153                 pclose(cmd_fp);
154         return ret;
155 }
156
157 // get filename and fd of given input type devices
158 static void _get_fds(input_dev *dev, int input_id)
159 {
160         DIR *dp;
161         struct dirent *d;
162         int count = 0;
163
164         dp = opendir("/sys/class/input");
165
166         if(dp != NULL)
167         {
168                 while((d = readdir(dp)) != NULL)
169                 {
170                         if(!strncmp(d->d_name, "event", 5))     // start with "event"
171                         {
172                                 // event file
173                                 if(input_id == get_input_id(d->d_name))
174                                 {
175                                         sprintf(dev[count].fileName, "/dev/input/%s", d->d_name);
176                                         dev[count].fd = open(dev[count].fileName, O_RDWR | O_NONBLOCK);
177                                         count++;
178                                 }
179                         }
180                 }
181
182                 closedir(dp);
183         }
184         dev[count].fd = ARRAY_END;      // end of input_dev array
185 }
186
187 //static
188 void _device_write(input_dev *dev, struct input_event* in_ev)
189 {
190         int i;
191         for(i = 0; dev[i].fd != ARRAY_END; i++)
192         {
193                 if(dev[i].fd >= 0)
194                 {
195                         write(dev[i].fd, in_ev, sizeof(struct input_event));
196                         LOGI("write(%d, %d, %d)\n",dev[i].fd, (int)in_ev, sizeof(struct input_event));
197                 }
198         }
199 }
200
201 long long get_total_alloc_size()
202 {
203         int i;
204         long long allocsize = 0;
205
206         for(i = 0; i < MAX_TARGET_COUNT; i++)
207         {
208                 if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0)
209                         allocsize += manager.target[i].allocmem;
210         }
211         return allocsize;
212 }
213
214 static int getEmptyTargetSlot()
215 {
216         int i;
217         for(i = 0; i < MAX_TARGET_COUNT; i++)
218         {
219                 if(manager.target[i].socket == -1)
220                         break;
221         }
222
223         return i;
224 }
225
226 static void setEmptyTargetSlot(int index)
227 {
228         if(index >= 0 && index < MAX_TARGET_COUNT)
229         {
230                 manager.target[index].pid = -1;
231                 manager.target[index].recv_thread = -1;
232                 manager.target[index].allocmem = 0;
233                 manager.target[index].starttime = 0;
234                 manager.target[index].initial_log = 0;
235                 if(manager.target[index].event_fd != -1)
236                         close(manager.target[index].event_fd);
237                 manager.target[index].event_fd = -1;
238                 if(manager.target[index].socket != -1)
239                         close(manager.target[index].socket);
240                 manager.target[index].socket = -1;
241         }
242 }
243
244 // ======================================================================================
245 // send functions to host
246 // ======================================================================================
247
248 //static
249 int sendACKCodeToHost(enum HostMessageType resp, int msgcode)
250 {
251         // FIXME:
252         //disabled string protocol
253         return 0;
254         if (manager.host.control_socket != -1)
255         {
256                 char codestr[16];
257                 char logstr[DA_MSG_MAX];
258                 int loglen, codelen;
259
260                 codelen = sprintf(codestr, "%d", msgcode);
261                 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr);
262
263                 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
264                 return 0;
265         }
266         else
267                 return 1;
268 }
269
270 // ========================================================================================
271 // start and terminate control functions
272 // ========================================================================================
273
274 static int exec_app(const struct app_info_t *app_info)
275 {
276         int res = 0;
277
278         switch (app_info->app_type) {
279         case APP_TYPE_TIZEN:
280                 kill_app(app_info->exe_path);
281                 if (exec_app_tizen(app_info->app_id, app_info->exe_path)) {
282                         LOGE("Cannot exec tizen app %s\n", app_info->app_id);
283                         res = -1;
284                 }
285                 break;
286         case APP_TYPE_RUNNING:
287                 // TODO: nothing, it's running
288                 break;
289         case APP_TYPE_COMMON:
290                 kill_app(app_info->exe_path);
291                 if (exec_app_common(app_info->exe_path)) {
292                         LOGE("Cannot exec common app %s\n", app_info->exe_path);
293                         res = -1;
294                 }
295                 break;
296         default:
297                 LOGE("Unknown app type %d\n", app_info->app_type);
298                 res = -1;
299                 break;
300         }
301
302         return res;
303 }
304
305 static void epoll_add_input_events();
306 static void epoll_del_input_events();
307
308 int start_profiling()
309 {
310         const struct app_info_t *app_info = &prof_session.app_info;
311         int res = 0;
312
313         // remove previous screen capture files
314         remove_indir(SCREENSHOT_DIR);
315         mkdir(SCREENSHOT_DIR, 0777);
316 #ifndef LOCALTEST
317         smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
318 #endif
319
320         if (IS_OPT_SET(FL_CPU | FL_MEMORY)) {
321                 if (samplingStart() < 0) {
322                         LOGE("Cannot start sampling\n");
323                         res = -1;
324                         goto exit;
325                 }
326         }
327
328         if (IS_OPT_SET(FL_RECORDING))
329                 epoll_add_input_events();
330
331         if (exec_app(app_info)) {
332                 LOGE("Cannot exec app\n");
333                 res = -1;
334                 goto recording_stop;
335         }
336
337         goto exit;
338
339 recording_stop:
340         if (IS_OPT_SET(FL_RECORDING))
341                 epoll_del_input_events();
342         if (IS_OPT_SET(FL_CPU | FL_MEMORY))
343                 samplingStop();
344
345 exit:
346         return res;
347 }
348
349 void stop_profiling(void)
350 {
351         if (IS_OPT_SET(FL_RECORDING))
352                 epoll_del_input_events();
353         if (IS_OPT_SET(FL_CPU | FL_MEMORY))
354                 samplingStop();
355 }
356
357 static void reconfigure_recording(struct conf_t conf)
358 {
359         uint64_t old_features = prof_session.conf.use_features;
360         uint64_t new_features = conf.use_features;
361         uint64_t to_enable = (new_features ^ old_features) & new_features;
362         uint64_t to_disable = (new_features ^ old_features) & old_features;
363
364         if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) {
365                 epoll_del_input_events();
366                 prof_session.conf.use_features &= ~FL_RECORDING;
367         }
368
369         if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) {
370                 epoll_add_input_events();
371                 prof_session.conf.use_features |= FL_RECORDING;
372         }
373
374 }
375
376 static int reconfigure_cpu_and_memory(struct conf_t conf)
377 {
378         uint64_t old_features = prof_session.conf.use_features;
379         uint64_t new_features = conf.use_features;
380         uint64_t to_enable = (new_features ^ old_features) & new_features;
381         uint64_t to_disable = (new_features ^ old_features) & old_features;
382
383         prof_session.conf.system_trace_period = conf.system_trace_period;
384
385         if (IS_OPT_SET(FL_CPU | FL_MEMORY))
386                 samplingStop();
387
388         if (IS_OPT_SET_IN(FL_CPU | FL_MEMORY, to_disable)) {
389                 prof_session.conf.use_features &= ~(FL_CPU | FL_MEMORY);
390                 return 0;
391         }
392
393         if (IS_OPT_SET_IN(FL_CPU | FL_MEMORY, to_enable)) {
394                 if (samplingStart() < 0) {
395                         LOGE("Cannot start sampling\n");
396                         return -1;
397                 }
398                 prof_session.conf.use_features |= (FL_CPU | FL_MEMORY);
399         }
400
401         return 0;
402 }
403
404 int reconfigure(struct conf_t conf)
405 {
406         reconfigure_recording(conf);
407         if (reconfigure_cpu_and_memory(conf)) {
408                 LOGE("Cannot reconf cpu and memory\n");
409                 return -1;
410         }
411
412         return 0;
413 }
414
415 // just send stop message to all target process
416 static void terminate_all_target()
417 {
418         int i;
419         ssize_t sendlen;
420         msg_target_t sendlog;
421
422         sendlog.type = MSG_STOP;
423         sendlog.length = 0;
424
425         for (i = 0; i < MAX_TARGET_COUNT; i++)
426         {
427                 if(manager.target[i].socket != -1)
428                 {
429                         sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
430                         if(sendlen != -1)
431                         {
432                                 LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket);
433                         }
434                 }
435         }
436 }
437
438 // terminate all target and wait for threads
439 void terminate_all()
440 {
441         int i;
442
443         terminate_all_target();
444
445         // wait for all other thread exit
446         for(i = 0; i < MAX_TARGET_COUNT; i++)
447         {
448                 if(manager.target[i].recv_thread != -1)
449                 {
450                         pthread_join(manager.target[i].recv_thread, NULL);
451                 }
452         }
453 }
454
455 // terminate all profiling by critical error
456 // TODO: don't send data to host
457 static void terminate_error(char* errstr, int sendtohost)
458 {
459         terminate_all();
460 }
461
462 #define MAX_EVENTS_NUM 10
463 static int deviceEventHandler(input_dev* dev, int input_type)
464 {
465         int ret = 0;
466         ssize_t size = 0;
467         int count = 0;
468         struct input_event in_ev[MAX_EVENTS_NUM];
469         struct msg_data_t *log;
470
471         if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
472         {
473                 do {
474                         size = read(dev->fd, &in_ev[count], sizeof(*in_ev) );
475                         if (size >0)
476                                 count++;
477                 } while (count < MAX_EVENTS_NUM && size > 0);
478
479                 if (count) {
480                         LOGI("read %d %s events\n",
481                              count,
482                              input_type == INPUT_ID_KEY ? STR_KEY : STR_TOUCH);
483                         log = gen_message_event(in_ev, count, input_type);
484                         printBuf((char *)log, MSG_DATA_HDR_LEN + log->len);
485                         write_to_buf(log);
486                         reset_data_msg(log);
487                 }
488         }
489         else
490         {
491                 LOGW("unknown input_type\n");
492                 ret = 1;
493         }
494         return ret;
495 }
496
497 // return 0 if normal case
498 // return plus value if non critical error occur
499 // return minus value if critical error occur
500 // return -11 if all target process closed
501 static int targetEventHandler(int epollfd, int index, uint64_t msg)
502 {
503         if(msg & EVENT_PID)
504         {
505                 if (index == 0) { // main application
506                         if (start_replay() != 0) {
507                                 LOGE("Cannot start replay thread\n");
508                                 return -1;
509                         }
510                 }
511                 manager.target[index].initial_log = 1;
512         }
513
514         if(msg & EVENT_STOP || msg & EVENT_ERROR)
515         {
516                 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
517                      manager.target[index].socket,
518                      manager.target[index].pid,
519                      manager.target_count - 1);
520                 if (index == 0) { // main application
521                         stop_replay();
522                 }
523                 epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
524                 setEmptyTargetSlot(index);
525                 if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) // all target client are closed
526                         return -11;
527         }
528
529         return 0;
530 }
531
532 // return 0 if normal case
533 // return plus value if non critical error occur
534 // return minus value if critical error occur
535 static int targetServerHandler(int efd)
536 {
537         msg_target_t log;
538         struct epoll_event ev;
539
540         int index = getEmptyTargetSlot();
541         if(index == MAX_TARGET_COUNT)
542         {
543                 LOGW("Max target number(8) reached, no more target can connected\n");
544                 return 1;
545         }
546
547         manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL);
548
549         if(manager.target[index].socket >= 0)   // accept succeed
550         {
551 #ifndef LOCALTEST
552                 // set smack attribute for certification
553                 fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
554                 fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
555 #endif /* LOCALTEST */
556
557                 // send config message to target process
558                 log.type = MSG_OPTION;
559                 log.length = sprintf(log.data, "%u",
560                                      prof_session.conf.use_features);
561                 send(manager.target[index].socket, &log,
562                      sizeof(log.type) + sizeof(log.length) + log.length,
563                      MSG_NOSIGNAL);
564
565                 // make event fd
566                 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
567                 if(manager.target[index].event_fd == -1)
568                 {
569                         // fail to make event fd
570                         LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket);
571                         goto TARGET_CONNECT_FAIL;
572                 }
573
574                 // add event fd to epoll list
575                 ev.events = EPOLLIN;
576                 ev.data.fd = manager.target[index].event_fd;
577                 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
578                 {
579                         // fail to add event fd
580                         LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket);
581                         goto TARGET_CONNECT_FAIL;
582                 }
583
584                 // make recv thread for target
585                 if(makeRecvThread(index) != 0)
586                 {
587                         // fail to make recv thread
588                         LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket);
589                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
590                         goto TARGET_CONNECT_FAIL;
591                 }
592
593                 if(manager.app_launch_timerfd >= 0)
594                 {
595                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
596                         close(manager.app_launch_timerfd);
597                         manager.app_launch_timerfd = -1;
598                 }
599
600                 LOGI("target connected = %d(running %d target)\n",
601                                 manager.target[index].socket, manager.target_count + 1);
602
603                 manager.target_count++;
604                 return 0;
605         }
606         else    // accept error
607         {
608                 LOGE("Failed to accept at target server socket\n");
609         }
610
611 TARGET_CONNECT_FAIL:
612         if(manager.target_count == 0)   // if this connection is main connection
613         {
614                 return -1;
615         }
616         else    // if this connection is not main connection then ignore process by error
617         {
618                 setEmptyTargetSlot(index);
619                 return 1;
620         }
621 }
622
623 // return 0 if normal case
624 // return plus value if non critical error occur
625 // return minus value if critical error occur
626 static int hostServerHandler(int efd)
627 {
628         static int hostserverorder = 0;
629         int csocket;
630         struct epoll_event ev;
631
632         if(hostserverorder > 1) // control and data socket connected already
633                 return 1;                       // ignore
634
635         csocket = accept(manager.host_server_socket, NULL, NULL);
636
637         if(csocket >= 0)                // accept succeed
638         {
639                 ev.events = EPOLLIN;
640                 ev.data.fd = csocket;
641                 if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
642                 {
643                         // consider as accept fail
644                         LOGE("Failed to add socket fd to epoll list\n");
645                         close(csocket);
646                         return -1;
647                 }
648
649                 if(hostserverorder == 0)
650                 {
651                         manager.host.control_socket = csocket;
652                         unlink_portfile();
653                         LOGI("host control socket connected = %d\n", csocket);
654                 }
655                 else
656                 {
657                         manager.host.data_socket = csocket;
658                         LOGI("host data socket connected = %d\n", csocket);
659                 }
660
661                 hostserverorder++;
662                 return 0;
663         }
664         else    // accept error
665         {
666                 LOGE("Failed to accept from host server socket\n");
667                 return -1;
668         }
669 }
670
671
672 // return 0 if normal case
673 // return plus value if non critical error occur
674 // return minus value if critical error occur
675 // return -11 if socket closed
676
677 static int controlSocketHandler(int efd)
678 {
679         ssize_t recv_len;
680         struct msg_t msg_head;
681         struct msg_t *msg;
682         int res = 0;
683
684         // Receive header
685         recv_len = recv(manager.host.control_socket,
686                        &msg_head,
687                        MSG_CMD_HDR_LEN, 0);
688         // error or close request from host
689         if (recv_len == -1 || recv_len == 0)
690                 return -11;
691         else {
692                 msg = malloc(MSG_CMD_HDR_LEN + msg_head.len);
693                 if (!msg) {
694                         LOGE("Cannot alloc msg\n");
695                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
696                         return -1;
697                 }
698                 msg->id = msg_head.id;
699                 msg->len = msg_head.len;
700                 if (msg->len > 0) {
701                         // Receive payload (if exists)
702                         recv_len = recv(manager.host.control_socket,
703                                         msg->payload,
704                                         msg->len, MSG_WAITALL);
705                 }
706                 res = host_message_handler(msg);
707                 free(msg);
708         }
709
710         return res;
711 }
712
713 static void epoll_add_input_events()
714 {
715         struct epoll_event ev;
716         int i;
717
718         // add device fds to epoll event pool
719         ev.events = EPOLLIN;
720         for (i = 0; g_key_dev[i].fd != ARRAY_END; i++) {
721                 if (g_key_dev[i].fd >= 0) {
722                         ev.data.fd = g_key_dev[i].fd;
723                         if (epoll_ctl(manager.efd,
724                                       EPOLL_CTL_ADD,
725                                       g_key_dev[i].fd, &ev) < 0)
726                                 LOGE("keyboard device file epoll_ctl error\n");
727                 }
728         }
729
730         ev.events = EPOLLIN;
731         for (i = 0; g_touch_dev[i].fd != ARRAY_END; i++) {
732                 if (g_touch_dev[i].fd >= 0) {
733                         ev.data.fd = g_touch_dev[i].fd;
734                         if (epoll_ctl(manager.efd,
735                                       EPOLL_CTL_ADD,
736                                       g_touch_dev[i].fd, &ev) < 0)
737                                 LOGE("touch device file epoll_ctl error\n");
738                 }
739         }
740 }
741
742 static void epoll_del_input_events()
743 {
744         int i;
745
746         // remove device fds from epoll event pool
747         for (i = 0; g_key_dev[i].fd != ARRAY_END; i++)
748                 if (g_key_dev[i].fd >= 0)
749                         if (epoll_ctl(manager.efd,
750                                       EPOLL_CTL_DEL,
751                                       g_key_dev[i].fd, NULL) < 0)
752                                 LOGE("keyboard device file epoll_ctl error\n");
753
754         for (i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
755                 if (g_touch_dev[i].fd >= 0)
756                         if (epoll_ctl(manager.efd,
757                                       EPOLL_CTL_DEL,
758                                       g_touch_dev[i].fd, NULL) < 0)
759                                 LOGE("touch device file epoll_ctl error\n");
760 }
761
762 // return 0 for normal case
763 int daemonLoop()
764 {
765         int                     ret = 0;                                // return value
766         int                     i, k;
767         ssize_t         recvLen;
768
769         struct epoll_event ev, *events;
770         int numevent;   // number of occured events
771
772         _get_fds(g_key_dev, INPUT_ID_KEY);
773         _get_fds(g_touch_dev, INPUT_ID_TOUCH);
774
775         // initialize epoll event pool
776         events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
777         if(events == NULL)
778         {
779                 LOGE("Out of memory when allocate epoll event pool\n");
780                 ret = -1;
781                 goto END_RETURN;
782         }
783         if((manager.efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
784         {
785                 LOGE("epoll creation error\n");
786                 ret = -1;
787                 goto END_EVENT;
788         }
789
790         // add server sockets to epoll event pool
791         ev.events = EPOLLIN;
792         ev.data.fd = manager.host_server_socket;
793         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
794                      manager.host_server_socket, &ev) < 0)
795         {
796                 LOGE("Host server socket epoll_ctl error\n");
797                 ret = -1;
798                 goto END_EFD;
799         }
800         ev.events = EPOLLIN;
801         ev.data.fd = manager.target_server_socket;
802         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
803                       manager.target_server_socket, &ev) < 0)
804         {
805                 LOGE("Target server socket epoll_ctl error\n");
806                 ret = -1;
807                 goto END_EFD;
808         }
809
810         // handler loop
811         while (1)
812         {
813                 numevent = epoll_wait(manager.efd, events, EPOLL_SIZE, -1);
814                 if(numevent <= 0)
815                 {
816                         LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
817                         continue;
818                 }
819
820                 for(i = 0; i < numevent; i++)
821                 {
822                         // check for request from event fd
823                         for(k = 0; k < MAX_TARGET_COUNT; k++)
824                         {
825                                 if(manager.target[k].socket != -1 &&
826                                                 events[i].data.fd == manager.target[k].event_fd)
827                                 {
828                                         uint64_t u;
829                                         recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
830                                         if(recvLen != sizeof(uint64_t))
831                                         {
832                                                 // maybe closed, but ignoring is more safe then removing fd from epoll list
833                                         }
834                                         else
835                                         {
836                                                 if(-11 == targetEventHandler(manager.efd, k, u))
837                                                 {
838                                                         LOGI("all target process is closed\n");
839                                                         continue;
840                                                 }
841                                         }
842                                         break;
843                                 }
844                         }
845
846                         if(k != MAX_TARGET_COUNT)
847                                 continue;
848
849                         // check for request from device fd
850                         for(k = 0; g_touch_dev[k].fd != ARRAY_END; k++)
851                         {
852                                 if(g_touch_dev[k].fd >= 0 && 
853                                                 events[i].data.fd == g_touch_dev[k].fd)
854                                 {
855                                         if(deviceEventHandler(&g_touch_dev[k], INPUT_ID_TOUCH) < 0)
856                                         {
857                                                 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
858                                                 ret = -1;
859                                                 goto END_EFD;
860                                         }
861                                         break;
862                                 }
863                         }
864
865                         if(g_touch_dev[k].fd != ARRAY_END)
866                                 continue;
867
868                         for(k = 0; g_key_dev[k].fd != ARRAY_END; k++)
869                         {
870                                 if(g_key_dev[k].fd >= 0 && 
871                                                 events[i].data.fd == g_key_dev[k].fd)
872                                 {
873                                         if(deviceEventHandler(&g_key_dev[k], INPUT_ID_KEY) < 0)
874                                         {
875                                                 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
876                                                 ret = -1;
877                                                 goto END_EFD;
878                                         }
879                                         break;
880                                 }
881                         }
882
883                         if(g_key_dev[k].fd != ARRAY_END)
884                                 continue;
885
886                         // connect request from target
887                         if(events[i].data.fd == manager.target_server_socket)
888                         {
889                                 if(targetServerHandler(manager.efd) < 0)        // critical error
890                                 {
891                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
892                                         ret = -1;
893                                         goto END_EFD;
894                                 }
895                         }
896                         // connect request from host
897                         else if(events[i].data.fd == manager.host_server_socket)
898                         {
899                                 int result = hostServerHandler(manager.efd);
900                                 if(result < 0)
901                                 {
902                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
903                                         ret = -1;
904                                         goto END_EFD;
905                                 }
906                         }
907                         // control message from host
908                         else if(events[i].data.fd == manager.host.control_socket)
909                         {
910                                 int result = controlSocketHandler(manager.efd);
911                                 if(result == -11)       // socket close
912                                 {
913                                         // close target and host socket and quit
914                                         LOGI("host close = %d\n", manager.host.control_socket);
915                                         ret = 0;
916                                         goto END_EFD;
917                                 }
918                                 else if(result < 0)
919                                 {
920                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
921                                         ret = -1;
922                                         goto END_EFD;
923                                 }
924                         }
925                         else if(events[i].data.fd == manager.host.data_socket)
926                         {
927                                 char recvBuf[32];
928                                 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
929                                 if(recvLen == 0)
930                                 {       // close data socket
931                                         epoll_ctl(manager.efd, EPOLL_CTL_DEL,
932                                                   manager.host.data_socket,
933                                                   NULL);
934                                         close(manager.host.data_socket);
935                                         manager.host.data_socket = -1;
936                                         // TODO: finish transfer thread
937                                 }
938         
939                                 LOGW("host message from data socket %d\n", recvLen);
940                         }
941                         // check for application launch timerfd
942                         else if(events[i].data.fd == manager.app_launch_timerfd)
943                         {
944                                 // send to host timeout error message for launching application
945                                 terminate_error("Failed to launch application", 1);
946                                 epoll_ctl(manager.efd, EPOLL_CTL_DEL,
947                                           manager.app_launch_timerfd, NULL);
948                                 close(manager.app_launch_timerfd);
949                                 manager.app_launch_timerfd = -1;
950                                 ret = -1;
951                                 goto END_EFD;
952                         }
953                         // unknown socket
954                         else
955                         {
956                                 // never happened
957                                 LOGW("Unknown socket fd (%d)\n", events[i].data.fd);
958                         }
959                 }
960         }
961
962 END_EFD:
963         close(manager.efd);
964 END_EVENT:
965         free(events);
966 END_RETURN:
967         return ret;
968 }