[REFACTOR] add functions start_app_launch_timer stop_app_launch_timer
[platform/core/system/swap-manager.git] / daemon / daemon.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2000 - 2013 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  * Cherepanov Vitaliy <v.cherepanov@samsung.com>
12  * Nikita Kalyazin    <n.kalyazin@samsung.com>
13  *
14  * Licensed under the Apache License, Version 2.0 (the "License");
15  * you may not use this file except in compliance with the License.
16  * You may obtain a copy of the License at
17  *
18  * http://www.apache.org/licenses/LICENSE-2.0
19  *
20  * Unless required by applicable law or agreed to in writing, software
21  * distributed under the License is distributed on an "AS IS" BASIS,
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23  * See the License for the specific language governing permissions and
24  * limitations under the License.
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  * - Samsung RnD Institute Russia
29  *
30  */
31 #define __STDC_FORMAT_MACROS
32 #include <stdio.h>
33 #include <stdlib.h>                     // for realpath
34 #include <string.h>                     // for strtok, strcpy, strncpy
35 #include <limits.h>                     // for realpath
36 #include <inttypes.h>
37
38 #include <errno.h>                      // for errno
39 #include <sys/types.h>          // for accept, mkdir, opendir, readdir
40 #include <sys/socket.h>         // for accept
41 #include <sys/stat.h>           // for mkdir
42 #include <sys/eventfd.h>        // for eventfd
43 #include <sys/epoll.h>          // for epoll apis
44 #include <sys/timerfd.h>        // for timerfd
45 #include <unistd.h>                     // for access, sleep
46 #include <stdbool.h>
47
48 #include <ctype.h>
49
50 #ifndef LOCALTEST
51 #include <attr/xattr.h>         // for fsetxattr
52 #include <sys/smack.h>
53 #endif
54
55 #include <linux/input.h>
56 #include <dirent.h>
57 #include <fcntl.h>
58 #include "daemon.h"
59 #include "sys_stat.h"
60 #include "utils.h"
61 #include "da_protocol.h"
62 #include "da_data.h"
63 #include "debug.h"
64 #include "process_info.h"
65
66 #define DA_WORK_DIR                             "/home/developer/sdk_tools/da/"
67 #define DA_READELF_PATH                 "/home/developer/sdk_tools/da/readelf"
68 #define SCREENSHOT_DIR                  "/tmp/da"
69
70 #define EPOLL_SIZE                              10
71 #define MAX_APP_LAUNCH_TIME             60
72 #define MAX_CONNECT_TIMEOUT_TIME        5*60
73
74 #define MAX_DEVICE                              10
75 #define MAX_FILENAME                    128
76 #define BUF_SIZE                                1024
77 #define ARRAY_END                               (-11)
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 | O_NONBLOCK);
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
194 void _device_write(input_dev *dev, struct input_event* in_ev)
195 {
196         int i;
197         for(i = 0; dev[i].fd != ARRAY_END; i++)
198         {
199                 if(dev[i].fd >= 0)
200                 {
201                         write(dev[i].fd, in_ev, sizeof(struct input_event));
202                         LOGI("write(%d, %d, %d)\n",
203                                         dev[i].fd, (int)in_ev, sizeof(struct input_event));
204                 }
205         }
206 }
207
208 long long get_total_alloc_size()
209 {
210         int i;
211         long long allocsize = 0;
212
213         for(i = 0; i < MAX_TARGET_COUNT; i++)
214         {
215                 if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0)
216                         allocsize += manager.target[i].allocmem;
217         }
218         return allocsize;
219 }
220
221 static int getEmptyTargetSlot()
222 {
223         int i;
224         for(i = 0; i < MAX_TARGET_COUNT; i++)
225         {
226                 if(manager.target[i].socket == -1)
227                         break;
228         }
229
230         return i;
231 }
232
233 static void setEmptyTargetSlot(int index)
234 {
235         if(index >= 0 && index < MAX_TARGET_COUNT)
236         {
237                 manager.target[index].pid = -1;
238                 manager.target[index].recv_thread = -1;
239                 manager.target[index].allocmem = 0;
240                 manager.target[index].starttime = 0;
241                 manager.target[index].initial_log = 0;
242                 if(manager.target[index].event_fd != -1)
243                         close(manager.target[index].event_fd);
244                 manager.target[index].event_fd = -1;
245                 if(manager.target[index].socket != -1)
246                         close(manager.target[index].socket);
247                 manager.target[index].socket = -1;
248         }
249 }
250
251 // =============================================================================
252 // start and terminate control functions
253 // =============================================================================
254
255 //start application launch timer function
256 static int start_app_launch_timer()
257 {
258         int res = 0;
259         struct epoll_event ev;
260
261         manager.app_launch_timerfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
262         if(manager.app_launch_timerfd > 0)
263         {
264                 struct itimerspec ctime;
265                 ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME;
266                 ctime.it_value.tv_nsec = 0;
267                 ctime.it_interval.tv_sec = 0;
268                 ctime.it_interval.tv_nsec = 0;
269                 if (timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL) < 0)
270                 {
271                         LOGE("fail to set app launch timer\n");
272                         close(manager.app_launch_timerfd);
273                         manager.app_launch_timerfd = -1;
274                         res = -1;
275                 }
276                 else
277                 {
278                         // add event fd to epoll list
279                         ev.events = EPOLLIN;
280                         ev.data.fd = manager.app_launch_timerfd;
281                         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
282                                                 manager.app_launch_timerfd, &ev) < 0)
283                         {
284                                 // fail to add event fd
285                                 LOGE("fail to add app launch timer fd to epoll list\n");
286                                 close(manager.app_launch_timerfd);
287                                 manager.app_launch_timerfd = -1;
288                                 res = -2;
289                         } else {
290                                 LOGI("application launch time started\n");
291                         }
292                 }
293         } else {
294                 LOGE("cannot create launch timer\n");
295                 res = -3;
296         }
297
298         return res;
299 }
300
301 //stop application launch timer
302 static int stop_app_launch_timer()
303 {
304         epoll_ctl(manager.efd, EPOLL_CTL_DEL,manager.app_launch_timerfd, NULL);
305         close(manager.app_launch_timerfd);
306         manager.app_launch_timerfd = -1;
307         return 0;
308 }
309
310 static int exec_app(const struct app_info_t *app_info)
311 {
312         int res = 0;
313         static struct epoll_event ev;
314
315
316         switch (app_info->app_type) {
317         case APP_TYPE_TIZEN:
318                 kill_app(app_info->exe_path);
319                 if (exec_app_tizen(app_info->app_id, app_info->exe_path)) {
320                         LOGE("Cannot exec tizen app %s\n", app_info->app_id);
321                         res = -1;
322                 }
323                 break;
324         case APP_TYPE_RUNNING:
325                 // TODO: nothing, it's running
326                 LOGI("already started\n");
327                 write_process_info(atoi(app_info->app_id), 0);
328                 break;
329         case APP_TYPE_COMMON:
330                 kill_app(app_info->exe_path);
331                 if (exec_app_common(app_info->exe_path)) {
332                         LOGE("Cannot exec common app %s\n", app_info->exe_path);
333                         res = -1;
334                 }
335                 break;
336         default:
337                 LOGE("Unknown app type %d\n", app_info->app_type);
338                 res = -1;
339                 break;
340         }
341
342         if (res == 0 && app_info->app_type != APP_TYPE_RUNNING)
343                 if (start_app_launch_timer()<0)
344                         res = -1;
345
346         LOGI("ret=%d\n", res);
347         return res;
348 }
349
350 int launch_timer_start()
351 {
352         static struct epoll_event ev;
353         int res = 0;
354
355         manager.connect_timeout_timerfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
356         if(manager.connect_timeout_timerfd > 0)
357         {
358                 struct itimerspec ctime;
359                 ctime.it_value.tv_sec = MAX_CONNECT_TIMEOUT_TIME;
360                 ctime.it_value.tv_nsec = 0;
361                 ctime.it_interval.tv_sec = 0;
362                 ctime.it_interval.tv_nsec = 0;
363                 if (timerfd_settime(manager.connect_timeout_timerfd, 0, &ctime, NULL) < 0)
364                 {
365                         LOGE("fail to set connect timeout timer\n");
366                         close(manager.connect_timeout_timerfd);
367                         manager.connect_timeout_timerfd = -1;
368                 }
369                 else
370                 {
371                         // add event fd to epoll list
372                         ev.events = EPOLLIN;
373                         ev.data.fd = manager.connect_timeout_timerfd;
374                         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
375                                                 manager.connect_timeout_timerfd, &ev) < 0)
376                         {
377                                 // fail to add event fd
378                                 LOGE("fail to add app connection timeout timer fd to epoll list\n");
379                                 close(manager.connect_timeout_timerfd);
380                                 manager.connect_timeout_timerfd = -1;
381                         } else {
382                                 LOGI("connection timeout timer started\n");
383                         }
384                 }
385         } else {
386                 LOGE("cannot create connection timeout timer\n");
387         }
388
389         LOGI("ret=%d\n", res);
390         return res;
391 }
392
393 static void epoll_add_input_events();
394 static void epoll_del_input_events();
395
396 int start_profiling()
397 {
398         const struct app_info_t *app_info = &prof_session.app_info;
399         int res = 0;
400
401         // remove previous screen capture files
402         remove_indir(SCREENSHOT_DIR);
403         mkdir(SCREENSHOT_DIR, 0777);
404 #ifndef LOCALTEST
405         smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
406 #endif
407
408         if (IS_OPT_SET(FL_CPU | FL_MEMORY)) {
409                 if (samplingStart() < 0) {
410                         LOGE("Cannot start sampling\n");
411                         res = -1;
412                         goto exit;
413                 }
414         }
415
416         if (IS_OPT_SET(FL_RECORDING))
417                 epoll_add_input_events();
418
419         if (exec_app(app_info)) {
420                 LOGE("Cannot exec app\n");
421                 res = -1;
422                 goto recording_stop;
423         }
424
425         goto exit;
426
427 recording_stop:
428         if (IS_OPT_SET(FL_RECORDING))
429                 epoll_del_input_events();
430         if (IS_OPT_SET(FL_CPU | FL_MEMORY))
431                 samplingStop();
432
433 exit:
434         LOGI("return %d\n", res);
435         return res;
436 }
437
438 void stop_profiling(void)
439 {
440         if (IS_OPT_SET(FL_RECORDING))
441                 epoll_del_input_events();
442         if (IS_OPT_SET(FL_CPU | FL_MEMORY))
443                 samplingStop();
444 }
445
446 static void reconfigure_recording(struct conf_t conf)
447 {
448         uint64_t old_features = prof_session.conf.use_features0;
449         uint64_t new_features = conf.use_features0;
450         uint64_t to_enable = (new_features ^ old_features) & new_features;
451         uint64_t to_disable = (new_features ^ old_features) & old_features;
452
453         if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) {
454                 epoll_del_input_events();
455                 prof_session.conf.use_features0 &= ~FL_RECORDING;
456         }
457
458         if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) {
459                 epoll_add_input_events();
460                 prof_session.conf.use_features0 |= FL_RECORDING;
461         }
462
463 }
464
465 static int reconfigure_cpu_and_memory(struct conf_t conf)
466 {
467         uint64_t old_features = prof_session.conf.use_features0;
468         uint64_t new_features = conf.use_features0;
469         uint64_t to_enable = (new_features ^ old_features) & new_features;
470         uint64_t to_disable = (new_features ^ old_features) & old_features;
471
472         prof_session.conf.system_trace_period = conf.system_trace_period;
473
474         if (IS_OPT_SET(FL_CPU | FL_MEMORY))
475                 samplingStop();
476
477         if (IS_OPT_SET_IN(FL_CPU | FL_MEMORY, to_disable)) {
478                 prof_session.conf.use_features0 &= ~(FL_CPU | FL_MEMORY);
479                 return 0;
480         }
481
482         if (IS_OPT_SET_IN(FL_CPU | FL_MEMORY, to_enable)) {
483                 if (samplingStart() < 0) {
484                         LOGE("Cannot start sampling\n");
485                         return -1;
486                 }
487                 prof_session.conf.use_features0 |= (FL_CPU | FL_MEMORY);
488         }
489
490         return 0;
491 }
492
493 int reconfigure(struct conf_t conf)
494 {
495         reconfigure_recording(conf);
496         if (reconfigure_cpu_and_memory(conf)) {
497                 LOGE("Cannot reconf cpu and memory\n");
498                 return -1;
499         }
500
501         return 0;
502 }
503
504 // just send stop message to all target process
505 static void terminate_all_target()
506 {
507         int i;
508         ssize_t sendlen;
509         msg_target_t sendlog;
510
511         sendlog.type = MSG_STOP;
512         sendlog.length = 0;
513
514         for (i = 0; i < MAX_TARGET_COUNT; i++)
515         {
516                 if(manager.target[i].socket != -1)
517                 {
518                         sendlen = send(manager.target[i].socket, &sendlog,
519                                                         sizeof(sendlog.type) + sizeof(sendlog.length),
520                                                         MSG_NOSIGNAL);
521                         if(sendlen != -1)
522                         {
523                                 LOGI("TERMINATE send exit msg (socket %d) "
524                                                 "by terminate_all_target()\n", manager.target[i].socket);
525                         }
526                 }
527         }
528 }
529
530 // terminate all target and wait for threads
531 void terminate_all()
532 {
533         int i;
534         terminate_all_target();
535
536         // wait for all other thread exit
537         for(i = 0; i < MAX_TARGET_COUNT; i++)
538         {
539                 if(manager.target[i].recv_thread != -1)
540                 {
541                         pthread_join(manager.target[i].recv_thread, NULL);
542                 }
543         }
544 }
545
546 // terminate all profiling by critical error
547 // TODO: don't send data to host
548 static void terminate_error(char* errstr, int send_to_host)
549 {
550         LOGE("termination all with err '%s'\n", errstr);
551         struct msg_data_t *msg = NULL;
552         if (send_to_host != 0){
553                 msg = gen_message_error(errstr);
554                 if (msg) {
555                         write_to_buf(msg);
556                         free_msg_data(msg);
557                 } else {
558                         LOGI("cannot generate error message\n");
559                 }
560         }
561         terminate_all();
562 }
563
564 #define MAX_EVENTS_NUM 10
565 static int deviceEventHandler(input_dev* dev, int input_type)
566 {
567         int ret = 0;
568         ssize_t size = 0;
569         int count = 0;
570         struct input_event in_ev[MAX_EVENTS_NUM];
571         struct msg_data_t *log;
572
573         if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
574         {
575                 do {
576                         size = read(dev->fd, &in_ev[count], sizeof(*in_ev) );
577                         if (size >0)
578                                 count++;
579                 } while (count < MAX_EVENTS_NUM && size > 0);
580
581                 if (count) {
582                         LOGI("read %d %s events\n",
583                              count,
584                              input_type == INPUT_ID_KEY ? STR_KEY : STR_TOUCH);
585                         log = gen_message_event(in_ev, count, input_type);
586                         printBuf((char *)log, MSG_DATA_HDR_LEN + log->len);
587                         write_to_buf(log);
588                         free_msg_data(log);
589                 }
590         }
591         else
592         {
593                 LOGW("unknown input_type\n");
594                 ret = 1; // it is not error
595         }
596         return ret;
597 }
598
599 // return 0 if normal case
600 // return plus value if non critical error occur
601 // return minus value if critical error occur
602 // return -11 if all target process closed
603 static int targetEventHandler(int epollfd, int index, uint64_t msg)
604 {
605         if(msg & EVENT_PID)
606         {
607                 if (index == 0) { // main application
608
609                         if ( is_same_app_process(prof_session.app_info.exe_path,
610                                                 manager.target[index].pid) == 0 ) {
611                                 LOGE("is same error: '%s' is not %d\n",
612                                                 prof_session.app_info.exe_path,
613                                                 manager.target[index].pid);
614                                 return -1;
615                         }
616
617                         if (start_replay() != 0) {
618                                 LOGE("Cannot start replay thread\n");
619                                 return -1;
620                         }
621                 }
622                 manager.target[index].initial_log = 1;
623         }
624
625         if(msg & EVENT_STOP || msg & EVENT_ERROR)
626         {
627                 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
628                      manager.target[index].socket,
629                      manager.target[index].pid,
630                      manager.target_count - 1);
631                 if (index == 0) { // main application
632                         stop_replay();
633                 }
634                 epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
635                 setEmptyTargetSlot(index);
636                 // all target client are closed
637                 if (0 == __sync_sub_and_fetch(&manager.target_count, 1))
638                         return -11;
639         }
640
641         return 0;
642 }
643
644 // return 0 if normal case
645 // return plus value if non critical error occur
646 // return minus value if critical error occur
647 static int targetServerHandler(int efd)
648 {
649         msg_target_t log;
650         struct epoll_event ev;
651
652         int index = getEmptyTargetSlot();
653         if(index == MAX_TARGET_COUNT)
654         {
655                 LOGW("Max target number(8) reached, no more target can connected\n");
656                 return 1;
657         }
658
659         manager.target[index].socket =
660                 accept(manager.target_server_socket, NULL, NULL);
661
662         if(manager.target[index].socket >= 0)   // accept succeed
663         {
664 #ifndef LOCALTEST
665                 // set smack attribute for certification
666                 fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
667                 fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
668 #endif /* LOCALTEST */
669
670                 // send config message to target process
671                 log.type = MSG_OPTION;
672                 log.length = sprintf(log.data, "%lu",
673                                      (unsigned long int) prof_session.conf.use_features0);
674                 send(manager.target[index].socket, &log,
675                      sizeof(log.type) + sizeof(log.length) + log.length,
676                      MSG_NOSIGNAL);
677
678                 // make event fd
679                 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
680                 if(manager.target[index].event_fd == -1)
681                 {
682                         // fail to make event fd
683                         LOGE("fail to make event fd for socket (%d)\n",
684                                         manager.target[index].socket);
685                         goto TARGET_CONNECT_FAIL;
686                 }
687
688                 // add event fd to epoll list
689                 ev.events = EPOLLIN;
690                 ev.data.fd = manager.target[index].event_fd;
691                 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
692                 {
693                         // fail to add event fd
694                         LOGE("fail to add event fd to epoll list for socket (%d)\n",
695                                         manager.target[index].socket);
696                         goto TARGET_CONNECT_FAIL;
697                 }
698
699                 // make recv thread for target
700                 if(makeRecvThread(index) != 0)
701                 {
702                         // fail to make recv thread
703                         LOGE("fail to make recv thread for socket (%d)\n",
704                                         manager.target[index].socket);
705                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
706                         goto TARGET_CONNECT_FAIL;
707                 }
708
709                 if(manager.app_launch_timerfd >= 0)
710                 {
711                         LOGI("release launch timer\n");
712                         if (stop_app_launch_timer()<0)
713                                 LOGE("cannot stop app launch timer\n");
714                 }
715
716                 LOGI("target connected = %d(running %d target)\n",
717                                 manager.target[index].socket, manager.target_count + 1);
718
719                 manager.target_count++;
720                 return 0;
721         }
722         else    // accept error
723         {
724                 LOGE("Failed to accept at target server socket\n");
725         }
726
727 TARGET_CONNECT_FAIL:
728         if(manager.target_count == 0)   // if this connection is main connection
729         {
730                 return -1;
731         }
732         else
733         {
734                 // if this connection is not main connection then ignore process by error
735                 setEmptyTargetSlot(index);
736                 return 1;
737         }
738 }
739
740 // return 0 if normal case
741 // return plus value if non critical error occur
742 // return minus value if critical error occur
743 static int hostServerHandler(int efd)
744 {
745         static int hostserverorder = 0;
746         int csocket;
747         struct epoll_event ev;
748
749         if(hostserverorder > 1) // control and data socket connected already
750                 return 1;                       // ignore
751
752         csocket = accept(manager.host_server_socket, NULL, NULL);
753
754         if(csocket >= 0)                // accept succeed
755         {
756                 ev.events = EPOLLIN;
757                 ev.data.fd = csocket;
758                 if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
759                 {
760                         // consider as accept fail
761                         LOGE("Failed to add socket fd to epoll list\n");
762                         close(csocket);
763                         return -1;
764                 }
765
766                 if(hostserverorder == 0)
767                 {
768                         manager.host.control_socket = csocket;
769                         unlink_portfile();
770                         LOGI("host control socket connected = %d\n", csocket);
771                 }
772                 else
773                 {
774                         manager.host.data_socket = csocket;
775                         LOGI("host data socket connected = %d\n", csocket);
776                 }
777
778                 hostserverorder++;
779                 return 0;
780         }
781         else    // accept error
782         {
783                 LOGE("Failed to accept from host server socket\n");
784                 return -1;
785         }
786 }
787
788
789 // return 0 if normal case
790 // return plus value if non critical error occur
791 // return minus value if critical error occur
792 // return -11 if socket closed
793
794 static int controlSocketHandler(int efd)
795 {
796         ssize_t recv_len;
797         struct msg_t msg_head;
798         struct msg_t *msg;
799         int res = 0;
800
801         if(manager.connect_timeout_timerfd >= 0)
802         {
803                 LOGI("release connect timeout timer\n");
804                 epoll_ctl(efd, EPOLL_CTL_DEL, manager.connect_timeout_timerfd, NULL);
805                 close(manager.connect_timeout_timerfd);
806                 manager.connect_timeout_timerfd = -1;
807         }
808
809         // Receive header
810         recv_len = recv(manager.host.control_socket,
811                        &msg_head,
812                        MSG_CMD_HDR_LEN, 0);
813         // error or close request from host
814         if (recv_len == -1 || recv_len == 0)
815                 return -11;
816         else {
817                 msg = malloc(MSG_CMD_HDR_LEN + msg_head.len);
818                 if (!msg) {
819                         LOGE("Cannot alloc msg\n");
820                         sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
821                         return -1;
822                 }
823                 msg->id = msg_head.id;
824                 msg->len = msg_head.len;
825                 if (msg->len > 0) {
826                         // Receive payload (if exists)
827                         recv_len = recv(manager.host.control_socket,
828                                         msg->payload,
829                                         msg->len, MSG_WAITALL);
830                         if (recv_len == -1)
831                                 return -11;
832                 }
833                 res = host_message_handler(msg);
834                 free(msg);
835         }
836
837         return res;
838 }
839
840 static void epoll_add_input_events()
841 {
842         struct epoll_event ev;
843         int i;
844
845         // add device fds to epoll event pool
846         ev.events = EPOLLIN;
847         for (i = 0; g_key_dev[i].fd != ARRAY_END; i++) {
848                 if (g_key_dev[i].fd >= 0) {
849                         ev.data.fd = g_key_dev[i].fd;
850                         if (epoll_ctl(manager.efd,
851                                       EPOLL_CTL_ADD,
852                                       g_key_dev[i].fd, &ev) < 0)
853                                 LOGE("keyboard device file epoll_ctl error\n");
854                 }
855         }
856
857         ev.events = EPOLLIN;
858         for (i = 0; g_touch_dev[i].fd != ARRAY_END; i++) {
859                 if (g_touch_dev[i].fd >= 0) {
860                         ev.data.fd = g_touch_dev[i].fd;
861                         if (epoll_ctl(manager.efd,
862                                       EPOLL_CTL_ADD,
863                                       g_touch_dev[i].fd, &ev) < 0)
864                                 LOGE("touch device file epoll_ctl error\n");
865                 }
866         }
867 }
868
869 static void epoll_del_input_events()
870 {
871         int i;
872
873         // remove device fds from epoll event pool
874         for (i = 0; g_key_dev[i].fd != ARRAY_END; i++)
875                 if (g_key_dev[i].fd >= 0)
876                         if (epoll_ctl(manager.efd,
877                                       EPOLL_CTL_DEL,
878                                       g_key_dev[i].fd, NULL) < 0)
879                                 LOGE("keyboard device file epoll_ctl error\n");
880
881         for (i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
882                 if (g_touch_dev[i].fd >= 0)
883                         if (epoll_ctl(manager.efd,
884                                       EPOLL_CTL_DEL,
885                                       g_touch_dev[i].fd, NULL) < 0)
886                                 LOGE("touch device file epoll_ctl error\n");
887 }
888 static bool initialize_epoll_events(void)
889 {
890         struct epoll_event ev;
891
892         if ((manager.efd = epoll_create1(0)) < 0) {
893           LOGE("epoll creation error\n");
894           return false;
895         }
896
897         // add server sockets to epoll event pool
898         ev.events = EPOLLIN;
899         ev.data.fd = manager.host_server_socket;
900         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
901                      manager.host_server_socket, &ev) < 0)
902         {
903                 LOGE("Host server socket epoll_ctl error\n");
904                 return false;
905         }
906         ev.events = EPOLLIN;
907         ev.data.fd = manager.target_server_socket;
908         if (epoll_ctl(manager.efd, EPOLL_CTL_ADD,
909                       manager.target_server_socket, &ev) < 0)
910         {
911                 LOGE("Target server socket epoll_ctl error\n");
912                 return false;
913         }
914         return true;
915 }
916
917 // return 0 for normal case
918 int daemonLoop()
919 {
920         int return_value = 0;
921         struct epoll_event *events = malloc(EPOLL_SIZE * sizeof(*events));
922
923         _get_fds(g_key_dev, INPUT_ID_KEY);
924         _get_fds(g_touch_dev, INPUT_ID_TOUCH);
925
926         if (!events) {
927                 LOGE("Out of memory when allocate epoll event pool\n");
928                 return_value = -1;
929                 goto END_EVENT;
930         }
931         if (!initialize_epoll_events()) {
932                 return_value = -1;
933                 goto END_EFD;
934         }
935
936         if (launch_timer_start() < 0) {
937                 LOGE("Launch timer start failed\n");
938                 return_value = -1;
939                 goto END_EFD;
940         }
941         // handler loop
942         while (1) {
943                 int i, k;
944                 ssize_t recvLen;
945                 // number of occured events
946                 int numevent = epoll_wait(manager.efd, events, EPOLL_SIZE, -1);
947                 if (numevent <= 0) {
948                         LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
949                         continue;
950                 }
951
952                 for(i = 0; i < numevent; i++)
953                 {
954                         // check for request from event fd
955                         for(k = 0; k < MAX_TARGET_COUNT; k++)
956                         {
957                                 if(manager.target[k].socket != -1 &&
958                                                 events[i].data.fd == manager.target[k].event_fd)
959                                 {
960                                         uint64_t u;
961                                         recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
962                                         if(recvLen != sizeof(uint64_t))
963                                         {
964                                                 // maybe closed, but ignoring is more safe then
965                                                 // removing fd from epoll list
966                                         }
967                                         else
968                                         {
969                                                 if(-11 == targetEventHandler(manager.efd, k, u))
970                                                 {
971                                                         LOGI("all target process is closed\n");
972                                                         continue;
973                                                 }
974                                         }
975                                         break;
976                                 }
977                         }
978
979                         if(k != MAX_TARGET_COUNT)
980                                 continue;
981
982                         // check for request from device fd
983                         for(k = 0; g_touch_dev[k].fd != ARRAY_END; k++)
984                         {
985                                 if(g_touch_dev[k].fd >= 0 && 
986                                                 events[i].data.fd == g_touch_dev[k].fd)
987                                 {
988                                         if(deviceEventHandler(&g_touch_dev[k], INPUT_ID_TOUCH) < 0)
989                                         {
990                                                 LOGE("Internal DA framework error, "
991                                                          "Please re-run the profiling (touch dev)\n");
992                                                 continue;
993                                         }
994                                         break;
995                                 }
996                         }
997
998                         if(g_touch_dev[k].fd != ARRAY_END)
999                                 continue;
1000
1001                         for(k = 0; g_key_dev[k].fd != ARRAY_END; k++)
1002                         {
1003                                 if(g_key_dev[k].fd >= 0 && 
1004                                                 events[i].data.fd == g_key_dev[k].fd)
1005                                 {
1006                                         if(deviceEventHandler(&g_key_dev[k], INPUT_ID_KEY) < 0)
1007                                         {
1008                                                 LOGE("Internal DA framework error, "
1009                                                          "Please re-run the profiling (key dev)\n");
1010                                                 continue;
1011                                         }
1012                                         break;
1013                                 }
1014                         }
1015
1016                         if(g_key_dev[k].fd != ARRAY_END)
1017                                 continue;
1018
1019                         // connect request from target
1020                         if (events[i].data.fd == manager.target_server_socket)
1021                         {
1022                                 if (targetServerHandler(manager.efd) < 0)       // critical error
1023                                 {
1024                                         terminate_error("Internal DA framework error, "
1025                                                                         "Please re-run the profiling (targetServerHandler)\n", 1);
1026                                         continue;
1027                                 }
1028                         }
1029                         // connect request from host
1030                         else if (events[i].data.fd == manager.host_server_socket)
1031                         {
1032                                 int result = hostServerHandler(manager.efd);
1033                                 if (result < 0)
1034                                 {
1035                                         LOGE("Internal DA framework error (hostServerHandler)\n");
1036                                         continue;
1037                                 }
1038                         }
1039                         // control message from host
1040                         else if (events[i].data.fd == manager.host.control_socket)
1041                         {
1042                                 int result = controlSocketHandler(manager.efd);
1043                                 if (result == -11)      // socket close
1044                                 {
1045                                         //if the host disconnected.
1046                                         //In all other cases daemon must report an error and continue the loop
1047                                         //close connect_timeoutt and host socket and quit
1048                                         LOGI("Connection closed. Termination. (%d)\n",
1049                                              manager.host.control_socket);
1050                                         return_value = 0;
1051                                         goto END_EFD;
1052                                 }
1053                                 else if (result < 0)
1054                                 {
1055                                         terminate_error("Internal DA framework error, "
1056                                                         "Please re-run the profiling.", 1);
1057                                         return_value = -1;
1058                                         goto END_EFD;
1059                                 }
1060                         }
1061                         else if (events[i].data.fd == manager.host.data_socket)
1062                         {
1063                                 char recvBuf[32];
1064                                 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1065                                 if (recvLen == 0)
1066                                 {       // close data socket
1067                                         epoll_ctl(manager.efd, EPOLL_CTL_DEL,
1068                                                   manager.host.data_socket,
1069                                                   NULL);
1070                                         close(manager.host.data_socket);
1071                                         manager.host.data_socket = -1;
1072                                         // TODO: finish transfer thread
1073                                 }
1074
1075                                 LOGI("host message from data socket %d\n", recvLen);
1076                         }
1077                         // check for application launch timerfd
1078                         else if (events[i].data.fd == manager.app_launch_timerfd)
1079                         {
1080                                 // send to host timeout error message for launching application
1081                                 LOGE("Failed to launch application\n");
1082                                 if (stop_app_launch_timer()<0)
1083                                         LOGE("cannot stop app launch timer\n");
1084                                 continue;
1085                         }
1086                         // check for connection timeout timerfd
1087                         else if (events[i].data.fd == manager.connect_timeout_timerfd)
1088                         {
1089                                 // send to host timeout error message for launching application
1090                                 terminate_error("no incoming connections", 1);
1091                                 epoll_ctl(manager.efd, EPOLL_CTL_DEL,
1092                                           manager.connect_timeout_timerfd, NULL);
1093                                 close(manager.connect_timeout_timerfd);
1094                                 manager.connect_timeout_timerfd = -1;
1095                                 LOGE("No connection in %d sec. shutdown.\n",MAX_CONNECT_TIMEOUT_TIME);
1096                                 goto END_EFD;
1097                         }
1098                         // unknown socket
1099                         else
1100                         {
1101                                 // never happened
1102                                 LOGW("Unknown socket fd (%d)\n", events[i].data.fd);
1103                         }
1104                 }
1105         }
1106
1107 END_EFD:
1108         LOGI("close efd\n");
1109         close(manager.efd);
1110 END_EVENT:
1111         free(events);
1112         return return_value;
1113 }