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