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