[FIX] Some host build warnings
[platform/core/system/swap-manager.git] / daemon / daemon.c
1 /*
2 *  DA manager
3 *
4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: 
7 *
8 * Jaewon Lim <jaewon81.lim@samsung.com>
9 * Woojin Jung <woojin2.jung@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
11
12  * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 * Contributors:
25 * - S-Core Co., Ltd
26 *
27 */ 
28
29 #include <stdio.h>
30 #include <stdlib.h>                     // for realpath
31 #include <string.h>                     // for strtok, strcpy, strncpy
32 #include <limits.h>                     // for realpath
33
34 #include <errno.h>                      // for errno
35 #include <sys/types.h>          // for accept, mkdir, opendir, readdir
36 #include <sys/socket.h>         // for accept
37 #include <sys/stat.h>           // for mkdir
38 #include <sys/eventfd.h>        // for eventfd
39 #include <sys/epoll.h>          // for epoll apis
40 #include <sys/timerfd.h>        // for timerfd
41 #include <unistd.h>                     // for access, sleep
42 #ifndef HOST_BUILD
43 #include <attr/xattr.h>         // for fsetxattr
44 #endif
45 #include <linux/input.h>
46 #include <dirent.h>
47 #include <fcntl.h>
48 #ifndef HOST_BUILD
49 #include <sys/smack.h>
50 #endif
51 #include "daemon.h"
52 #include "sys_stat.h"
53 #include "utils.h"
54 #include "da_protocol.h"
55 #define DA_WORK_DIR                             "/home/developer/sdk_tools/da/"
56 #define DA_READELF_PATH                 "/home/developer/sdk_tools/da/readelf"
57 #define SCREENSHOT_DIR                  "/tmp/da"
58
59 #define EPOLL_SIZE                              10
60 #define MAX_CONNECT_SIZE                12
61 #define MAX_APP_LAUNCH_TIME             6
62
63 #define INPUT_ID_TOUCH                  0
64 #define INPUT_ID_KEY                    1       
65 #define STR_TOUCH                               "TOUCH"
66 #define STR_KEY                                 "KEY"
67 #define INPUT_ID_STR_KEY                "ID_INPUT_KEY=1"
68 #define INPUT_ID_STR_TOUCH              "ID_INPUT_TOUCHSCREEN=1"
69 #define INPUT_ID_STR_KEYBOARD   "ID_INPUT_KEYBOARD=1"
70 #define INPUT_ID_STR_TABLET             "ID_INPUT_TABLET=1"
71
72 #define MAX_DEVICE                              10
73 #define MAX_FILENAME                    128
74 #define BUF_SIZE                                1024
75 #define ARRAY_END                               (-11)
76
77 typedef struct _input_dev
78 {
79         int fd;
80         char fileName[MAX_FILENAME];
81 } input_dev;
82
83 input_dev g_key_dev[MAX_DEVICE];
84 input_dev g_touch_dev[MAX_DEVICE];
85
86 // return bytes size of readed data
87 // return 0 if no data readed or error occurred
88 static int _file_read(FILE* fp, char *buffer, int size)
89 {
90         int ret = 0;
91
92         if(fp != NULL && size > 0)
93         {
94                 ret = fread((void*)buffer, sizeof(char), size, fp);
95         }
96         else
97         {
98                 // fp is null
99                 if(size > 0)
100                         buffer[0] = '\0';
101
102                 ret = 0;        // error case
103         }
104
105         return ret;
106 }
107
108 // get input id of given input device
109 static int get_input_id(char* inputname)
110 {
111         static int query_cmd_type = 0;  // 1 if /lib/udev/input_id, 2 if udevadm
112         FILE* cmd_fp = NULL;
113         char buffer[BUF_SIZE];
114         char command[MAX_FILENAME];
115         int ret = -1;
116
117         // determine input_id query command
118         if(unlikely(query_cmd_type == 0))
119         {
120                 if(access("/lib/udev/input_id", F_OK) == 0)             // there is /lib/udev/input_id
121                 {
122                         query_cmd_type = 1;
123                 }
124                 else    // there is not /lib/udev/input_id
125                 {
126                         query_cmd_type = 2;
127                 }
128         }
129
130         // make command string
131         if(query_cmd_type == 1)
132         {
133                 sprintf(command, "/lib/udev/input_id /class/input/%s", inputname);
134         }
135         else
136         {
137                 sprintf(command, "udevadm info --name=input/%s --query=property", inputname);
138         }
139
140         // run command
141         cmd_fp = popen(command, "r");
142         _file_read(cmd_fp, buffer, BUF_SIZE);
143
144         // determine input id
145         if(strstr(buffer, INPUT_ID_STR_KEY))                    // key
146         {
147                 ret = INPUT_ID_KEY;
148         }
149         else if(strstr(buffer, INPUT_ID_STR_TOUCH))             // touch
150         {
151                 ret = INPUT_ID_TOUCH;
152         }
153         else if(strstr(buffer, INPUT_ID_STR_KEYBOARD))  // keyboard
154         {
155                 ret = INPUT_ID_KEY;
156         }
157         else if(strstr(buffer, INPUT_ID_STR_TABLET))    // touch (emulator)
158         {
159                 ret = INPUT_ID_TOUCH;
160         }
161
162         if(cmd_fp != NULL)
163                 pclose(cmd_fp);
164         return ret;
165 }
166
167 // get filename and fd of given input type devices
168 static void _get_fds(input_dev *dev, int input_id)
169 {
170         DIR *dp;
171         struct dirent *d;
172         int count = 0;
173
174         dp = opendir("/sys/class/input");
175
176         if(dp != NULL)
177         {
178                 while((d = readdir(dp)) != NULL)
179                 {
180                         if(!strncmp(d->d_name, "event", 5))     // start with "event"
181                         {
182                                 // event file
183                                 if(input_id == get_input_id(d->d_name))
184                                 {
185                                         sprintf(dev[count].fileName, "/dev/input/%s", d->d_name);
186                                         dev[count].fd = open(dev[count].fileName, O_RDWR | O_NONBLOCK);
187                                         count++;
188                                 }
189                         }
190                 }
191
192                 closedir(dp);
193         }
194         dev[count].fd = ARRAY_END;      // end of input_dev array
195 }
196
197 static void _device_write(input_dev *dev, struct input_event* in_ev)
198 {
199         int i;
200         for(i = 0; dev[i].fd != ARRAY_END; i++)
201         {
202                 if(dev[i].fd >= 0)
203                         write(dev[i].fd, in_ev, sizeof(struct input_event));
204         }
205 }
206
207 long long get_total_alloc_size()
208 {
209         int i;
210         long long allocsize = 0;
211
212         for(i = 0; i < MAX_TARGET_COUNT; i++)
213         {
214                 if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0)
215                         allocsize += manager.target[i].allocmem;
216         }
217         return allocsize;
218 }
219
220 static int getEmptyTargetSlot()
221 {
222         int i;
223         for(i = 0; i < MAX_TARGET_COUNT; i++)
224         {
225                 if(manager.target[i].socket == -1)
226                         break;
227         }
228
229         return i;
230 }
231
232 static void setEmptyTargetSlot(int index)
233 {
234         if(index >= 0 && index < MAX_TARGET_COUNT)
235         {
236                 manager.target[index].pid = -1;
237                 manager.target[index].recv_thread = -1;
238                 manager.target[index].allocmem = 0;
239                 manager.target[index].starttime = 0;
240                 manager.target[index].initial_log = 0;
241                 if(manager.target[index].event_fd != -1)
242                         close(manager.target[index].event_fd);
243                 manager.target[index].event_fd = -1;
244                 if(manager.target[index].socket != -1)
245                         close(manager.target[index].socket);
246                 manager.target[index].socket = -1;
247         }
248 }
249
250 // ======================================================================================
251 // send functions to host
252 // ======================================================================================
253
254 int pseudoSendDataToHost(struct msg_data_t* log)
255 {
256         uint32_t total_len = 
257                                         sizeof(log->id) +
258                                         sizeof(log->sequence) +
259                                         sizeof(uint64_t) + //time
260                                         sizeof(log->len);
261
262         char *buf = malloc(total_len+log->len);
263         char *p = buf;
264         memset(p,0,total_len);
265
266         pack_int(p,log->id);
267         pack_int(p,log->sequence);
268         pack_time(p,log->time);
269         pack_int(p,log->len);
270
271         memcpy(p,log->payload,log->len);
272         printBuf(buf,total_len+log->len);
273         if (event_fd >0){
274                 write(event_fd, buf, total_len+log->len);
275         }
276         free(buf);
277
278         return 0;
279 }
280
281 int sendDataToHost(msg_t* log)
282 {
283         if (manager.host.data_socket != -1)
284         {
285                 char logstr[DA_MSG_MAX];
286                 int loglen;
287
288                 if(log->length != 0)
289                         loglen = sprintf(logstr, "%d|%d|%s\n", log->type, log->length + 1, log->data);
290                 else
291                         loglen = sprintf(logstr, "%d|%d|\n", log->type, log->length + 1);
292
293 //              loglen = sprintf(logstr, "%d|%s\n", log->type, log->data);
294
295                 pthread_mutex_lock(&(manager.host.data_socket_mutex));
296                 send(manager.host.data_socket, logstr, loglen, MSG_NOSIGNAL);
297                 pthread_mutex_unlock(&(manager.host.data_socket_mutex));
298                 return 0;
299         }
300         else
301                 return 1;
302 }
303
304 // msgstr can be NULL
305 static int sendACKStrToHost(enum HostMessageType resp, char* msgstr)
306 {
307         if (manager.host.control_socket != -1)
308         {
309                 char logstr[DA_MSG_MAX];
310                 int loglen;
311
312                 if(msgstr != NULL)
313                         loglen = sprintf(logstr, "%d|%d|%s", (int)resp, strlen(msgstr), msgstr);
314                 else
315                         loglen = sprintf(logstr, "%d|0|", (int)resp);
316
317                 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
318                 return 0;
319         }
320         else
321                 return 1;
322 }
323
324
325
326 static int sendACKCodeToHost(enum HostMessageType resp, int msgcode)
327 {
328         // FIXME:
329         //disabled string protocol
330         return 0;
331         if (manager.host.control_socket != -1)
332         {
333                 char codestr[16];
334                 char logstr[DA_MSG_MAX];
335                 int loglen, codelen;
336
337                 codelen = sprintf(codestr, "%d", msgcode);
338                 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr);
339
340                 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
341                 return 0;
342         }
343         else
344                 return 1;
345 }
346
347 // ========================================================================================
348 // start and terminate control functions
349 // ========================================================================================
350
351 static int startProfiling(long launchflag)
352 {
353         char execPath[PATH_MAX];
354
355         // remove previous screen capture files
356         remove_indir(SCREENSHOT_DIR);
357         mkdir(SCREENSHOT_DIR, 0777);
358 #ifndef HOST_BUILD
359         smack_lsetlabel(SCREENSHOT_DIR, "*", SMACK_LABEL_ACCESS);
360 #endif
361         manager.config_flag = launchflag;
362
363 #ifdef RUN_APP_LOADER
364         strcpy(execPath, manager.appPath);
365 #else
366         get_executable(manager.appPath, execPath, PATH_MAX);
367 #endif
368         if(samplingStart() < 0)
369                 return -1;
370
371         if(exec_app(execPath, get_app_type(manager.appPath)) == 0)
372         {
373                 samplingStop();
374                 return -1;
375         }
376
377         LOGI("Timer Started\n");
378
379         return 0;
380 }
381
382 // terminate single target
383 // just send stop message to target process
384 static void terminate_target(int index)
385 {
386         ssize_t sendlen;
387         msg_t sendlog;
388         sendlog.type = MSG_STOP;
389         sendlog.length = 0;
390
391         if(manager.target[index].socket != -1)
392         {
393                 // result of sending to disconnected socket is not expected
394                 sendlen = send(manager.target[index].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
395                 if(sendlen != -1)
396                 {
397                         LOGI("TERMINATE send exit msg (socket %d) by terminate_target()\n", manager.target[index].socket);
398                 }
399         }
400 }
401
402 // just send stop message to all target process
403 static void terminate_all_target()
404 {
405         int i;
406         ssize_t sendlen;
407         msg_t sendlog;
408
409         sendlog.type = MSG_STOP;
410         sendlog.length = 0;
411
412         for (i = 0; i < MAX_TARGET_COUNT; i++)
413         {
414                 if(manager.target[i].socket != -1)
415                 {
416                         sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
417                         if(sendlen != -1)
418                         {
419                                 LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket);
420                         }
421                 }
422         }
423 }
424
425 // terminate all target and wait for threads
426 static void terminate_all()
427 {
428         int i;
429         terminate_all_target();
430         samplingStop();
431
432         // wait for all other thread exit
433         for(i = 0; i < MAX_TARGET_COUNT; i++)
434         {
435                 if(manager.target[i].recv_thread != -1)
436                 {
437                         pthread_join(manager.target[i].recv_thread, NULL);
438                 }
439         }
440 }
441
442 // terminate all profiling by critical error
443 static void terminate_error(char* errstr, int sendtohost)
444 {
445         msg_t log;
446
447         LOGE("TERMINATE ERROR: %s\n", errstr);
448         if(sendtohost)
449         {
450                 log.type = MSG_ERROR;
451                 log.length = sprintf(log.data, "%s", errstr);
452                 sendDataToHost(&log);
453         }
454
455         terminate_all();
456 }
457
458 // ===========================================================================================
459 // message parsing and handling functions
460 // ===========================================================================================
461
462 static int parseDeviceMessage(msg_t* log)
463 {
464         char eventType[MAX_FILENAME];
465         struct input_event in_ev;
466         int i, index;
467
468         if(log == NULL)
469                 return -1;
470
471         eventType[0] = '\0';
472         in_ev.type = 0;
473         in_ev.code = 0;
474         in_ev.value = 0;
475
476         index = 0;
477         for(i = 0; i < log->length; i++)
478         {
479                 if(log->data[i] == '\n')
480                         break;
481
482                 if(log->data[i] == '`') // meet separate
483                 {
484                         i++;
485                         index++;
486                         continue;
487                 }
488
489                 if(index == 0)          // parse eventType
490                 {
491                         eventType[i] = log->data[i];
492                         eventType[i+1] = '\0';
493                 }
494                 else if(index == 1)     // parse in_ev.type
495                 {
496                         in_ev.type = in_ev.type * 10 + (log->data[i] - '0');
497                 }
498                 else if(index == 2)     // parse in_ev.code
499                 {
500                         in_ev.code = in_ev.code * 10 + (log->data[i] - '0');
501                 }
502                 else if(index == 3)     // parse in_ev.value
503                 {
504                         in_ev.value = in_ev.value * 10 + (log->data[i] - '0');
505                 }
506         }
507
508         if(index != 3)
509                 return -1;      // parse error
510
511         if(0 == strncmp(eventType, STR_TOUCH, strlen(STR_TOUCH)))
512         {
513                 _device_write(g_touch_dev, &in_ev);
514         }
515         else if(0 == strncmp(eventType, STR_KEY, strlen(STR_KEY)))
516         {
517                 _device_write(g_key_dev, &in_ev);
518         }
519
520         return 0;
521 }
522
523 // return 0 if normal case
524 // return plus value if non critical error occur
525 // return minus value if critical error occur
526 static int _hostMessageHandler(int efd,struct msg_t* log)
527 {
528         int ret = 0;
529         /*
530         long flag = 0;
531         char *barloc, *tmploc;
532         char execPath[PATH_MAX];
533
534         if (log == NULL)
535                 return 1;
536
537         switch (log->type)
538         {
539         case MSG_REPLAY:
540                 sendACKStrToHost(MSG_OK, NULL);
541                 parseDeviceMessage(log);
542                 break;
543         case MSG_VERSION:
544                 if(strcmp(PROTOCOL_VERSION, log->data) != 0)
545                 {
546                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_PROTOCOL_VERSION);
547                 }
548                 else
549                 {
550                         sendACKStrToHost(MSG_OK, NULL);
551                 }
552                 break;
553         case MSG_START:
554                 LOGI("MSG_START handling : %s\n", log->data);
555                 if(log->length == 0)
556                 {
557                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA);
558                         return -1;              // wrong message format
559                 }
560
561                 // parsing for host start status
562                 tmploc  = log->data;
563                 barloc = strchr(tmploc, '|');
564                 if(barloc == NULL)
565                 {
566                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
567                         return -1;              // wrong message format
568                 }
569
570                 // parsing for target launch option flag
571                 tmploc = barloc + 1;
572                 barloc = strchr(tmploc, '|');
573                 if(barloc != NULL)
574                 {
575                         while(tmploc < barloc)
576                         {
577                                 flag = (flag * 10) + (*tmploc - '0');
578                                 tmploc++;
579                         }
580                 }
581                 else
582                 {
583                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
584                         return -1;      // wrong message format
585                 }
586                 LOGI("launch flag : %lx\n", flag);
587
588                 // parsing for application package name
589                 tmploc = barloc + 1;
590                 strcpy(manager.appPath, tmploc);
591
592                 get_executable(manager.appPath, execPath, PATH_MAX); // get exact app executable file name
593                 LOGI("executable app path %s\n", manager.appPath);
594
595 #ifdef RUN_APP_LOADER
596                 kill_app(manager.appPath);
597 #else
598                 kill_app(execPath);
599 #endif
600
601                 {
602                         char command[PATH_MAX];
603                         struct epoll_event ev;
604
605                         //save app install path
606                         mkdir(DA_WORK_DIR, 0775);
607                         sprintf(command,
608                                         "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH,
609                                         execPath, DA_INSTALL_PATH);
610                         LOGI("appInstallCommand %s\n", command);
611                         system(command);
612
613                         sprintf(command,
614                                         "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH,
615                                         execPath, DA_BUILD_OPTION);
616                         LOGI("appInstallCommand %s\n", command);
617                         system(command);
618
619                         if(startProfiling(flag) < 0)
620                         {
621                                 sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING);
622                                 return -1;
623                         }
624
625                         manager.app_launch_timerfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
626                         if(manager.app_launch_timerfd > 0)
627                         {
628                                 struct itimerspec ctime;
629                                 ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME;
630                                 ctime.it_value.tv_nsec = 0;
631                                 ctime.it_interval.tv_sec = 0;
632                                 ctime.it_interval.tv_nsec = 0;
633                                 if(0 > timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL))
634                                 {
635                                         LOGE("fail to set app launch timer\n");
636                                         close(manager.app_launch_timerfd);
637                                         manager.app_launch_timerfd = -1;
638                                 }
639                                 else
640                                 {
641                                         // add event fd to epoll list
642                                         ev.events = EPOLLIN;
643                                         ev.data.fd = manager.app_launch_timerfd;
644                                         if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.app_launch_timerfd, &ev) < 0)
645                                         {
646                                                 // fail to add event fd
647                                                 LOGE("fail to add app launch timer fd to epoll list\n");
648                                                 close(manager.app_launch_timerfd);
649                                                 manager.app_launch_timerfd = -1;
650                                         }
651                                 }
652                         }
653                 }
654                 sendACKStrToHost(MSG_OK, NULL);
655                 break;
656         case MSG_STOP:
657                 LOGI("MSG_STOP handling\n");
658                 sendACKStrToHost(MSG_OK, NULL);
659                 terminate_all();
660                 break;
661         case MSG_OPTION:
662                 if(log->length > 0)
663                 {
664                         int i;
665                         msg_t sendlog;
666                         manager.config_flag = atoi(log->data);
667                         sendACKStrToHost(MSG_OK, NULL);
668
669                         LOGI("MSG_OPTION : str(%s), flag(%x)\n", log->data, manager.config_flag);
670
671                         sendlog.type = MSG_OPTION;
672                         sendlog.length = sprintf(sendlog.data, "%u", manager.config_flag);
673
674                         for(i = 0; i < MAX_TARGET_COUNT; i++)
675                         {
676                                 if(manager.target[i].socket != -1)
677                                 {
678                                         send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length, MSG_NOSIGNAL);
679                                 }
680                         }
681                 }
682                 else
683                 {
684                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA);
685                         ret = 1;
686                 }
687                 break;
688         case MSG_ISALIVE:
689                 sendACKStrToHost(MSG_OK, NULL);
690                 break;
691         default:
692                 LOGW("Unknown msg\n");
693                 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_TYPE);
694                 ret = 1;
695                 break;
696         }
697 */
698         return ret;
699 }
700
701 // ========================================================================================
702 // socket and event_fd handling functions
703 // ========================================================================================
704
705 // return 0 if normal case
706 // return plus value if non critical error occur
707 // return minus value if critical error occur
708 static int deviceEventHandler(input_dev* dev, int input_type)
709 {
710         int ret = 0;
711         struct input_event in_ev;
712         msg_t log;
713
714         if(input_type == INPUT_ID_TOUCH)
715         {
716                 //touch read
717                 read(dev->fd, &in_ev, sizeof(struct input_event));
718                 log.type = MSG_RECORD;
719                 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
720                                 STR_TOUCH, dev->fileName, in_ev.time.tv_sec,
721                                 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
722                 sendDataToHost(&log);
723         }
724         else if(input_type == INPUT_ID_KEY)
725         {
726                 //key read
727                 read(dev->fd, &in_ev, sizeof(struct input_event));
728                 log.type = MSG_RECORD;
729                 log.length = sprintf(log.data, "%s`,%s`,%ld`,%ld`,%hu`,%hu`,%u",
730                                 STR_KEY, dev->fileName, in_ev.time.tv_sec,
731                                 in_ev.time.tv_usec, in_ev.type, in_ev.code, in_ev.value);
732                 sendDataToHost(&log);
733         }
734         else
735         {
736                 LOGW("unknown input_type\n");
737                 ret = 1;
738         }
739
740         return ret;
741 }
742
743 #define MAX_EVENTS_NUM 10
744 static int deviceEventHandlerNew(input_dev* dev, int input_type)
745 {
746         int ret = 0;
747         ssize_t size = 0;
748         int count = 0;
749         struct input_event in_ev[MAX_EVENTS_NUM];
750         struct msg_data_t log;
751
752         if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
753         {
754                 do {
755 //                      LOGI(">read %s events\n,", input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH);
756                         size = read(dev->fd, &in_ev[count], sizeof(*in_ev) );
757 //                      LOGI("<read %s events : size = %d\n,", input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH,size);
758                         if (size >0)
759                                 count++;
760                 } while (count < MAX_EVENTS_NUM && size > 0);
761
762                 if(count != 0){
763                         LOGI("readed %d %s events\n,", count, input_type==INPUT_ID_KEY?STR_KEY:STR_TOUCH);
764                         gen_message_event(&log,&in_ev[0],count,input_type);
765                         pseudoSendDataToHost(&log);
766                         reset_data_msg(&log);
767                 }
768         }
769         else
770         {
771                 LOGW("unknown input_type\n");
772                 ret = 1;
773         }
774 /*
775         if(input_type == INPUT_ID_TOUCH || input_type == INPUT_ID_KEY)
776         {
777
778                 if (size = read(dev->fd, &in_ev, sizeof(in_ev) ) !=0 )
779                 {
780                         LOGI("readed %d touch events\n,", 1);
781                         gen_message_event(&log,&in_ev,1,input_type);
782                         pseudoSendDataToHost(&log);
783                 }
784         }
785         else
786         {
787                 LOGW("unknown input_type\n");
788                 ret = 1;
789         }
790 */
791         return ret;
792 }
793
794 // return 0 if normal case
795 // return plus value if non critical error occur
796 // return minus value if critical error occur
797 // return -11 if all target process closed
798 static int targetEventHandler(int epollfd, int index, uint64_t msg)
799 {
800         msg_t log;
801
802         if(msg & EVENT_PID)
803         {
804                 if(index == 0)          // assume index 0 is main application process
805                 {
806                         int base_address;
807                         char tempBuff[DA_MSG_MAX];
808                         char tempBuff2[DA_MSG_MAX];
809                         char tempPath[PATH_MAX];
810
811                         get_executable(manager.appPath, tempPath, PATH_MAX);
812                         if(realpath(tempPath, tempBuff) == NULL)
813                         {
814                                 LOGW("Failed to get realpath of app\n");
815                                 strcpy(tempBuff, tempPath);
816                         }
817
818                         sprintf(tempPath, "/proc/%d/maps", manager.target[index].pid);
819                         sprintf(tempBuff2, "cat %s | grep %s | cut -d\"-\" -f1 > %s",
820                                         tempPath, tempBuff, DA_BASE_ADDRESS);
821                         LOGI("base address command is %s\n", tempBuff2);
822
823                         do {
824                                 if(access(tempPath, F_OK) != 0)
825                                         return -1;
826                                 if(is_same_app_process(manager.appPath, manager.target[index].pid) == 0)
827                                         return -1;
828
829                                 system(tempBuff2);
830                                 if(get_app_base_address(&base_address) == 1)
831                                         break;
832                                 sleep(0);
833                         } while(1);
834
835                         tempPath[0] = '\0';
836                         get_app_install_path(tempPath, PATH_MAX);
837
838 #ifndef HOST_BUILD
839                         get_device_info(tempBuff, DA_MSG_MAX);
840 #endif
841
842                         log.type = MSG_DEVICE;
843                         if (strlen(tempPath) > 0)
844                         {
845                                 get_executable(manager.appPath, tempBuff2, DA_MSG_MAX);
846                                 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,%s/%s", tempBuff,
847                                                 manager.target[index].pid, manager.target[index].starttime,
848                                                 is_app_built_pie(), base_address, get_app_type(manager.appPath),
849                                                 tempPath, get_app_name(tempBuff2));
850                         }
851                         else
852                         {
853                                 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,", tempBuff,
854                                                 manager.target[index].pid, manager.target[index].starttime,
855                                                 is_app_built_pie(), base_address, get_app_type(manager.appPath));
856                         }
857
858                         LOGI("%s\n", log.data);
859                 }
860                 else
861                 {
862                         log.type = MSG_PID;
863                         log.length = sprintf(log.data, "%d`,%Lu", manager.target[index].pid, manager.target[index].starttime);
864                 }
865
866                 sendDataToHost(&log);
867                 manager.target[index].initial_log = 1;
868         }
869
870         if(msg & EVENT_STOP || msg & EVENT_ERROR)
871         {
872                 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
873                                 manager.target[index].socket, manager.target[index].pid, manager.target_count - 1);
874
875                 terminate_target(index);
876                 epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
877                 setEmptyTargetSlot(index);
878                 if (0 == __sync_sub_and_fetch(&manager.target_count, 1))        // all target client are closed
879                 {
880                         log.type = MSG_TERMINATE;
881                         log.length = 0;
882                         log.data[0] = '\0';
883                         sendDataToHost(&log);
884                         return -11;
885                 }
886         }
887
888         return 0;
889 }
890
891 // return 0 if normal case
892 // return plus value if non critical error occur
893 // return minus value if critical error occur
894 static int targetServerHandler(int efd)
895 {
896         msg_t log;
897         struct epoll_event ev;
898
899         int index = getEmptyTargetSlot();
900         if(index == MAX_TARGET_COUNT)
901         {
902                 LOGW("Max target number(8) reached, no more target can connected\n");
903                 return 1;
904         }
905
906         manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL);
907
908         if(manager.target[index].socket >= 0)   // accept succeed
909         {
910 #ifndef HOST_BUILD
911                 // set smack attribute for certification
912                 fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
913                 fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
914 #endif /* HOST_BUILD */
915
916                 // send config message to target process
917                 log.type = MSG_OPTION;
918                 log.length = sprintf(log.data, "%u", manager.config_flag);
919                 send(manager.target[index].socket, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_NOSIGNAL);
920
921                 // make event fd
922                 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
923                 if(manager.target[index].event_fd == -1)
924                 {
925                         // fail to make event fd
926                         LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket);
927                         goto TARGET_CONNECT_FAIL;
928                 }
929
930                 // add event fd to epoll list
931                 ev.events = EPOLLIN;
932                 ev.data.fd = manager.target[index].event_fd;
933                 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
934                 {
935                         // fail to add event fd
936                         LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket);
937                         goto TARGET_CONNECT_FAIL;
938                 }
939
940                 // make recv thread for target
941                 if(makeRecvThread(index) != 0)
942                 {
943                         // fail to make recv thread
944                         LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket);
945                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
946                         goto TARGET_CONNECT_FAIL;
947                 }
948
949                 if(manager.app_launch_timerfd >= 0)
950                 {
951                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
952                         close(manager.app_launch_timerfd);
953                         manager.app_launch_timerfd = -1;
954                 }
955
956                 LOGI("target connected = %d(running %d target)\n",
957                                 manager.target[index].socket, manager.target_count + 1);
958
959                 manager.target_count++;
960                 return 0;
961         }
962         else    // accept error
963         {
964                 LOGE("Failed to accept at target server socket\n");
965         }
966
967 TARGET_CONNECT_FAIL:
968         if(manager.target_count == 0)   // if this connection is main connection
969         {
970                 return -1;
971         }
972         else    // if this connection is not main connection then ignore process by error
973         {
974                 setEmptyTargetSlot(index);
975                 return 1;
976         }
977 }
978
979 // return 0 if normal case
980 // return plus value if non critical error occur
981 // return minus value if critical error occur
982 static int hostServerHandler(int efd)
983 {
984         static int hostserverorder = 0;
985         int csocket;
986         struct epoll_event ev;
987
988         if(hostserverorder > 1) // control and data socket connected already
989                 return 1;                       // ignore
990
991         csocket = accept(manager.host_server_socket, NULL, NULL);
992
993         if(csocket >= 0)                // accept succeed
994         {
995                 ev.events = EPOLLIN;
996                 ev.data.fd = csocket;
997                 if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
998                 {
999                         // consider as accept fail
1000                         LOGE("Failed to add socket fd to epoll list\n");
1001                         close(csocket);
1002                         return -1;
1003                 }
1004
1005                 if(hostserverorder == 0)
1006                 {
1007                         manager.host.control_socket = csocket;
1008                         unlink_portfile();
1009                         LOGI("host control socket connected = %d\n", csocket);
1010                 }
1011                 else
1012                 {
1013                         manager.host.data_socket = csocket;
1014                         LOGI("host data socket connected = %d\n", csocket);
1015                 }
1016
1017                 hostserverorder++;
1018                 return 0;
1019         }
1020         else    // accept error
1021         {
1022                 LOGE("Failed to accept from host server socket\n");
1023                 return -1;
1024         }
1025 }
1026
1027
1028 //TODO del it or move to debug section
1029 void printBuf (char * buf, int len)
1030 {
1031         int i,j;
1032         char local_buf[3*16 + 2*16 + 1];
1033         char * p1, * p2;
1034         LOGI("BUFFER:\n");
1035         for ( i = 0; i < len/16 + 1; i++)
1036         {
1037                 memset(local_buf, ' ', 5*16);
1038                 p1 = local_buf;
1039                 p2 = local_buf + 3*17;
1040                 for ( j = 0; j < 16; j++)
1041                         if (i*16+j < len )
1042                         {
1043                                 sprintf(p1, "%02X ",(unsigned char) *buf);
1044                                 p1+=3;
1045                                 if (isprint( *buf)){
1046                                         sprintf(p2, "%c ",(int)*buf);
1047                                 }else{
1048                                         sprintf(p2,". ");
1049                                 }
1050                                 p2+=2;
1051                                 buf++;
1052                         }
1053                 *p1 = ' ';
1054                 *p2 = '\0';
1055                 LOGI("%s\n",local_buf);
1056         }
1057 }
1058
1059 // return 0 if normal case
1060 // return plus value if non critical error occur
1061 // return minus value if critical error occur
1062 // return -11 if socket closed
1063
1064 static int controlSocketHandler(int efd)
1065 {
1066         ssize_t recvLen;
1067         char recvBuf[DA_MSG_MAX];
1068         msg_t log;
1069
1070         // host log format xxx|length|str
1071         recvLen = recv(manager.host.control_socket, recvBuf, DA_MSG_MAX, 0);
1072
1073         if (recvLen > 0)
1074         {
1075                 recvBuf[recvLen] = '\0';
1076                 printBuf(recvBuf,recvLen);
1077                 LOGI("host sent control msg str(%s)\n", recvBuf);
1078                 if(parseHostMessage(&log, recvBuf) < 0)
1079                 {
1080                         // error to parse host message
1081                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
1082                         return 1;
1083                 }
1084
1085                 // host msg command handling
1086                 return hostMessageHandle(&log);
1087         }
1088         else    // close request from HOST
1089         {
1090                 return -11;
1091         }
1092 }
1093
1094 // return 0 for normal case
1095 int daemonLoop()
1096 {
1097         int                     ret = 0;                                // return value
1098         int                     i, k;
1099         ssize_t         recvLen;
1100
1101         struct epoll_event ev, *events;
1102         int efd;                // epoll fd
1103         int numevent;   // number of occured events
1104
1105         _get_fds(g_key_dev, INPUT_ID_KEY);
1106         _get_fds(g_touch_dev, INPUT_ID_TOUCH);
1107
1108         // initialize epoll event pool
1109         events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
1110         if(events == NULL)
1111         {
1112                 LOGE("Out of memory when allocate epoll event pool\n");
1113                 ret = -1;
1114                 goto END_RETURN;
1115         }
1116         if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
1117         {
1118                 LOGE("epoll creation error\n");
1119                 ret = -1;
1120                 goto END_EVENT;
1121         }
1122
1123         // add server sockets to epoll event pool
1124         ev.events = EPOLLIN;
1125         ev.data.fd = manager.host_server_socket;
1126         if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.host_server_socket, &ev) < 0)
1127         {
1128                 LOGE("Host server socket epoll_ctl error\n");
1129                 ret = -1;
1130                 goto END_EFD;
1131         }
1132         ev.events = EPOLLIN;
1133         ev.data.fd = manager.target_server_socket;
1134         if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target_server_socket, &ev) < 0)
1135         {
1136                 LOGE("Target server socket epoll_ctl error\n");
1137                 ret = -1;
1138                 goto END_EFD;
1139         }
1140
1141         // add device fds to epoll event pool
1142         ev.events = EPOLLIN;
1143         for(i = 0; g_key_dev[i].fd != ARRAY_END; i++)
1144         {
1145                 if(g_key_dev[i].fd >= 0)
1146                 {
1147                         ev.data.fd = g_key_dev[i].fd;
1148                         if(epoll_ctl(efd, EPOLL_CTL_ADD, g_key_dev[i].fd, &ev) < 0)
1149                         {
1150                                 LOGE("keyboard device file epoll_ctl error\n");
1151                         }
1152                 }
1153         }
1154
1155         ev.events = EPOLLIN;
1156         for(i = 0; g_touch_dev[i].fd != ARRAY_END; i++)
1157         {
1158                 if(g_touch_dev[i].fd >= 0)
1159                 {
1160                         ev.data.fd = g_touch_dev[i].fd;
1161                         if(epoll_ctl(efd, EPOLL_CTL_ADD, g_touch_dev[i].fd, &ev) < 0)
1162                         {
1163                                 LOGE("touch device file epoll_ctl error\n");
1164                         }
1165                 }
1166         }
1167
1168         // handler loop
1169         while (1)
1170         {
1171                 numevent = epoll_wait(efd, events, EPOLL_SIZE, -1);
1172                 if(numevent <= 0)
1173                 {
1174                         LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
1175                         continue;
1176                 }
1177
1178                 for(i = 0; i < numevent; i++)
1179                 {
1180                         // check for request from event fd
1181                         for(k = 0; k < MAX_TARGET_COUNT; k++)
1182                         {
1183                                 if(manager.target[k].socket != -1 &&
1184                                                 events[i].data.fd == manager.target[k].event_fd)
1185                                 {
1186                                         uint64_t u;
1187                                         recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
1188                                         if(recvLen != sizeof(uint64_t))
1189                                         {
1190                                                 // maybe closed, but ignoring is more safe then removing fd from epoll list
1191                                         }
1192                                         else
1193                                         {
1194                                                 if(-11 == targetEventHandler(efd, k, u))
1195                                                 {
1196                                                         LOGI("all target process is closed\n");
1197                                                         terminate_all();
1198                                                         ret = 0;
1199                                                         goto END_EFD;
1200                                                 }
1201                                         }
1202                                         break;
1203                                 }
1204                         }
1205
1206                         if(k != MAX_TARGET_COUNT)
1207                                 continue;
1208
1209                         // check for request from device fd
1210                         for(k = 0; g_touch_dev[k].fd != ARRAY_END; k++)
1211                         {
1212                                 if(g_touch_dev[k].fd >= 0 && 
1213                                                 events[i].data.fd == g_touch_dev[k].fd)
1214                                 {
1215                                         if(deviceEventHandlerNew(&g_touch_dev[k], INPUT_ID_TOUCH) < 0)
1216                                         {
1217                                                 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1218                                                 ret = -1;
1219                                                 goto END_EFD;
1220                                         }
1221                                         break;
1222                                 }
1223                         }
1224
1225                         if(g_touch_dev[k].fd != ARRAY_END)
1226                                 continue;
1227
1228                         for(k = 0; g_key_dev[k].fd != ARRAY_END; k++)
1229                         {
1230                                 if(g_key_dev[k].fd >= 0 && 
1231                                                 events[i].data.fd == g_key_dev[k].fd)
1232                                 {
1233                                         if(deviceEventHandlerNew(&g_key_dev[k], INPUT_ID_KEY) < 0)
1234                                         {
1235                                                 terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1236                                                 ret = -1;
1237                                                 goto END_EFD;
1238                                         }
1239                                         break;
1240                                 }
1241                         }
1242
1243                         if(g_key_dev[k].fd != ARRAY_END)
1244                                 continue;
1245
1246                         // connect request from target
1247                         if(events[i].data.fd == manager.target_server_socket)
1248                         {
1249                                 if(targetServerHandler(efd) < 0)        // critical error
1250                                 {
1251                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1252                                         ret = -1;
1253                                         goto END_EFD;
1254                                 }
1255                         }
1256                         // connect request from host
1257                         else if(events[i].data.fd == manager.host_server_socket)
1258                         {
1259                                 int result = hostServerHandler(efd);
1260                                 if(result < 0)
1261                                 {
1262                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1263                                         ret = -1;
1264                                         goto END_EFD;
1265                                 }
1266                         }
1267                         // control message from host
1268                         else if(events[i].data.fd == manager.host.control_socket)
1269                         {
1270                                 int result = controlSocketHandler(efd);
1271                                 if(result == -11)       // socket close
1272                                 {
1273                                         // close target and host socket and quit
1274                                         LOGI("host close = %d\n", manager.host.control_socket);
1275                                         terminate_all();
1276                                         ret = 0;
1277                                         goto END_EFD;
1278                                 }
1279                                 else if(result < 0)
1280                                 {
1281                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
1282                                         ret = -1;
1283                                         goto END_EFD;
1284                                 }
1285                         }
1286                         else if(events[i].data.fd == manager.host.data_socket)
1287                         {
1288                                 char recvBuf[32];
1289                                 recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
1290                                 if(recvLen == 0)
1291                                 {       // close data socket
1292                                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.host.data_socket, NULL);
1293                                         close(manager.host.data_socket);
1294                                         manager.host.data_socket = -1;
1295                                 }
1296         
1297                                 LOGW("host message from data socket %d\n", recvLen);
1298                         }
1299                         // check for application launch timerfd
1300                         else if(events[i].data.fd == manager.app_launch_timerfd)
1301                         {
1302                                 // send to host timeout error message for launching application
1303                                 terminate_error("Failed to launch application", 1);
1304                                 epoll_ctl(efd, EPOLL_CTL_DEL, manager.app_launch_timerfd, NULL);
1305                                 close(manager.app_launch_timerfd);
1306                                 manager.app_launch_timerfd = -1;
1307                                 ret = -1;
1308                                 goto END_EFD;
1309                         }
1310                         // unknown socket
1311                         else
1312                         {
1313                                 // never happened
1314                                 LOGW("Unknown socket fd (%d)\n", events[i].data.fd);
1315                         }
1316                 }
1317         }
1318
1319 END_EFD:
1320         close(efd);
1321 END_EVENT:
1322         free(events);
1323 END_RETURN:
1324         return ret;
1325 }