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