[IMPROVE] Implement freezing/unfreezing apps
[platform/core/system/swap-manager.git] / daemon / da_protocol.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Cherepanov Vitaliy <v.cherepanov@samsung.com>
9  * Nikita Kalyazin    <n.kalyazin@samsung.com>
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  * Contributors:
24  * - Samsung RnD Institute Russia
25  *
26  */
27
28
29 #include <stdint.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include <errno.h>
34
35 #include <sys/types.h>
36 #include <sys/socket.h>
37
38 #include <sys/sysinfo.h>
39
40 #include "da_protocol.h"
41 #include "da_inst.h"
42 #include "da_protocol_check.h"
43 #include "daemon.h"
44 #include "sys_stat.h"
45 #include "transfer_thread.h"
46 #include "elf.h"
47 #include "ioctl_commands.h"
48 #include "debug.h"
49 #include "md5.h"
50 #include "da_data.h"
51 #include "freezing.h"
52
53 #include <sys/stat.h>
54 #include <fcntl.h>
55 #include <unistd.h>
56
57 static pthread_mutex_t stop_all_mutex = PTHREAD_MUTEX_INITIALIZER;
58
59 static void inline free_msg(struct msg_t *msg)
60 {
61         free(msg);
62 }
63
64 struct prof_session_t prof_session;
65
66 static void print_conf(struct conf_t *conf);
67 //DEBUG FUNCTIONS
68 #define dstr(x) #x
69 #define check_and_return(check) if ( ID == check ) {return dstr(check);}
70
71 char *msg_ID_str(enum HostMessageT ID)
72 {
73         check_and_return(NMSG_KEEP_ALIVE);
74         check_and_return(NMSG_START);
75         check_and_return(NMSG_STOP);
76         check_and_return(NMSG_CONFIG);
77         check_and_return(NMSG_BINARY_INFO);
78         check_and_return(NMSG_GET_TARGET_INFO);
79         check_and_return(NMSG_SWAP_INST_ADD);
80         check_and_return(NMSG_SWAP_INST_REMOVE);
81         check_and_return(NMSG_GET_SCREENSHOT);
82
83         check_and_return(NMSG_KEEP_ALIVE_ACK);
84         check_and_return(NMSG_START_ACK);
85         check_and_return(NMSG_STOP_ACK);
86         check_and_return(NMSG_CONFIG_ACK);
87         check_and_return(NMSG_BINARY_INFO_ACK);
88         check_and_return(NMSG_SWAP_INST_ACK);
89         check_and_return(NMSG_GET_TARGET_INFO_ACK);
90         check_and_return(NMSG_SWAP_INST_ADD_ACK);
91         check_and_return(NMSG_SWAP_INST_REMOVE_ACK);
92
93         check_and_return(NMSG_PROCESS_INFO);
94         check_and_return(NMSG_TERMINATE);
95         check_and_return(NMSG_ERROR);
96         check_and_return(NMSG_SAMPLE);
97         check_and_return(NMSG_SYSTEM);
98         check_and_return(NMSG_IMAGE);
99         check_and_return(NMSG_RECORD);
100         check_and_return(NMSG_FUNCTION_ENTRY);
101         check_and_return(NMSG_FUNCTION_EXIT);
102         check_and_return(NMSG_CONTEXT_SWITCH_ENTRY);
103         check_and_return(NMSG_CONTEXT_SWITCH_EXIT);
104         return "HZ";
105 }
106
107
108 static char *msgErrStr(enum ErrorCode err)
109 {
110         switch (err) {
111         case ERR_NO:
112                 return "success";
113         case ERR_LOCKFILE_CREATE_FAILED:
114                 return "lock file create failed";
115         case ERR_ALREADY_RUNNING:
116                 return "already running";
117         case ERR_INITIALIZE_SYSTEM_INFO_FAILED:
118                 return "initialize system info failed";
119         case ERR_HOST_SERVER_SOCKET_CREATE_FAILED:
120                 return "host server socket create failed";
121         case ERR_TARGET_SERVER_SOCKET_CREATE_FAILED:
122                 return "target server socket create failed";
123         case ERR_SIGNAL_MASK_SETTING_FAILED: //TODO del (old parametr)
124                 return "ERR SIGNAL MASK SETTING FAILED";
125         case ERR_WRONG_MESSAGE_FORMAT:
126                 return "wrong message format";
127         case ERR_WRONG_MESSAGE_TYPE:
128                 return "wrong message type";
129         case ERR_WRONG_MESSAGE_DATA:
130                 return "wrong message data";
131         case ERR_CANNOT_START_PROFILING:
132                 return "cannot start profiling";
133         case ERR_SERV_SOCK_CREATE:
134                 return "server socket creation failed (written in /tmp/da.port file)";
135         case ERR_SERV_SOCK_BIND:
136                 return "server socket bind failed (written in /tmp/da.port file)";
137         case ERR_SERV_SOCK_LISTEN:
138                 return "server socket listen failed (written in /tmp/da.port file)";
139         case ERR_UNKNOWN:
140         default:
141                 return "unknown error";
142         }
143         return "unknown error";
144 }
145
146
147 #define print_feature(f,in,to,delim)            \
148         if (f & in) {                           \
149                 sprintf(to, dstr(f) delim );    \
150                 to+=strlen( dstr(f) delim );    \
151         }
152 #define print_feature_0(f) print_feature(f, feature0, to, ", \n\t")
153 static void feature_code_str(uint64_t feature0, uint64_t feature1, char *to)
154 {
155         print_feature_0(FL_CPU);
156         print_feature_0(FL_MEMORY);
157         print_feature_0(FL_FUNCTION_PROFILING);
158         print_feature_0(FL_MEMORY_ALLOC_PROBING);
159         print_feature_0(FL_FILE_API_PROBING);
160         print_feature_0(FL_THREAD_API_PROBING);
161         print_feature_0(FL_OSP_UI_API_PROBING);
162         print_feature_0(FL_SCREENSHOT);
163         print_feature_0(FL_USER_EVENT);
164         print_feature_0(FL_RECORDING);
165         print_feature_0(FL_SYSTCALL_FILE);
166         print_feature_0(FL_SYSTCALL_IPC);
167         print_feature_0(FL_SYSTCALL_PROCESS);
168         print_feature_0(FL_SYSTCALL_SIGNAL);
169         print_feature_0(FL_SYSTCALL_NETWORK);
170         print_feature_0(FL_SYSTCALL_DESC);
171         print_feature_0(FL_CONTEXT_SWITCH);
172         print_feature_0(FL_NETWORK_API_PROBING);
173         print_feature_0(FL_OPENGL_API_PROBING);
174         print_feature_0(FL_MEMORY_ALLOC_ALWAYS_PROBING);
175         print_feature_0(FL_FILE_API_ALWAYS_PROBING);
176         print_feature_0(FL_THREAD_API_ALWAYS_PROBING);
177         print_feature_0(FL_OSP_UI_API_ALWAYS_PROBING);
178         print_feature_0(FL_NETWORK_API_ALWAYS_PROBING);
179         print_feature_0(FL_OPENGL_API_ALWAYS_PROBING);
180 }
181
182
183 //PARSE FUNCTIONS
184 static inline uint32_t get_avail_msg_size(struct msg_buf_t *msg)
185 {
186         return (uint32_t)(msg->end - msg->cur_pos);
187 }
188
189 static inline uint32_t get_msg_cur_size(struct msg_buf_t *msg)
190 {
191         return (uint32_t) (msg->cur_pos - msg->payload);
192 }
193
194 int parse_string(struct msg_buf_t *msg, char **str)
195 {
196         parse_deb("size = %d\n", get_avail_msg_size(msg));
197         int len = strlen(msg->cur_pos) + 1;
198
199         if (get_avail_msg_size(msg) < len)
200                 return 0;
201
202         *str = strdup(msg->cur_pos);
203         parse_deb("<%s>\n", *str);
204         msg->cur_pos += len;
205         return 1;
206 }
207
208 static const char* parse_string_inplace(struct msg_buf_t *msg)
209 {
210         const char *str = msg->cur_pos;
211         int avail_size = get_avail_msg_size(msg);
212         int len = strnlen(str, avail_size);
213
214         /* Malformed string or exhaused buffer. Strlen is at least one byte
215          * less, that availiable space. If it is not, string is lacking
216          * terminating null char.
217          */
218
219         if (len == avail_size)
220                 return NULL;
221
222         msg->cur_pos += len + 1;
223         return str;
224 }
225
226 int parse_string_no_alloc(struct msg_buf_t *msg, char *str)
227 {
228         parse_deb("size = %d\n", get_avail_msg_size(msg));
229         int len = strlen(msg->cur_pos) + 1;
230
231         if (get_avail_msg_size(msg) < len)
232                 return 0;
233
234         memcpy(str, msg->cur_pos, len);
235         parse_deb("<%s>\n", str);
236         msg->cur_pos += len;
237         return 1;
238 }
239
240 int parse_int8(struct msg_buf_t *msg, uint8_t *val)
241 {
242         parse_deb("size = %d\n", get_avail_msg_size(msg));
243         if (get_avail_msg_size(msg) < sizeof(*val))
244                 return 0;
245         *val = *(uint8_t *)msg->cur_pos;
246         msg->cur_pos += sizeof(uint8_t);
247
248         parse_deb("<%d><0x%08X>\n", *val, *val);
249         return 1;
250 }
251
252
253
254 int parse_int32(struct msg_buf_t *msg, uint32_t *val)
255 {
256         parse_deb("size = %d\n", get_avail_msg_size(msg));
257         if (get_avail_msg_size(msg) < sizeof(*val))
258                 return 0;
259         *val = *(uint32_t *)msg->cur_pos;
260         msg->cur_pos += sizeof(uint32_t);
261
262
263         parse_deb("<%d><0x%08X>\n", *val, *val);
264         return 1;
265 }
266
267
268 int parse_int64(struct msg_buf_t *msg, uint64_t *val)
269 {
270         parse_deb("size = %d\n", get_avail_msg_size(msg));
271         if (get_avail_msg_size(msg) < sizeof(*val))
272                 return 0;
273
274         *val = *(uint64_t *)msg->cur_pos;
275
276         parse_deb("<%llu><0x%016llX>\n", *val, *val);
277         msg->cur_pos += sizeof(uint64_t);
278         return 1;
279 }
280
281 static int parse_conf(struct msg_buf_t *msg, struct conf_t *conf)
282 {
283
284         parse_deb("parse_conf\n");
285         if (!parse_int64(msg, &conf->use_features0)) {
286                 LOGE("use features0 error\n");
287                 return 0;
288         }
289
290         if (!parse_int64(msg, &conf->use_features1)) {
291                 LOGE("use features1 parsing error\n");
292                 return 0;
293         }
294         //Check features value
295         if (!check_conf_features(conf->use_features0, conf->use_features1)) {
296                 LOGE("check features fail\n");
297                 return 0;
298         }
299
300         if (!parse_int32( msg, &conf->system_trace_period) ||
301                 !check_conf_systrace_period(conf->system_trace_period))
302         {
303                 LOGE("system trace period error\n");
304                 return 0;
305         }
306
307         if (!parse_int32( msg, &conf->data_message_period) ||
308                 !check_conf_datamsg_period(conf->data_message_period))
309         {
310                 LOGE("data message period error\n");
311                 return 0;
312         }
313         //print_conf(conf);
314         return 1;
315 }
316
317 //REPLAY EVENTS PARSE
318 static int parse_timeval(struct msg_buf_t *msg, struct timeval *tv)
319 {
320         uint32_t nsec = 0;
321
322         parse_deb("time\n");
323
324         if (!parse_int32(msg, (uint32_t *)&tv->tv_sec)) {
325                 LOGE("sec parsing error\n");
326                 return 0;
327         }
328
329         if (!parse_int32(msg, &nsec)) {
330                 LOGE("usec parsing error\n");
331                 return 0;
332         }
333         tv->tv_usec = nsec / 1000;
334
335         return 1;
336 }
337
338 static int parse_replay_event(struct msg_buf_t *msg,
339                                     struct replay_event_t *re)
340 {
341
342         if (!parse_timeval(msg, &re->ev.time)) {
343                 LOGE("time parsing error\n");
344                 return 0;
345         }
346
347         if (!parse_int32(msg, &re->id)) {
348                 LOGE("id parsing error\n");
349                 return 0;
350         }
351
352         if (!parse_int32(msg, (uint32_t *)&re->ev.type)) {
353                 LOGE("type parsing error\n");
354                 return 0;
355         }
356
357         if (!parse_int32(msg, (uint32_t *)&re->ev.code)) {
358                 LOGE("code parsing error\n");
359                 return 0;
360         }
361
362         if (!parse_int32(msg, (uint32_t *)&re->ev.value)) {
363                 LOGE("value parsing error\n");
364                 return 0;
365         }
366
367         return 1;
368 }
369
370 void reset_replay_event_seq(struct replay_event_seq_t *res)
371 {
372         res->enabled = 0;
373         res->tv = (struct timeval){0, 0};
374         if (res->event_num != 0)
375                 free(res->events);
376         res->event_num = 0;
377 }
378
379 int parse_replay_event_seq(struct msg_buf_t *msg,
380                            struct replay_event_seq_t *res)
381 {
382         int i = 0;
383         parse_deb("REPLAY\n");
384         if (!parse_int32(msg, &res->enabled)) {
385                 LOGE("enabled parsing error\n");
386                 return 0;
387         }
388
389         if(res->enabled == 0) {
390                 parse_deb("disable\n");
391                 return 1;
392         }
393
394         parse_deb("time main\n");
395         if (!parse_timeval(msg, &res->tv)) {
396                 LOGE("time parsing error\n");
397                 return 0;
398         }
399
400         parse_deb("count\n");
401         if (!parse_int32(msg, &res->event_num)) {
402                 LOGE("event num parsing error\n");
403                 return 0;
404         }
405         parse_deb("events num=%d\n", res->event_num);
406
407         res->events = (struct replay_event_t *)malloc(res->event_num *
408                                                       sizeof(*res->events));
409         if (!res->events) {
410                 LOGE("events alloc error\n");
411                 return 0;
412         }
413
414         for (i = 0; i < res->event_num; i++) {
415                 parse_deb("sub_rep\n");
416                 if (!parse_replay_event(msg, &res->events[i])) {
417                         LOGE("event #%d parsing error\n", i + 1);
418                         free(res->events);
419                         res->event_num = 0;
420                         return 0;
421                 }
422         }
423
424         return 1;
425 }
426
427 //*REPLAY EVENT PARSE
428
429 static int parse_msg_config(struct msg_buf_t *msg_payload,
430                               struct conf_t *conf)
431 {
432         if (!parse_conf(msg_payload, conf)) {
433                 LOGE("conf parsing error\n");
434                 return 0;
435         }
436
437         print_conf(conf);
438         return 1;
439 }
440
441 static void init_parse_control(struct msg_buf_t *buf, struct msg_t *msg)
442 {
443         buf->payload = msg->payload;
444         buf->len = msg->len;
445         buf->end = msg->payload + msg->len;
446         buf->cur_pos = msg->payload;
447 }
448
449 static void reset_target_info(struct target_info_t *target_info)
450 {
451         return;
452 }
453
454 static void running_status_on(struct prof_session_t *prof_session)
455 {
456         prof_session->running_status = 1;
457 }
458
459 static void running_status_off(struct prof_session_t *prof_session)
460 {
461         prof_session->running_status = 0;
462 }
463
464 int check_running_status(const struct prof_session_t *prof_session)
465 {
466         return prof_session->running_status;
467 }
468
469 static void reset_app_inst(struct user_space_inst_t *us_inst)
470 {
471         free_data_list((struct data_list_t **)&us_inst->app_inst_list);
472         us_inst->app_num = 0;
473         us_inst->app_inst_list = NULL;
474 }
475
476 void reset_system_info(struct system_info_t *sys_info)
477 {
478         if (sys_info->thread_load)
479                 free(sys_info->thread_load);
480         if (sys_info->process_load)
481                 free(sys_info->process_load);
482         if (sys_info->cpu_frequency)
483                 free(sys_info->cpu_frequency);
484         if (sys_info->cpu_load)
485                 free(sys_info->cpu_load);
486         memset(sys_info, 0, sizeof(*sys_info));
487 }
488
489 void init_prof_session(struct prof_session_t *prof_session)
490 {
491         memset(prof_session, 0, sizeof(*prof_session));
492 }
493
494 static size_t str_array_getsize(const char **strings, size_t len)
495 {
496         /*!
497          * Calculate about of memory to place array
498          * of \0 delimited strings
499          */
500         size_t size = 0;
501         unsigned int index;
502         for (index = 0; index != len; ++index)
503                 size += strlen(strings[index]) + 1;
504         return size;
505 }
506
507
508 static struct msg_t *gen_target_info_reply(struct target_info_t *target_info)
509 {
510         struct msg_t *msg;
511         char *p = NULL;
512         uint32_t ret_id = ERR_NO;
513
514         msg = malloc(sizeof(*msg) +
515                      sizeof(ret_id) +
516                      sizeof(*target_info) -
517                      sizeof(target_info->network_type) +
518                      strlen(target_info->network_type) + 1 +
519                      sizeof(uint32_t) + /* devices count */
520                      str_array_getsize(supported_devices_strings,
521                                        supported_devices_count));
522         if (!msg) {
523                 LOGE("Cannot alloc target info msg\n");
524                 free(msg);
525                 return NULL;
526         }
527
528         msg->id = NMSG_GET_TARGET_INFO_ACK;
529         p = msg->payload;
530
531         pack_int32(p, ret_id);
532         pack_int64(p, target_info->sys_mem_size);
533         pack_int64(p, target_info->storage_size);
534         pack_int32(p, target_info->bluetooth_supp);
535         pack_int32(p, target_info->gps_supp);
536         pack_int32(p, target_info->wifi_supp);
537         pack_int32(p, target_info->camera_count);
538         pack_str(p, target_info->network_type);
539         pack_int32(p, target_info->max_brightness);
540         pack_int32(p, target_info->cpu_core_count);
541         pack_int32(p, supported_devices_count);
542         p = pack_str_array(p, supported_devices_strings,
543                            supported_devices_count);
544
545         msg->len = p - msg->payload;
546
547         return msg;
548 }
549
550 static int send_reply(struct msg_t *msg)
551 {
552         printBuf((char *)msg, msg->len + sizeof (*msg));
553         if (send(manager.host.control_socket,
554                  msg, MSG_CMD_HDR_LEN + msg->len, MSG_NOSIGNAL) == -1) {
555                 LOGE("Cannot send reply : %s\n", strerror(errno));
556                 return -1;
557         }
558
559         return 0;
560 }
561
562 static void write_msg_error(const char *err_str)
563 {
564         struct msg_data_t *err_msg = gen_message_error(err_str);
565         write_to_buf(err_msg);
566         free_msg_data(err_msg);
567 }
568
569 static enum HostMessageT get_ack_msg_id(const enum HostMessageT id)
570 {
571         switch (id) {
572         case NMSG_KEEP_ALIVE:
573                 return NMSG_KEEP_ALIVE_ACK;
574         case NMSG_START:
575                 return NMSG_START_ACK;
576         case NMSG_STOP:
577                 return NMSG_STOP_ACK;
578         case NMSG_CONFIG:
579                 return NMSG_CONFIG_ACK;
580         case NMSG_BINARY_INFO:
581                 return NMSG_BINARY_INFO_ACK;
582         case NMSG_GET_TARGET_INFO:
583                 return NMSG_GET_TARGET_INFO_ACK;
584         case NMSG_SWAP_INST_ADD:
585                 return NMSG_SWAP_INST_ADD_ACK;
586         case NMSG_SWAP_INST_REMOVE:
587                 return NMSG_SWAP_INST_REMOVE_ACK;
588         default:
589                 LOGE("Fatal: unknown message ID [0x%X]\n", id);
590                 exit(EXIT_FAILURE);
591         }
592 }
593
594 int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
595                         char *payload, int payload_size)
596 {
597         if (manager.host.control_socket != -1) {
598                 struct msg_t *msg;
599                 uint32_t err = err_code;
600                 int loglen = sizeof(*msg) - sizeof(msg->payload) +
601                                          sizeof(err) + //return ID
602                                          payload_size;
603                 msg = malloc(loglen);
604                 char *p = msg->payload;
605
606                 resp = get_ack_msg_id(resp);
607
608                 //set message id
609                 msg->id = resp;
610                 //set payload lenth
611                 msg->len = payload_size + sizeof(err);
612                 //set return id
613                 pack_int32(p, err);
614                 //copy payload data
615                 memcpy(p, payload, payload_size);
616
617                 LOGI("ACK (%s) errcode<%s> payload=0x%08X; size=%d\n", msg_ID_str(resp),
618                                 msgErrStr(err_code), (int)payload, payload_size);
619                 printBuf((char *)msg, loglen);
620
621                 if (send(manager.host.control_socket, msg,
622                          loglen, MSG_NOSIGNAL) == -1) {
623                         LOGE("Cannot send reply: %s\n", strerror(errno));
624                         free(msg);
625                         return 1;
626                 }
627                 free(msg);
628                 return 0;
629         } else
630                 return 1;
631 }
632
633 static struct msg_t *gen_stop_msg(void)
634 {
635         struct msg_t *res = malloc(sizeof(*res));
636         memset(res, 0, sizeof(*res));
637         res->id = NMSG_STOP;
638         res->len = 0;
639         return res;
640 }
641
642
643 enum ErrorCode stop_all_no_lock(void)
644 {
645         enum ErrorCode error_code = ERR_NO;
646         struct msg_t *msg;
647
648         // stop all only if it has not been called yet
649         if (check_running_status(&prof_session)) {
650                 msg = gen_stop_msg();
651                 if(thaw_subgroup()) {
652                         LOGE("Cannot thaw subgroup\n");
653                         error_code = ERR_UNKNOWN;
654                         goto stop_all_exit;
655                 }
656                 terminate_all();
657                 stop_profiling();
658
659                 if (msg == NULL) {
660                         LOGE("cannot generate stop message\n");
661                         error_code = ERR_UNKNOWN;
662                         goto stop_all_exit;
663                 } else {
664                         if (ioctl_send_msg(msg) != 0) {
665                                 LOGE("ioctl send failed\n");
666                                 error_code = ERR_UNKNOWN;
667                                 free_msg(msg);
668                                 goto stop_all_exit;
669                         }
670                         free_msg(msg);
671                 }
672
673                 // we reset only app inst no lib no confing reset
674                 reset_app_inst(&prof_session.user_space_inst);
675                 stop_transfer();
676                 running_status_off(&prof_session);
677         } else
678                 LOGI("already stopped\n");
679
680 stop_all_exit:
681         LOGI("finished: ret = %d\n", error_code);
682         return error_code;
683 }
684
685 int stop_all_in_process(void)
686 {
687         return (pthread_mutex_trylock(&stop_all_mutex) != 0);
688 }
689
690 void stop_all_done(void)
691 {
692         pthread_mutex_unlock(&stop_all_mutex);
693 }
694
695 enum ErrorCode stop_all(void)
696 {
697         enum ErrorCode error_code = ERR_NO;
698
699         pthread_mutex_lock(&stop_all_mutex);
700         error_code = stop_all_no_lock();
701         pthread_mutex_unlock(&stop_all_mutex);
702
703         return error_code;
704 }
705
706 struct binary_ack {
707         uint32_t type;
708         char *binpath;
709         md5_byte_t digest[16];
710 };
711
712 static void binary_ack_free(struct binary_ack *ba)
713 {
714         if (ba)
715                 free(ba->binpath);
716         free(ba);
717 }
718
719 static size_t binary_ack_size(const struct binary_ack *ba)
720 {
721         /* MD5 is 16 bytes, so 16*2 hex digits */
722         return sizeof(uint32_t) + strlen(ba->binpath) + 1
723                 + 2*16 + 1;
724 }
725
726 static size_t binary_ack_pack(char *s, const struct binary_ack *ba)
727 {
728         unsigned int len = strlen(ba->binpath);
729         int i;
730         *(uint32_t *) s = ba->type;
731         s += sizeof(uint32_t);
732
733         if (len)
734                 memmove(s, ba->binpath, len);
735
736         *(s += len) = '\0';
737         s += 1;
738
739         for (i = 0; i!= 16; ++i) {
740                 sprintf(s, "%02x", ba->digest[i]);
741                 s += 2;
742         }
743         *s = '\0';
744         return sizeof(uint32_t) + len + 1 + 2*16 + 1;
745 }
746
747 static void get_file_md5sum(md5_byte_t digest[16], const char *filename)
748 {
749         md5_byte_t buffer[1024];
750         ssize_t size;
751         md5_state_t md5_state;
752         int fd = open(filename, O_RDONLY);
753
754         md5_init(&md5_state);
755         if (fd > 0)
756                 while ((size = read(fd, buffer, sizeof(buffer))) > 0)
757                         md5_append(&md5_state, buffer, size);
758
759         md5_finish(&md5_state, digest);
760         close(fd);
761 }
762
763 static const char* basename(const char *filename)
764 {
765         const char *p = strrchr(filename, '/');
766         return p ? p + 1 : NULL;
767 }
768 static struct binary_ack* binary_ack_alloc(const char *filename)
769 {
770         struct binary_ack *ba = malloc(sizeof(*ba));
771         char builddir[PATH_MAX];
772         char binpath[PATH_MAX];
773
774         ba->type = get_binary_type(filename);
775
776         get_build_dir(builddir, filename);
777
778         snprintf(binpath, sizeof(binpath), "%s/%s",
779                  builddir, basename(filename) ?: "");
780
781         ba->binpath = strdup(binpath);
782
783         get_file_md5sum(ba->digest, filename);
784
785         return ba;
786 }
787
788 static int process_msg_binary_info(struct msg_buf_t *msg)
789 {
790         uint32_t i, bincount;
791
792         if (!parse_int32(msg, &bincount)) {
793                 LOGE("MSG_BINARY_INFO error: No binaries count\n");
794                 return -1;
795         }
796
797         struct binary_ack *acks[bincount];
798         size_t total_size = 0;
799         for (i = 0; i != bincount; ++i) {
800                 const char *str = parse_string_inplace(msg);
801                 if (!str) {
802                         LOGE("MSG_BINARY_INFO error: No enough binaries\n");
803                         return -1;
804                 }
805                 acks[i] = binary_ack_alloc(str);
806                 total_size += binary_ack_size(acks[i]);
807         }
808         typedef uint32_t return_id;
809         typedef uint32_t binary_ack_count;
810         struct msg_t *msg_reply = malloc(sizeof(struct msg_t)
811                                          + sizeof(return_id)
812                                          + sizeof(binary_ack_count)
813                                          + total_size);
814         char *p = msg_reply->payload;
815
816         msg_reply->id = NMSG_BINARY_INFO_ACK;
817         msg_reply->len = total_size + sizeof(return_id)
818                                     + sizeof(binary_ack_count);
819
820         pack_int32(p, ERR_NO);
821         pack_int32(p, bincount);
822
823         for (i = 0; i != bincount; ++i) {
824                 p += binary_ack_pack(p, acks[i]);
825                 binary_ack_free(acks[i]);
826         }
827
828         int err = send_reply(msg_reply);
829         free(msg_reply);
830         return err;
831 }
832
833 static void get_serialized_time(uint32_t dst[2])
834 {
835         struct timeval tv;
836         gettimeofday(&tv, NULL);
837         dst[0] = tv.tv_sec;
838         dst[1] = tv.tv_usec * 1000;
839 }
840
841 static int process_msg_start(struct msg_buf_t *msg_control)
842 {
843         enum ErrorCode err_code = ERR_CANNOT_START_PROFILING;
844         struct msg_t *msg_reply;
845         uint32_t serialized_time[2];
846
847         if (check_running_status(&prof_session) == 1) {
848                 LOGW("Profiling has already been started\n");
849                 goto send_ack;
850         }
851
852         if (!check_conf(&prof_session.conf)) {
853                 LOGE("wrong profile config\n");
854                 goto send_ack;
855         }
856
857         if (msg_start(msg_control, &prof_session.user_space_inst,
858                       &msg_reply, &err_code) != 0) {
859                 LOGE("parse error\n");
860                 goto send_ack;
861         }
862
863         if (prepare_profiling() != 0) {
864                 LOGE("failed to prepare profiling\n");
865                 goto send_ack;
866         }
867
868         if (start_transfer() != 0) {
869                 LOGE("Cannot start transfer\n");
870                 goto send_ack;
871         }
872
873         if (ioctl_send_msg(msg_reply) != 0) {
874                 LOGE("cannot send message to device\n");
875                 goto send_ack;
876         }
877
878         running_status_on(&prof_session);
879
880         if (start_profiling() < 0) {
881                 LOGE("cannot start profiling\n");
882                 if (stop_all() != ERR_NO) {
883                         LOGE("Stop failed\n");
884                         write_msg_error("Stop failed");
885                 }
886                 goto send_ack;
887         }
888
889         err_code = ERR_NO;
890 send_ack:
891         get_serialized_time(serialized_time);
892         sendACKToHost(NMSG_START, err_code, (void *)&serialized_time,
893                       sizeof(serialized_time));
894
895         return -(err_code != ERR_NO);
896 }
897
898 static int process_msg_get_screenshot(struct msg_buf_t *msg_control)
899 {
900         int target_index;
901         int sock;
902         uint32_t log_len;
903         msg_target_t sendlog;
904         enum ErrorCode err_code = ERR_UNKNOWN;
905
906         // send config message to target process
907         sendlog.type = MSG_CAPTURE_SCREEN;
908         sendlog.length = 0;
909         log_len = sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length;
910
911         for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++) {
912                 sock = manager.target[target_index].socket;
913                 if (sock != -1) {
914                         if (send(sock, &sendlog, log_len, MSG_NOSIGNAL) == -1) {
915                                 LOGE("fail to send data to target index(%d)\n",
916                                      target_index);
917                         } else {
918                                 err_code = ERR_NO;
919                                 break;
920                         }
921                 }
922         }
923
924         return -(err_code != ERR_NO);
925 }
926
927 int host_message_handler(struct msg_t *msg)
928 {
929         struct target_info_t target_info;
930         struct msg_t *msg_reply = NULL;
931         struct msg_buf_t msg_control;
932         struct conf_t conf;
933         enum ErrorCode error_code = ERR_NO;
934
935         int target_index;
936         msg_target_t sendlog;
937
938         LOGI("MY HANDLE %s (%X)\n", msg_ID_str(msg->id), msg->id);
939         init_parse_control(&msg_control, msg);
940
941         switch (msg->id) {
942         case NMSG_KEEP_ALIVE:
943                 sendACKToHost(msg->id, ERR_NO, 0, 0);
944                 break;
945         case NMSG_START:
946                 return process_msg_start(&msg_control);
947         case NMSG_STOP:
948                 sendACKToHost(msg->id, ERR_NO, 0, 0);
949                 if (stop_all() != ERR_NO) {
950                         LOGE("Stop failed\n");
951                         write_msg_error("Stop failed");
952                 }
953                 break;
954         case NMSG_CONFIG:
955                 error_code = ERR_NO;
956                 if (!parse_msg_config(&msg_control, &conf)) {
957                         LOGE("config parsing error\n");
958                         sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
959                         return -1;
960                 }
961                 if (reconfigure(conf) != 0) {
962                         LOGE("Cannot change configuration\n");
963                         return -1;
964                 }
965                 //write to device
966                 if (ioctl_send_msg(msg) != 0) {
967                         LOGE("ioctl send error\n");
968                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
969                         return -1;
970                 }
971                 //send ack to host
972                 sendACKToHost(msg->id, ERR_NO, 0, 0);
973                 // send config message to target process
974                 sendlog.type = MSG_OPTION;
975                 sendlog.length = sprintf(sendlog.data, "%llu",
976                                      (unsigned long long) prof_session.conf.use_features0);
977                 for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++)
978                 {
979                         if(manager.target[target_index].socket != -1)
980                         {
981                                 if (0 > send(manager.target[target_index].socket, &sendlog,
982                                         sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length,
983                                              MSG_NOSIGNAL))
984                                         LOGE("fail to send data to target index(%d)\n", target_index);
985                         }
986                 }
987                 break;
988         case NMSG_BINARY_INFO:
989                 return process_msg_binary_info(&msg_control);
990         case NMSG_SWAP_INST_ADD:
991                 if (msg_swap_inst_add(&msg_control, &prof_session.user_space_inst,
992                                       &msg_reply, &error_code) != 0) {
993                         LOGE("swap inst add\n");
994                         goto send_ack;
995                 }
996                 if (msg_reply != NULL)
997                         if (ioctl_send_msg(msg_reply) != 0) {
998                                 error_code = ERR_UNKNOWN;
999                                 LOGE("ioclt send error\n");
1000                         }
1001                 //send ack to host
1002                 goto send_ack;
1003         case NMSG_SWAP_INST_REMOVE:
1004                 if (msg_swap_inst_remove(&msg_control, &prof_session.user_space_inst,
1005                                          &msg_reply, &error_code) != 0) {
1006                         LOGE("swap inst remove\n");
1007                         error_code = ERR_UNKNOWN;
1008                         goto send_ack;
1009                 }
1010                 if (msg_reply != NULL) {
1011                         if (ioctl_send_msg(msg_reply) != 0)
1012                                 error_code = ERR_UNKNOWN;
1013                 } else {
1014                         error_code = ERR_UNKNOWN;
1015                 }
1016                 goto send_ack;
1017         case NMSG_GET_TARGET_INFO:
1018                 fill_target_info(&target_info);
1019                 msg_reply = gen_target_info_reply(&target_info);
1020                 if (!msg_reply) {
1021                         LOGE("cannot generate reply message\n");
1022                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1023                         return -1;
1024                 }
1025                 if (send_reply(msg_reply) != 0) {
1026                         LOGE("Cannot send reply\n");
1027                 }
1028                 free(msg_reply);
1029                 reset_target_info(&target_info);
1030                 break;
1031         case NMSG_GET_SCREENSHOT:
1032                 return process_msg_get_screenshot(&msg_control);
1033         default:
1034                 LOGE("unknown message %d <0x%08X>\n", msg->id, msg->id);
1035         }
1036
1037         return 0;
1038
1039 send_ack:
1040         sendACKToHost(msg->id, error_code, 0, 0);
1041         if (msg_reply != NULL)
1042                 free(msg_reply);
1043         return (error_code == ERR_NO);
1044 }
1045
1046 // testing
1047
1048 static void print_conf(struct conf_t *conf)
1049 {
1050         char buf[1024];
1051         memset(&buf[0], 0, 1024);
1052         feature_code_str(conf->use_features0, conf->use_features1, buf);
1053         LOGI("conf = \n");
1054         LOGI("\tuse_features = 0x%016LX : 0x%016LX \n(\t%s)\n",
1055              conf->use_features0, conf->use_features1, buf);
1056         LOGI(
1057                  "\tsystem_trace_period = %d ms\n"
1058                  "\tdata message period = %d ms\n",
1059                  conf->system_trace_period,
1060                  conf->data_message_period
1061                  );
1062 }
1063
1064 void print_replay_event(struct replay_event_t *ev, uint32_t num, char *tab)
1065 {
1066         LOGW("%s\t#%04d:time=0x%08X %08X, "
1067                 " id=0x%08X,"
1068                 " type=0x%08X,"
1069                 " code=0x%08X,"
1070                 " value=0x%08X\n",
1071                 tab,num,
1072                 (unsigned int)ev->ev.time.tv_sec,//timeval
1073                 (unsigned int)ev->ev.time.tv_usec,//timeval
1074                 ev->id,
1075                 ev->ev.type,//u16
1076                 ev->ev.code,//u16
1077                 ev->ev.value//s32
1078                 );
1079 }