be0979eeed134aa077c53bb31e3a0289131456de
[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/timerfd.h>        // for timerfd
44 #include <unistd.h>             // for access, sleep
45 #include <stdbool.h>
46 #include <linux/netlink.h>
47 #include <linux/connector.h>
48
49 #include <ctype.h>
50
51 #include <fcntl.h>
52
53 #include <assert.h>
54
55 #include <Ecore.h>
56
57 #include "daemon.h"
58 #include "sys_stat.h"
59 #include "utils.h"
60 #include "da_protocol.h"
61 #include "da_inst.h"
62 #include "da_data.h"
63 #include "input_events.h"
64 #include "smack.h"
65 #include "us_interaction_msg.h"
66 #include "freezing.h"
67 #include "debug.h"
68
69 #define DA_WORK_DIR                     "/home/developer/sdk_tools/da/"
70 #define DA_READELF_PATH                 "/home/developer/sdk_tools/da/readelf"
71 #define SCREENSHOT_DIR                  "/tmp/da"
72
73 #define MAX_APP_LAUNCH_TIME             60
74 #define MAX_CONNECT_TIMEOUT_TIME        5*60
75
76 uint64_t get_total_alloc_size(void)
77 {
78         int i;
79         uint64_t allocsize = 0;
80
81         for (i = 0; i < MAX_TARGET_COUNT; i++) {
82                 if (manager.target[i].socket != -1 &&
83                     manager.target[i].allocmem > 0)
84                         allocsize += manager.target[i].allocmem;
85         }
86         return allocsize;
87 }
88
89 static int getEmptyTargetSlot()
90 {
91         int i;
92         for (i = 0; i < MAX_TARGET_COUNT; i++) {
93                 if (manager.target[i].socket == -1)
94                         break;
95         }
96
97         return i;
98 }
99
100 static void setEmptyTargetSlot(int index)
101 {
102         if (index >= 0 && index < MAX_TARGET_COUNT) {
103                 manager.target[index].pid = -1;
104                 manager.target[index].recv_thread = -1;
105                 manager.target[index].allocmem = 0;
106                 manager.target[index].initial_log = 0;
107                 if (manager.target[index].event_fd != -1)
108                         close(manager.target[index].event_fd);
109                 manager.target[index].event_fd = -1;
110                 if (manager.target[index].socket != -1)
111                         close(manager.target[index].socket);
112                 manager.target[index].socket = -1;
113         }
114 }
115
116 // =============================================================================
117 // start and terminate control functions
118 // =============================================================================
119
120 static Ecore_Fd_Handler *launch_timer_handler;
121
122 //stop application launch timer
123 static int stop_app_launch_timer()
124 {
125         close(manager.app_launch_timerfd);
126         manager.app_launch_timerfd = -1;
127
128         return 0;
129 }
130
131 static Eina_Bool launch_timer_cb(void *data, Ecore_Fd_Handler *fd_handler)
132 {
133         LOGE("Failed to launch application\n");
134         if (stop_app_launch_timer() < 0)
135                 LOGE("cannot stop app launch timer\n");
136
137         return ECORE_CALLBACK_CANCEL;
138 }
139
140 //start application launch timer function
141 static int start_app_launch_timer(int apps_count)
142 {
143         int res = 0;
144
145         assert(apps_count >= 0 && "negative apps count");
146
147         if (apps_count == 0)
148                 return res;
149
150         manager.app_launch_timerfd =
151             timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
152         if (manager.app_launch_timerfd > 0) {
153                 struct itimerspec ctime;
154                 ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME * apps_count;
155                 ctime.it_value.tv_nsec = 0;
156                 ctime.it_interval.tv_sec = 0;
157                 ctime.it_interval.tv_nsec = 0;
158                 if (timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL) < 0) {
159                         LOGE("fail to set app launch timer\n");
160                         stop_app_launch_timer();
161                         res = -1;
162                 } else {
163                         launch_timer_handler =
164                                 ecore_main_fd_handler_add(manager.app_launch_timerfd,
165                                                           ECORE_FD_READ,
166                                                           launch_timer_cb,
167                                                           NULL,
168                                                           NULL, NULL);
169                         if (!launch_timer_handler) {
170                                 LOGE("fail to add app launch timer fd to \n");
171                                 stop_app_launch_timer();
172                                 res = -2;
173                         } else {
174                                 LOGI("application launch time started\n");
175                         }
176                 }
177         } else {
178                 LOGE("cannot create launch timer\n");
179                 res = -3;
180         }
181
182         return res;
183 }
184
185 static inline void inc_apps_to_run()
186 {
187         manager.apps_to_run++;
188 }
189
190 static inline void dec_apps_to_run()
191 {
192         if (manager.apps_to_run > 0)
193                 manager.apps_to_run--;
194 }
195
196 static inline int get_apps_to_run()
197 {
198         return manager.apps_to_run;
199 }
200
201 static int kill_app_by_info(const struct app_info_t *app_info)
202 {
203         int res = 0;
204
205         if (app_info == NULL) {
206                 LOGE("Cannot exec app. app_info is NULL");
207                 return -1;
208         }
209
210         switch (app_info->app_type) {
211         case APP_TYPE_TIZEN:
212                 res = kill_app(app_info->exe_path);
213                 break;
214         case APP_TYPE_RUNNING:
215                 // TODO: nothing, it's running
216                 LOGI("already started\n");
217                 break;
218         case APP_TYPE_COMMON:
219                 res = kill_app(app_info->exe_path);
220                 break;
221         case APP_TYPE_WEB:
222                 /* do nothing (it is restarted by itself) */
223                 break;
224         default:
225                 LOGE("Unknown app type %d\n", app_info->app_type);
226                 res = -1;
227                 break;
228         }
229
230         return res;
231 }
232
233 static int exec_app(const struct app_info_t *app_info)
234 {
235         int res = 0;
236
237         if (app_info == NULL) {
238                 LOGE("Cannot exec app. app_info is NULL");
239                 return -1;
240         }
241
242         switch (app_info->app_type) {
243         case APP_TYPE_TIZEN:
244                 if (exec_app_tizen(app_info->app_id, app_info->exe_path)) {
245                         LOGE("Cannot exec tizen app %s\n", app_info->app_id);
246                         res = -1;
247                 } else {
248                         inc_apps_to_run();
249                 }
250                 break;
251         case APP_TYPE_RUNNING:
252                 // TODO: nothing, it's running
253                 LOGI("already started\n");
254                 break;
255         case APP_TYPE_COMMON:
256                 if (exec_app_common(app_info->exe_path)) {
257                         LOGE("Cannot exec common app %s\n", app_info->exe_path);
258                         res = -1;
259                 } else {
260                         inc_apps_to_run();
261                 }
262                 break;
263         case APP_TYPE_WEB:
264                 if (exec_app_web(app_info->app_id)) {
265                         LOGE("Cannot exec web app %s\n", app_info->app_id);
266                         res = -1;
267                 }
268                 break;
269         default:
270                 LOGE("Unknown app type %d\n", app_info->app_type);
271                 res = -1;
272                 break;
273         }
274
275         LOGI("ret=%d\n", res);
276         return res;
277 }
278
279 // just send stop message to all target process
280 static void terminate_all_target()
281 {
282         int i;
283         ssize_t sendlen;
284         msg_target_t sendlog;
285
286         sendlog.type = MSG_STOP;
287         sendlog.length = 0;
288
289         for (i = 0; i < MAX_TARGET_COUNT; i++) {
290                 if (manager.target[i].socket != -1) {
291                         sendlen = send(manager.target[i].socket, &sendlog,
292                                        sizeof(sendlog.type) +
293                                        sizeof(sendlog.length), MSG_NOSIGNAL);
294                         if (sendlen != -1) {
295                                 LOGI("TERMINATE send exit msg (socket %d) "
296                                      "by terminate_all_target()\n",
297                                      manager.target[i].socket);
298                         }
299                 }
300         }
301 }
302
303 // terminate all target and wait for threads
304 void terminate_all()
305 {
306         int i;
307         terminate_all_target();
308
309         // wait for all other thread exit
310         for (i = 0; i < MAX_TARGET_COUNT; i++) {
311                 if (manager.target[i].recv_thread != -1) {
312                         LOGI("join recv thread [%d] is started\n", i);
313                         pthread_join(manager.target[i].recv_thread, NULL);
314                         LOGI("join recv thread %d. done\n", i);
315                 }
316         }
317 }
318
319 // terminate all profiling by critical error
320 // TODO: don't send data to host
321 static void terminate_error(char *errstr, int send_to_host)
322 {
323         LOGE("termination all with err '%s'\n", errstr);
324         struct msg_data_t *msg = NULL;
325         if (send_to_host != 0) {
326                 msg = gen_message_error(errstr);
327                 if (msg) {
328                         write_to_buf(msg);
329                         free_msg_data(msg);
330                 } else {
331                         LOGI("cannot generate error message\n");
332                 }
333         }
334         terminate_all();
335 }
336
337 static Ecore_Fd_Handler *connect_timer_handler;
338
339 static Eina_Bool connect_timer_cb(void *data, Ecore_Fd_Handler *fd_handler)
340 {
341         terminate_error("no incoming connections", 1);
342         close(manager.connect_timeout_timerfd);
343         manager.connect_timeout_timerfd = -1;
344         LOGE("No connection in %d sec. shutdown.\n",
345              MAX_CONNECT_TIMEOUT_TIME);
346         ecore_main_loop_quit();
347
348         return ECORE_CALLBACK_CANCEL;
349 }
350
351 static int launch_timer_start(void)
352 {
353         int res = 0;
354
355         manager.connect_timeout_timerfd =
356             timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
357         if (manager.connect_timeout_timerfd > 0) {
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                         LOGE("fail to set connect timeout timer\n");
365                         close(manager.connect_timeout_timerfd);
366                         manager.connect_timeout_timerfd = -1;
367                 } else {
368                         connect_timer_handler =
369                                 ecore_main_fd_handler_add(manager.connect_timeout_timerfd,
370                                                           ECORE_FD_READ,
371                                                           connect_timer_cb,
372                                                           NULL,
373                                                           NULL, NULL);
374                         if (!connect_timer_handler) {
375                                 LOGE("fail to add app connection timeout timer fd\n");
376                                 close(manager.connect_timeout_timerfd);
377                                 manager.connect_timeout_timerfd = -1;
378                         } else {
379                                 LOGI("connection timeout timer started\n");
380                         }
381                 }
382         } else {
383                 LOGE("cannot create connection timeout timer\n");
384         }
385
386         LOGI("ret=%d\n", res);
387         return res;
388 }
389
390 int prepare_profiling(void)
391 {
392         struct app_list_t *app = NULL;
393         const struct app_info_t *app_info = NULL;
394
395         app_info = app_info_get_first(&app);
396         if (app_info == NULL) {
397                 LOGE("No app info found\n");
398                 return -1;
399         }
400
401         //all apps
402         while (app_info != NULL) {
403                 if (kill_app_by_info(app_info) != 0) {
404                         LOGE("kill app failed\n");
405                         return -1;
406                 }
407                 app_info = app_info_get_next(&app);
408         }
409         //init rw for systeminfo
410         //init recv send network systeminfo
411         sys_stat_prepare();
412         return 0;
413
414 }
415
416 int start_profiling(void)
417 {
418         struct app_list_t *app = NULL;
419         const struct app_info_t *app_info = NULL;
420         int res = 0;
421
422         app_info = app_info_get_first(&app);
423         if (app_info == NULL) {
424                 LOGE("No app info found\n");
425                 return -1;
426         }
427         // remove previous screen capture files
428         remove_indir(SCREENSHOT_DIR);
429         if (mkdir(SCREENSHOT_DIR, 0777) == -1 && errno != EEXIST)
430                 LOGW("Failed to create directory for screenshot : %s\n",
431                      strerror(errno));
432
433         set_label_for_all(SCREENSHOT_DIR);
434
435         if (samplingStart() < 0) {
436                 LOGE("Cannot start sampling\n");
437                 res = -1;
438                 goto exit;
439         }
440
441         if (IS_OPT_SET(FL_RECORDING))
442                 add_input_events();
443
444         while (app_info != NULL) {
445                 if (exec_app(app_info)) {
446                         LOGE("Cannot exec app\n");
447                         res = -1;
448                         goto recording_stop;
449                 }
450                 app_info = app_info_get_next(&app);
451         }
452
453         if (start_app_launch_timer(get_apps_to_run()) < 0) {
454                 res = -1;
455                 goto recording_stop;
456         }
457
458         goto exit;
459
460  recording_stop:
461         if (IS_OPT_SET(FL_RECORDING))
462                 del_input_events();
463         samplingStop();
464
465  exit:
466         LOGI("return %d\n", res);
467         return res;
468 }
469
470 void stop_profiling(void)
471 {
472         if (IS_OPT_SET(FL_RECORDING))
473                 del_input_events();
474         samplingStop();
475 }
476
477 static void reconfigure_recording(struct conf_t conf)
478 {
479         uint64_t old_features = prof_session.conf.use_features0;
480         uint64_t new_features = conf.use_features0;
481         uint64_t to_enable = (new_features ^ old_features) & new_features;
482         uint64_t to_disable = (new_features ^ old_features) & old_features;
483
484         if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) {
485                 del_input_events();
486                 prof_session.conf.use_features0 &= ~FL_RECORDING;
487         }
488
489         if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) {
490                 add_input_events();
491                 prof_session.conf.use_features0 |= FL_RECORDING;
492         }
493
494 }
495
496 int reconfigure(struct conf_t conf)
497 {
498         reconfigure_recording(conf);
499
500         samplingStop();
501         memcpy(&prof_session.conf, &conf, sizeof(conf));
502         if (samplingStart() < 0) {
503                 LOGE("Cannot start sampling\n");
504                 return -1;
505         }
506
507         return 0;
508 }
509
510 static Ecore_Fd_Handler *target_handlers[MAX_TARGET_COUNT];
511
512 static int target_event_pid_handler(int index, uint64_t msg)
513 {
514         struct app_list_t *app = NULL;
515         struct app_info_t *app_info = NULL;
516         if (index == 0) {       // main application
517                 app_info = app_info_get_first(&app);
518                 if (app_info == NULL) {
519                         LOGE("No app info found\n");
520                         return -1;
521                 }
522
523                 while (app_info != NULL) {
524                         if (is_same_app_process(app_info->exe_path,
525                                                 manager.target[index].pid))
526                                 break;
527                         app_info = app_info_get_next(&app);
528                 }
529
530                 if (app_info == NULL) {
531                         LOGE("pid %d not found in app list\n",
532                              manager.target[index].pid);
533                         return -1;
534                 }
535
536                 if (start_replay() != 0) {
537                         LOGE("Cannot start replay thread\n");
538                         return -1;
539                 }
540         }
541         manager.target[index].initial_log = 1;
542         return 0;
543 }
544
545 static int target_event_stop_handler(int index, uint64_t msg)
546 {
547         LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
548              manager.target[index].socket, manager.target[index].pid,
549              manager.target_count - 1);
550
551         if (index == 0)         // main application
552                 stop_replay();
553
554         ecore_main_fd_handler_del(target_handlers[index]);
555
556         setEmptyTargetSlot(index);
557         // all target client are closed
558         if (0 == __sync_sub_and_fetch(&manager.target_count, 1)) {
559                 LOGI("all targets are stopped\n");
560                 if (stop_all() != ERR_NO)
561                         LOGE("Stop failed\n");
562                 return -11;
563         }
564
565         return 0;
566 }
567
568 // return 0 if normal case
569 // return plus value if non critical error occur
570 // return minus value if critical error occur
571 // return -11 if all target process closed
572 static int target_event_handler(int index, uint64_t msg)
573 {
574         int err = 0;
575         if (msg & EVENT_PID)
576                 err = target_event_pid_handler(index, msg);
577         if (err)
578                 return err;
579
580         if (msg & EVENT_STOP || msg & EVENT_ERROR)
581                 err = target_event_stop_handler(index, msg);
582
583         return err;
584 }
585
586 static Eina_Bool target_event_cb(void *data, Ecore_Fd_Handler *fd_handler)
587 {
588         uint64_t u;
589         ssize_t recvLen;
590         int index = (int)data;
591
592         recvLen = read(manager.target[index].event_fd, &u, sizeof(uint64_t));
593         if (recvLen != sizeof(uint64_t)) {
594                 // maybe closed, but ignoring is more safe then
595                 // removing fd from event loop
596         } else {
597                 if (-11 == target_event_handler(index, u)) {
598                         LOGI("all target process is closed\n");
599                 }
600         }
601
602         return ECORE_CALLBACK_RENEW;
603 }
604
605 /**
606  * return 0 if normal case
607  * return plus value if non critical error occur
608  * return minus value if critical error occur
609  */
610 static int targetServerHandler(void)
611 {
612         msg_target_t log, pid_msg;
613         ssize_t recvlen;
614
615         int index = getEmptyTargetSlot();
616         if (index == MAX_TARGET_COUNT) {
617                 LOGW("Max target number(8) reached, no more target can connected\n");
618                 return 1;
619         }
620
621         manager.target[index].socket =
622                 accept(manager.target_server_socket, NULL, NULL);
623
624         if (manager.target[index].socket >= 0) {
625                 /* accept succeed */
626                 fd_setup_attributes(manager.target[index].socket);
627
628                 /* send config message to target process */
629                 log.type = MSG_OPTION;
630                 log.length = sprintf(log.data, "%llu",
631                                      prof_session.conf.use_features0);
632                 if (0 > send(manager.target[index].socket, &log,
633                              sizeof(log.type) + sizeof(log.length) + log.length,
634                              MSG_NOSIGNAL))
635                         LOGE("fail to send data to target index(%d)\n", index);
636
637                 // make event fd
638                 manager.target[index].event_fd = eventfd(EFD_CLOEXEC, EFD_NONBLOCK);
639                 if (manager.target[index].event_fd == -1) {
640                         // fail to make event fd
641                         LOGE("fail to make event fd for socket (%d)\n",
642                              manager.target[index].socket);
643                         goto TARGET_CONNECT_FAIL;
644                 }
645
646                 target_handlers[index] =
647                         ecore_main_fd_handler_add(manager.target[index].event_fd,
648                                                   ECORE_FD_READ,
649                                                   target_event_cb,
650                                                   (void *)index,
651                                                   NULL, NULL);
652                 if (!target_handlers[index]) {
653                         LOGE("fail to add event fd for socket (%d)\n",
654                              manager.target[index].socket);
655                         goto TARGET_CONNECT_FAIL;
656                 }
657
658                 // make recv thread for target
659                 if (makeRecvThread(index) != 0) {
660                         // fail to make recv thread
661                         LOGE("fail to make recv thread for socket (%d)\n",
662                              manager.target[index].socket);
663                         ecore_main_fd_handler_del(target_handlers[index]);
664                         goto TARGET_CONNECT_FAIL;
665                 }
666
667                 dec_apps_to_run();
668
669                 if ((manager.app_launch_timerfd > 0) && (get_apps_to_run() == 0)) {
670                         if (stop_app_launch_timer() < 0)
671                                 LOGE("cannot stop app launch timer\n");
672                 }
673
674                 LOGI("target connected = %d(running %d target)\n",
675                      manager.target[index].socket, manager.target_count + 1);
676
677                 manager.target_count++;
678                 return 0;
679         } else {
680                 // accept error
681                 LOGE("Failed to accept at target server socket\n");
682         }
683
684  TARGET_CONNECT_FAIL:
685         if (manager.target_count == 0) {
686                 // if this connection is main connection
687                 return -1;
688         } else {
689                 // if this connection is not main connection then ignore process by error
690                 setEmptyTargetSlot(index);
691                 return 1;
692         }
693 }
694
695 static Ecore_Fd_Handler *host_ctrl_handler;
696 static Ecore_Fd_Handler *host_data_handler;
697
698 // return plus value if non critical error occur
699 // return minus value if critical error occur
700 // return -11 if socket closed
701 static int controlSocketHandler(int efd)
702 {
703         ssize_t recv_len;
704         struct msg_t msg_head;
705         struct msg_t *msg;
706         int res = 0;
707
708         if (manager.connect_timeout_timerfd >= 0) {
709                 LOGI("release connect timeout timer\n");
710                 close(manager.connect_timeout_timerfd);
711                 manager.connect_timeout_timerfd = -1;
712         }
713         // Receive header
714         recv_len = recv(manager.host.control_socket,
715                         &msg_head, MSG_CMD_HDR_LEN, 0);
716         // error or close request from host
717         if (recv_len == -1 || recv_len == 0)
718                 return -11;
719         else {
720                 msg = malloc(MSG_CMD_HDR_LEN + msg_head.len);
721                 if (!msg) {
722                         LOGE("Cannot alloc msg\n");
723                         sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
724                         return -1;
725                 }
726                 msg->id = msg_head.id;
727                 msg->len = msg_head.len;
728                 if (msg->len > 0) {
729                         // Receive payload (if exists)
730                         recv_len = recv(manager.host.control_socket,
731                                         msg->payload, msg->len, MSG_WAITALL);
732                         if (recv_len == -1)
733                                 return -11;
734                 }
735                 printBuf((char *)msg, MSG_CMD_HDR_LEN + msg->len);
736                 res = host_message_handler(msg);
737                 free(msg);
738         }
739
740         return res;
741 }
742
743 static Eina_Bool host_ctrl_cb(void *data, Ecore_Fd_Handler *fd_handler)
744 {
745         int result = controlSocketHandler(manager.efd);
746         if (result == -11) {
747                 // socket close
748                 //if the host disconnected.
749                 //In all other cases daemon must report an error and continue the loop
750                 //close connect_timeoutt and host socket and quit
751                 LOGI("Connection closed. Termination. (%d)\n",
752                      manager.host.control_socket);
753                 ecore_main_loop_quit();
754         } else if (result < 0) {
755                 LOGE("Control socket handler.\n");
756         }
757
758         return ECORE_CALLBACK_RENEW;
759 }
760
761 static Eina_Bool host_data_cb(void *data, Ecore_Fd_Handler *fd_handler)
762 {
763         ssize_t recvLen;
764         char recvBuf[32];
765
766         recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
767         if (recvLen == 0) {
768                 // close data socket
769                 ecore_main_fd_handler_del(host_data_handler);
770                 close(manager.host.data_socket);
771                 manager.host.data_socket = -1;
772                 // TODO: finish transfer thread
773         }
774
775         LOGI("host message from data socket %d\n", recvLen);
776
777         return ECORE_CALLBACK_RENEW;
778 }
779
780 // return 0 if normal case
781 // return plus value if non critical error occur
782 // return minus value if critical error occur
783 static int hostServerHandler(void)
784 {
785         static int hostserverorder = 0;
786         int csocket;
787
788         if (hostserverorder > 1)        // control and data socket connected already
789                 return 1;               // ignore
790
791         csocket = accept(manager.host_server_socket, NULL, NULL);
792
793         if (csocket >= 0) {
794                 // accept succeed
795
796                 if (hostserverorder == 0) {
797                         manager.host.control_socket = csocket;
798                         unlink_portfile();
799                         LOGI("host control socket connected = %d\n", csocket);
800                         host_ctrl_handler =
801                                 ecore_main_fd_handler_add(manager.host.control_socket,
802                                                           ECORE_FD_READ,
803                                                           host_ctrl_cb,
804                                                           NULL,
805                                                           NULL, NULL);
806                         if (!host_ctrl_handler) {
807                                 LOGE("Failed to add host control socket fd\n");
808                                 close(csocket);
809                                 return -1;
810                         }
811                 } else {
812                         manager.host.data_socket = csocket;
813                         LOGI("host data socket connected = %d\n", csocket);
814
815                         host_data_handler =
816                                 ecore_main_fd_handler_add(manager.host.data_socket,
817                                                           ECORE_FD_READ,
818                                                           host_data_cb,
819                                                           NULL,
820                                                           NULL, NULL);
821                         if (!host_data_handler) {
822                                 LOGE("Failed to add host data socket fd\n");
823                                 close(csocket);
824                                 return -1;
825                         }
826                 }
827
828                 hostserverorder++;
829                 return 0;
830         } else {
831                 // accept error
832                 LOGE("Failed to accept from host server socket\n");
833                 return -1;
834         }
835 }
836
837 static int kernel_handler(void)
838 {
839         int res, size, ret;
840         socklen_t optlen;
841         struct nlmsghdr *nlh;
842         struct cn_msg *msg;
843         ssize_t len;
844
845         /* Get buffer size */
846         optlen = sizeof(size);
847
848         /* We're using SOCK_DGRAM, so, get it maximum size */
849         res = getsockopt(manager.kernel_socket, SOL_SOCKET, SO_SNDBUF, &size,
850                          &optlen);
851
852         if (res == -1) {
853                 LOGE("Get maximum buffer size failed\n");
854                 return -1;
855         }
856
857         /* Alloc mem for nlh message struct and receive it */
858         nlh = malloc(size);
859         if (nlh == NULL)
860                 return -1;
861         len = recv(manager.kernel_socket, nlh, size, 0);
862         if ((len <= 0) || (nlh->nlmsg_len == 0)) {
863                 ret = -1;
864                 goto free_and_end;
865         }
866
867         /* nlh data field contains connectors message */
868         msg = NLMSG_DATA(nlh);
869         if (msg->len == 0) {
870                 ret = -1;
871                 goto free_and_end;
872         }
873
874         switch(*(enum us_interaction_k2u_msg_t *) msg->data) {
875         case US_INT_PAUSE_APPS:
876                 freeze_subgroup();
877                 break;
878         case US_INT_CONT_APPS:
879                 thaw_subgroup();
880                 break;
881         default:
882                 LOGE("Unknown command\n");
883         }
884
885         /* Insert your message handler here */
886
887         ret = 0;
888
889 free_and_end:
890         free(nlh);
891
892         return ret;
893 }
894
895
896 static Ecore_Fd_Handler *host_connect_handler;
897 static Ecore_Fd_Handler *target_connect_handler;
898 static Ecore_Fd_Handler *kernel_connect_handler;
899
900 static Eina_Bool host_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
901 {
902         // connect request from host
903         int result = hostServerHandler();
904         if (result < 0) {
905                 LOGE("Internal DA framework error (hostServerHandler)\n");
906         }
907
908         return ECORE_CALLBACK_RENEW;
909 }
910
911 static Eina_Bool target_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
912 {
913         if (targetServerHandler() < 0) {
914                 // critical error
915                 terminate_error("Internal DA framework error, "
916                                 "Please re-run the profiling "
917                                 "(targetServerHandler)\n", 1);
918         }
919
920         return ECORE_CALLBACK_RENEW;
921 }
922
923 static Eina_Bool kernel_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
924 {
925         if (kernel_handler() < 0) {
926                 LOGE("Internal DA framework error (kernel_handler)\n");
927         }
928
929         return ECORE_CALLBACK_RENEW;
930 }
931
932 static bool initialize_events(void)
933 {
934         host_connect_handler =
935                 ecore_main_fd_handler_add(manager.host_server_socket,
936                                           ECORE_FD_READ,
937                                           host_connect_cb,
938                                           NULL,
939                                           NULL, NULL);
940         if (!host_connect_handler) {
941                 LOGE("Host server socket add error\n");
942                 return false;
943         }
944
945         target_connect_handler =
946                 ecore_main_fd_handler_add(manager.target_server_socket,
947                                           ECORE_FD_READ,
948                                           target_connect_cb,
949                                           NULL,
950                                           NULL, NULL);
951         if (!target_connect_handler) {
952                 LOGE("Target server socket add error\n");
953                 return false;
954         }
955
956         kernel_connect_handler =
957             ecore_main_fd_handler_add(manager.kernel_socket,
958                                       ECORE_FD_READ,
959                                       kernel_connect_cb,
960                                       NULL,
961                                       NULL, NULL);
962         if (!kernel_connect_handler) {
963                 LOGE("Kernel socket add error\n");
964                 return false;
965         }
966
967         return true;
968 }
969
970 // return 0 for normal case
971 int daemonLoop(void)
972 {
973         int return_value = 0;
974
975         ecore_init();
976
977         if (init_input_events() == -1) {
978                 return_value = -1;
979                 goto END_EVENT;
980         }
981
982         if (!initialize_events()) {
983                 return_value = -1;
984                 goto END_EFD;
985         }
986
987         if (launch_timer_start() < 0) {
988                 LOGE("Launch timer start failed\n");
989                 return_value = -1;
990                 goto END_EFD;
991         }
992
993         init_prof_session(&prof_session);
994
995         ecore_main_loop_begin();
996         ecore_shutdown();
997
998  END_EFD:
999         LOGI("close efd\n");
1000         close(manager.efd);
1001  END_EVENT:
1002         return return_value;
1003 }