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