8c892225095d9a27cdce7fe2ea6cc854940fc06f
[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 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_app_info(struct app_info_t *app_info);
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 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 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 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 void strip_args(const char *cmd, char *path)
282 {
283         char *bin_end = strchr(cmd, ' ');
284
285         if (!bin_end) {
286                 strcpy(path, cmd);
287         } else {
288                 size_t binname_len = bin_end - cmd;
289                 memcpy(path, cmd, binname_len);
290                 path[binname_len] = '\0';
291         }
292 }
293
294 static int parse_app_info(struct msg_buf_t *msg,
295                                struct app_info_t *app_info)
296 {
297         char bin_path[MAX_FILENAME];
298
299         //Application type
300         parse_deb("parse_app_info\n");
301         if (!parse_int32(msg, &app_info->app_type) ||
302                 !check_app_type(app_info->app_type))
303         {
304                 LOGE("app type error\n");
305                 return 0;
306         }
307         //Application ID
308         if (!parse_string(msg, &app_info->app_id) ||
309                 !check_app_id(app_info->app_type, app_info->app_id))
310         {
311                 LOGE("app id parsing error\n");
312                 return 0;
313         }
314         //Applicaion exe path
315         if (!parse_string(msg, &app_info->exe_path)) {
316                 LOGE("app info parsing error\n");
317                 return 0;
318         }
319         strip_args(app_info->exe_path, bin_path);
320         if (!check_exec_path(bin_path)) {
321                 LOGE("app info parsing error\n");
322                 return 0;
323         }
324 //      print_app_info(app_info);
325         return 1;
326 }
327
328 static int parse_conf(struct msg_buf_t *msg, struct conf_t *conf)
329 {
330
331         parse_deb("parse_conf\n");
332         if (!parse_int64(msg, &conf->use_features0)) {
333                 LOGE("use features0 error\n");
334                 return 0;
335         }
336
337         if (!parse_int64(msg, &conf->use_features1)) {
338                 LOGE("use features1 parsing error\n");
339                 return 0;
340         }
341         //Check features value
342         if (!check_conf_features(conf->use_features0, conf->use_features1)) {
343                 LOGE("check features fail\n");
344                 return 0;
345         }
346
347         if (!parse_int32( msg, &conf->system_trace_period) ||
348                 !check_conf_systrace_period(conf->system_trace_period))
349         {
350                 LOGE("system trace period error\n");
351                 return 0;
352         }
353
354         if (!parse_int32( msg, &conf->data_message_period) ||
355                 !check_conf_datamsg_period(conf->data_message_period))
356         {
357                 LOGE("data message period error\n");
358                 return 0;
359         }
360         //print_conf(conf);
361         return 1;
362 }
363
364 //REPLAY EVENTS PARSE
365 static int parse_timeval(struct msg_buf_t *msg, struct timeval *tv)
366 {
367         uint32_t nsec = 0;
368
369         parse_deb("time\n");
370
371         if (!parse_int32(msg, (uint32_t *)&tv->tv_sec)) {
372                 LOGE("sec parsing error\n");
373                 return 0;
374         }
375
376         if (!parse_int32(msg, &nsec)) {
377                 LOGE("usec parsing error\n");
378                 return 0;
379         }
380         tv->tv_usec = nsec / 1000;
381
382         return 1;
383 }
384
385 static int parse_replay_event(struct msg_buf_t *msg,
386                                     struct replay_event_t *re)
387 {
388
389         if (!parse_timeval(msg, &re->ev.time)) {
390                 LOGE("time parsing error\n");
391                 return 0;
392         }
393
394         if (!parse_int32(msg, &re->id)) {
395                 LOGE("id parsing error\n");
396                 return 0;
397         }
398
399         if (!parse_int32(msg, (uint32_t *)&re->ev.type)) {
400                 LOGE("type parsing error\n");
401                 return 0;
402         }
403
404         if (!parse_int32(msg, (uint32_t *)&re->ev.code)) {
405                 LOGE("code parsing error\n");
406                 return 0;
407         }
408
409         if (!parse_int32(msg, (uint32_t *)&re->ev.value)) {
410                 LOGE("value parsing error\n");
411                 return 0;
412         }
413
414         return 1;
415 }
416
417 void reset_replay_event_seq(struct replay_event_seq_t *res)
418 {
419         res->enabled = 0;
420         res->tv = (struct timeval){0, 0};
421         if (res->event_num != 0)
422                 free(res->events);
423         res->event_num = 0;
424 }
425
426 int parse_replay_event_seq(struct msg_buf_t *msg,
427                            struct replay_event_seq_t *res)
428 {
429         int i = 0;
430         parse_deb("REPLAY\n");
431         if (!parse_int32(msg, &res->enabled)) {
432                 LOGE("enabled parsing error\n");
433                 return 0;
434         }
435
436         if(res->enabled == 0) {
437                 parse_deb("disable\n");
438                 return 1;
439         }
440
441         parse_deb("time main\n");
442         if (!parse_timeval(msg, &res->tv)) {
443                 LOGE("time parsing error\n");
444                 return 0;
445         }
446
447         parse_deb("count\n");
448         if (!parse_int32(msg, &res->event_num)) {
449                 LOGE("event num parsing error\n");
450                 return 0;
451         }
452         parse_deb("events num=%d\n", res->event_num);
453
454         res->events = (struct replay_event_t *)malloc(res->event_num *
455                                                       sizeof(*res->events));
456         if (!res->events) {
457                 LOGE("events alloc error\n");
458                 return 0;
459         }
460
461         for (i = 0; i < res->event_num; i++) {
462                 parse_deb("sub_rep\n");
463                 if (!parse_replay_event(msg, &res->events[i])) {
464                         LOGE("event #%d parsing error\n", i + 1);
465                         free(res->events);
466                         res->event_num = 0;
467                         return 0;
468                 }
469         }
470
471         return 1;
472 }
473
474 //*REPLAY EVENT PARSE
475
476 int get_sys_mem_size(uint32_t *sys_mem_size){
477         struct sysinfo info;
478         sysinfo(&info);
479         *sys_mem_size = info.totalram;
480         return 0;
481 }
482
483 static int parse_msg_config(struct msg_buf_t *msg_payload,
484                               struct conf_t *conf)
485 {
486         if (!parse_conf(msg_payload, conf)) {
487                 LOGE("conf parsing error\n");
488                 return 0;
489         }
490
491         print_conf(conf);
492         return 1;
493 }
494
495 static int parse_msg_binary_info(struct msg_buf_t *msg_payload,
496                               struct app_info_t *app_info)
497 {
498         if (!parse_app_info(msg_payload, app_info)) {
499                 LOGE("app info parsing error\n");
500                 return 0;
501         }
502
503         print_app_info(app_info);
504         return 1;
505 }
506
507 static void init_parse_control(struct msg_buf_t *buf, struct msg_t *msg)
508 {
509         buf->payload = msg->payload;
510         buf->len = msg->len;
511         buf->end = msg->payload + msg->len;
512         buf->cur_pos = msg->payload;
513 }
514
515 static void reset_app_info(struct app_info_t *app_info)
516 {
517         if (app_info->app_id != NULL)
518                 free(app_info->app_id);
519         if (app_info->exe_path != NULL)
520                 free(app_info->exe_path);
521         memset(app_info, 0, sizeof(*app_info));
522 }
523
524 static void reset_target_info(struct target_info_t *target_info)
525 {
526         return;
527 }
528
529 static void reset_conf(struct conf_t *conf)
530 {
531         memset(conf, 0, sizeof(*conf));
532 }
533
534 static void running_status_on(struct prof_session_t *prof_session)
535 {
536         prof_session->running_status = 1;
537 }
538
539 static void running_status_off(struct prof_session_t *prof_session)
540 {
541         prof_session->running_status = 0;
542 }
543
544 int check_running_status(const struct prof_session_t *prof_session)
545 {
546         return prof_session->running_status;
547 }
548
549 static void reset_app_inst(struct user_space_inst_t *us_inst)
550 {
551         free_data_list((struct data_list_t **)&us_inst->app_inst_list);
552         us_inst->app_num = 0;
553         us_inst->app_inst_list = NULL;
554 }
555
556 static void reset_lib_inst(struct user_space_inst_t *us_inst)
557 {
558         free_data_list((struct data_list_t **)&us_inst->lib_inst_list);
559         us_inst->lib_num = 0;
560         us_inst->lib_inst_list = NULL;
561 }
562
563 static void reset_user_space_inst(struct user_space_inst_t *us_inst)
564 {
565         reset_app_inst(us_inst);
566         reset_lib_inst(us_inst);
567 }
568
569 void reset_system_info(struct system_info_t *sys_info)
570 {
571         if (sys_info->thread_load)
572                 free(sys_info->thread_load);
573         if (sys_info->process_load)
574                 free(sys_info->process_load);
575         if (sys_info->cpu_frequency)
576                 free(sys_info->cpu_frequency);
577         if (sys_info->cpu_load)
578                 free(sys_info->cpu_load);
579         memset(sys_info, 0, sizeof(*sys_info));
580 }
581
582 void init_prof_session(struct prof_session_t *prof_session)
583 {
584         memset(prof_session, 0, sizeof(*prof_session));
585 }
586
587 static void reset_prof_session(struct prof_session_t *prof_session)
588 {
589         reset_conf(&prof_session->conf);
590         reset_user_space_inst(&prof_session->user_space_inst);
591         reset_replay_event_seq(&prof_session->replay_event_seq);
592         running_status_off(prof_session);
593 }
594
595 static struct msg_t *gen_binary_info_reply(struct app_info_t *app_info)
596 {
597         uint32_t binary_type = get_binary_type(app_info->exe_path);
598         char binary_path[PATH_MAX];
599         struct msg_t *msg;
600         char *p = NULL;
601         uint32_t ret_id = ERR_NO;
602
603         get_build_dir(binary_path, app_info->exe_path);
604
605         if (binary_type == BINARY_TYPE_UNKNOWN) {
606                 LOGE("Binary is neither relocatable, nor executable\n");
607                 return NULL;
608         }
609
610         msg = malloc(sizeof(*msg) +
611                               sizeof(ret_id) +
612                               sizeof(binary_type) +
613                               strlen(binary_path) + 1);
614         if (!msg) {
615                 LOGE("Cannot alloc bin info msg\n");
616                 return NULL;
617         }
618
619         msg->id = NMSG_BINARY_INFO_ACK;
620         p = msg->payload;
621
622         pack_int32(p, ret_id);
623         pack_int32(p, binary_type);
624         pack_str(p, binary_path);
625
626         msg->len = p - msg->payload;
627
628         return msg;
629 }
630
631 static size_t str_array_getsize(const char **strings, size_t len)
632 {
633         /*!
634          * Calculate about of memory to place array
635          * of \0 delimited strings
636          */
637         size_t size = 0;
638         unsigned int index;
639         for (index = 0; index != len; ++index)
640                 size += strlen(strings[index]) + 1;
641         return size;
642 }
643
644
645 static struct msg_t *gen_target_info_reply(struct target_info_t *target_info)
646 {
647         struct msg_t *msg;
648         char *p = NULL;
649         uint32_t ret_id = ERR_NO;
650
651         msg = malloc(sizeof(*msg) +
652                      sizeof(ret_id) +
653                      sizeof(*target_info) -
654                      sizeof(target_info->network_type) +
655                      strlen(target_info->network_type) + 1 +
656                      sizeof(uint32_t) + /* devices count */
657                      str_array_getsize(supported_devices_strings,
658                                        supported_devices_count));
659         if (!msg) {
660                 LOGE("Cannot alloc target info msg\n");
661                 free(msg);
662                 return NULL;
663         }
664
665         msg->id = NMSG_GET_TARGET_INFO_ACK;
666         p = msg->payload;
667
668         pack_int32(p, ret_id);
669         pack_int64(p, target_info->sys_mem_size);
670         pack_int64(p, target_info->storage_size);
671         pack_int32(p, target_info->bluetooth_supp);
672         pack_int32(p, target_info->gps_supp);
673         pack_int32(p, target_info->wifi_supp);
674         pack_int32(p, target_info->camera_count);
675         pack_str(p, target_info->network_type);
676         pack_int32(p, target_info->max_brightness);
677         pack_int32(p, target_info->cpu_core_count);
678         pack_int32(p, supported_devices_count);
679         p = pack_str_array(p, supported_devices_strings,
680                            supported_devices_count);
681
682         msg->len = p - msg->payload;
683
684         return msg;
685 }
686
687 static int send_reply(struct msg_t *msg)
688 {
689         printBuf((char *)msg, msg->len + sizeof (*msg));
690         if (send(manager.host.control_socket,
691                  msg, MSG_CMD_HDR_LEN + msg->len, MSG_NOSIGNAL) == -1) {
692                 LOGE("Cannot send reply : %s\n", strerror(errno));
693                 return -1;
694         }
695
696         return 0;
697 }
698
699 static void write_msg_error(const char *err_str)
700 {
701         struct msg_data_t *err_msg = gen_message_error(err_str);
702         write_to_buf(err_msg);
703         free_msg_data(err_msg);
704 }
705
706 int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
707                         char *payload, int payload_size)
708 {
709         if (manager.host.control_socket != -1) {
710                 struct msg_t *msg;
711                 uint32_t err = err_code;
712                 int loglen = sizeof(*msg) - sizeof(msg->payload) +
713                                          sizeof(err) + //return ID
714                                          payload_size;
715                 msg = malloc(loglen);
716                 char *p = msg->payload;
717
718                 //get ack message ID
719                 switch (resp) {
720                         case NMSG_KEEP_ALIVE:
721                                 resp = NMSG_KEEP_ALIVE_ACK;
722                                 break;
723                         case NMSG_START:
724                                 resp = NMSG_START_ACK;
725                                 break;
726                         case NMSG_STOP:
727                                 resp = NMSG_STOP_ACK;
728                                 break;
729                         case NMSG_CONFIG:
730                                 resp = NMSG_CONFIG_ACK;
731                                 break;
732                         case NMSG_BINARY_INFO:
733                                 resp = NMSG_BINARY_INFO_ACK;
734                                 break;
735                         case NMSG_GET_TARGET_INFO:
736                                 resp = NMSG_GET_TARGET_INFO_ACK;
737                                 break;
738                         case NMSG_SWAP_INST_ADD:
739                                 resp = NMSG_SWAP_INST_ADD_ACK;
740                                 break;
741                         case NMSG_SWAP_INST_REMOVE:
742                                 resp = NMSG_SWAP_INST_REMOVE_ACK;
743                                 break;
744                         default:
745                                 //TODO report error
746                                 LOGE("unknown message ID [0x%X]\n", resp);
747                                 free(msg);
748                                 return 1;
749                 }
750
751                 //set message id
752                 msg->id = resp;
753                 //set payload lenth
754                 msg->len = payload_size + sizeof(err);
755                 //set return id
756                 pack_int32(p, err);
757                 //copy payload data
758                 memcpy(p, payload, payload_size);
759
760                 LOGI("ACK (%s) errcode<%s> payload=0x%08X; size=%d\n", msg_ID_str(resp),
761                                 msgErrStr(err_code), (int)payload, payload_size);
762                 printBuf((char *)msg, loglen);
763
764                 if (send(manager.host.control_socket, msg,
765                          loglen, MSG_NOSIGNAL) == -1) {
766                         LOGE("Cannot send reply: %s\n", strerror(errno));
767                         free(msg);
768                         return 1;
769                 }
770                 free(msg);
771                 return 0;
772         } else
773                 return 1;
774 }
775
776 struct msg_t *gen_stop_msg(void)
777 {
778         struct msg_t *res = malloc(sizeof(*res));
779         memset(res, 0, sizeof(*res));
780         res->id = NMSG_STOP;
781         res->len = 0;
782         return res;
783 }
784
785
786 enum ErrorCode stop_all_no_lock(void)
787 {
788         enum ErrorCode error_code = ERR_NO;
789         struct msg_t *msg;
790
791         // stop all only if it has not been called yet
792         if (check_running_status(&prof_session)) {
793                 msg = gen_stop_msg();
794                 terminate_all();
795                 stop_profiling();
796
797                 if (msg == NULL) {
798                         LOGE("cannot generate stop message\n");
799                         error_code = ERR_UNKNOWN;
800                         goto stop_all_exit;
801                 } else {
802                         if (ioctl_send_msg(msg) != 0) {
803                                 LOGE("ioctl send failed\n");
804                                 error_code = ERR_UNKNOWN;
805                                 free_msg(msg);
806                                 goto stop_all_exit;
807                         }
808                         free_msg(msg);
809                 }
810
811                 // we reset only app inst no lib no confing reset
812                 reset_app_inst(&prof_session.user_space_inst);
813                 stop_transfer();
814                 running_status_off(&prof_session);
815         } else
816                 LOGI("already stopped\n");
817
818 stop_all_exit:
819         LOGI("finished: ret = %d\n", error_code);
820         return error_code;
821 }
822
823 int stop_all_in_process(void)
824 {
825         return (pthread_mutex_trylock(&stop_all_mutex) != 0);
826 }
827
828 void stop_all_done(void)
829 {
830         pthread_mutex_unlock(&stop_all_mutex);
831 }
832
833 enum ErrorCode stop_all(void)
834 {
835         enum ErrorCode error_code = ERR_NO;
836
837         pthread_mutex_lock(&stop_all_mutex);
838         error_code = stop_all_no_lock();
839         pthread_mutex_unlock(&stop_all_mutex);
840
841         return error_code;
842 }
843
844 struct binary_ack {
845         uint32_t type;
846         char *binpath;
847         md5_byte_t digest[16];
848 };
849
850 static void binary_ack_free(struct binary_ack *ba)
851 {
852         if (ba)
853                 free(ba->binpath);
854         free(ba);
855 }
856
857 static size_t binary_ack_size(const struct binary_ack *ba)
858 {
859         /* MD5 is 16 bytes, so 16*2 hex digits */
860         return sizeof(uint32_t) + strlen(ba->binpath) + 1
861                 + 2*16 + 1;
862 }
863
864 static size_t binary_ack_pack(char *s, const struct binary_ack *ba)
865 {
866         unsigned int len = strlen(ba->binpath);
867         int i;
868         *(uint32_t *) s = ba->type;
869         s += sizeof(uint32_t);
870
871         if (len)
872                 memmove(s, ba->binpath, len);
873
874         *(s += len) = '\0';
875         s += 1;
876
877         for (i = 0; i!= 16; ++i) {
878                 sprintf(s, "%02x", ba->digest[i]);
879                 s += 2;
880         }
881         *s = '\0';
882         return sizeof(uint32_t) + len + 1 + 2*16 + 1;
883 }
884
885 static void get_file_md5sum(md5_byte_t digest[16], const char *filename)
886 {
887         md5_byte_t buffer[1024];
888         ssize_t size;
889         md5_state_t md5_state;
890         int fd = open(filename, O_RDONLY);
891
892         md5_init(&md5_state);
893         if (fd > 0)
894                 while ((size = read(fd, buffer, sizeof(buffer))) > 0)
895                         md5_append(&md5_state, buffer, size);
896
897         md5_finish(&md5_state, digest);
898         close(fd);
899 }
900
901 static const char* basename(const char *filename)
902 {
903         const char *p = strrchr(filename, '/');
904         return p ? p + 1 : NULL;
905 }
906 static struct binary_ack* binary_ack_alloc(const char *filename)
907 {
908         struct binary_ack *ba = malloc(sizeof(*ba));
909         char builddir[PATH_MAX];
910         char binpath[PATH_MAX];
911
912         ba->type = get_binary_type(filename);
913
914         get_build_dir(builddir, filename);
915
916         snprintf(binpath, sizeof(binpath), "%s/%s",
917                  builddir, basename(filename) ?: "");
918
919         ba->binpath = strdup(binpath);
920
921         get_file_md5sum(ba->digest, filename);
922
923         return ba;
924 }
925
926 static int process_msg_binary_info(struct msg_buf_t *msg)
927 {
928         uint32_t i, bincount;
929
930         if (!parse_int32(msg, &bincount)) {
931                 LOGE("MSG_BINARY_INFO error: No binaries count\n");
932                 return -1;
933         }
934
935         struct binary_ack *acks[bincount];
936         size_t total_size = 0;
937         for (i = 0; i != bincount; ++i) {
938                 const char *str = parse_string_inplace(msg);
939                 if (!str) {
940                         LOGE("MSG_BINARY_INFO error: No enough binaries\n");
941                         return -1;
942                 }
943                 acks[i] = binary_ack_alloc(str);
944                 total_size += binary_ack_size(acks[i]);
945         }
946         typedef uint32_t return_id;
947         typedef uint32_t binary_ack_count;
948         struct msg_t *msg_reply = malloc(sizeof(struct msg_t)
949                                          + sizeof(return_id)
950                                          + sizeof(binary_ack_count)
951                                          + total_size);
952         char *p = msg_reply->payload;
953
954         msg_reply->id = NMSG_BINARY_INFO_ACK;
955         msg_reply->len = total_size + sizeof(return_id)
956                                     + sizeof(binary_ack_count);
957
958         pack_int32(p, ERR_NO);
959         pack_int32(p, bincount);
960
961         for (i = 0; i != bincount; ++i) {
962                 p += binary_ack_pack(p, acks[i]);
963                 binary_ack_free(acks[i]);
964         }
965
966         int err = send_reply(msg_reply);
967         free(msg_reply);
968         return err;
969 }
970
971 static void get_serialized_time(uint32_t dst[2])
972 {
973         struct timeval tv;
974         gettimeofday(&tv, NULL);
975         dst[0] = tv.tv_sec;
976         dst[1] = tv.tv_usec * 1000;
977 }
978
979 static int process_msg_start(struct msg_buf_t *msg_control)
980 {
981         enum ErrorCode err_code = ERR_CANNOT_START_PROFILING;
982         struct msg_t *msg_reply;
983         uint32_t serialized_time[2];
984
985         if (check_running_status(&prof_session) == 1) {
986                 LOGW("Profiling has already been started\n");
987                 goto send_ack;
988         }
989
990         if (!check_conf(&prof_session.conf)) {
991                 LOGE("wrong profile config\n");
992                 goto send_ack;
993         }
994
995         if (msg_start(msg_control, &prof_session.user_space_inst,
996                       &msg_reply, &err_code) != 0) {
997                 LOGE("parse error\n");
998                 goto send_ack;
999         }
1000
1001         if (prepare_profiling() != 0) {
1002                 LOGE("failed to prepare profiling\n");
1003                 goto send_ack;
1004         }
1005
1006         if (start_transfer() != 0) {
1007                 LOGE("Cannot start transfer\n");
1008                 goto send_ack;
1009         }
1010
1011         if (ioctl_send_msg(msg_reply) != 0) {
1012                 LOGE("cannot send message to device\n");
1013                 goto send_ack;
1014         }
1015
1016         running_status_on(&prof_session);
1017
1018         if (start_profiling() < 0) {
1019                 LOGE("cannot start profiling\n");
1020                 if (stop_all() != ERR_NO) {
1021                         LOGE("Stop failed\n");
1022                         write_msg_error("Stop failed");
1023                 }
1024                 goto send_ack;
1025         }
1026
1027         err_code = ERR_NO;
1028 send_ack:
1029         get_serialized_time(serialized_time);
1030         sendACKToHost(NMSG_START, err_code, (void *)&serialized_time,
1031                       sizeof(serialized_time));
1032
1033         return -(err_code != ERR_NO);
1034 }
1035
1036 int process_msg_get_screenshot(struct msg_buf_t *msg_control)
1037 {
1038         int target_index;
1039         int sock;
1040         uint32_t log_len;
1041         msg_target_t sendlog;
1042         enum ErrorCode err_code = ERR_UNKNOWN;
1043
1044         // send config message to target process
1045         sendlog.type = MSG_CAPTURE_SCREEN;
1046         sendlog.length = sprintf(sendlog.data, "");
1047         log_len = sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length;
1048
1049         for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++) {
1050                 sock = manager.target[target_index].socket;
1051                 if (sock != -1) {
1052                         if (send(sock, &sendlog, log_len, MSG_NOSIGNAL) == -1) {
1053                                 LOGE("fail to send data to target index(%d)\n",
1054                                      target_index);
1055                         } else {
1056                                 err_code = ERR_NO;
1057                                 break;
1058                         }
1059                 }
1060         }
1061
1062         return -(err_code != ERR_NO);
1063 }
1064
1065 int host_message_handler(struct msg_t *msg)
1066 {
1067         struct target_info_t target_info;
1068         struct msg_t *msg_reply = NULL;
1069         struct msg_buf_t msg_control;
1070         struct conf_t conf;
1071         enum ErrorCode error_code = ERR_NO;
1072
1073         int target_index;
1074         msg_target_t sendlog;
1075
1076         LOGI("MY HANDLE %s (%X)\n", msg_ID_str(msg->id), msg->id);
1077         init_parse_control(&msg_control, msg);
1078
1079         switch (msg->id) {
1080         case NMSG_KEEP_ALIVE:
1081                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1082                 break;
1083         case NMSG_START:
1084                 return process_msg_start(&msg_control);
1085         case NMSG_STOP:
1086                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1087                 if (stop_all() != ERR_NO) {
1088                         LOGE("Stop failed\n");
1089                         write_msg_error("Stop failed");
1090                 }
1091                 break;
1092         case NMSG_CONFIG:
1093                 error_code = ERR_NO;
1094                 if (!parse_msg_config(&msg_control, &conf)) {
1095                         LOGE("config parsing error\n");
1096                         sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
1097                         return -1;
1098                 }
1099                 if (reconfigure(conf) != 0) {
1100                         LOGE("Cannot change configuration\n");
1101                         return -1;
1102                 }
1103                 //write to device
1104                 if (ioctl_send_msg(msg) != 0) {
1105                         LOGE("ioctl send error\n");
1106                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1107                         return -1;
1108                 }
1109                 //send ack to host
1110                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1111                 // send config message to target process
1112                 sendlog.type = MSG_OPTION;
1113                 sendlog.length = sprintf(sendlog.data, "%llu",
1114                                      (unsigned long long) prof_session.conf.use_features0);
1115                 for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++)
1116                 {
1117                         if(manager.target[target_index].socket != -1)
1118                         {
1119                                 if (0 > send(manager.target[target_index].socket, &sendlog,
1120                                         sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length,
1121                                              MSG_NOSIGNAL))
1122                                         LOGE("fail to send data to target index(%d)\n", target_index);
1123                         }
1124                 }
1125                 break;
1126         case NMSG_BINARY_INFO:
1127                 return process_msg_binary_info(&msg_control);
1128         case NMSG_SWAP_INST_ADD:
1129                 if (msg_swap_inst_add(&msg_control, &prof_session.user_space_inst,
1130                                       &msg_reply, &error_code) != 0) {
1131                         LOGE("swap inst add\n");
1132                         goto send_ack;
1133                 }
1134                 if (msg_reply != NULL)
1135                         if (ioctl_send_msg(msg_reply) != 0) {
1136                                 error_code = ERR_UNKNOWN;
1137                                 LOGE("ioclt send error\n");
1138                         }
1139                 //send ack to host
1140                 goto send_ack;
1141         case NMSG_SWAP_INST_REMOVE:
1142                 if (msg_swap_inst_remove(&msg_control, &prof_session.user_space_inst,
1143                                          &msg_reply, &error_code) != 0) {
1144                         LOGE("swap inst remove\n");
1145                         error_code = ERR_UNKNOWN;
1146                         goto send_ack;
1147                 }
1148                 if (msg_reply != NULL) {
1149                         if (ioctl_send_msg(msg_reply) != 0)
1150                                 error_code = ERR_UNKNOWN;
1151                 } else {
1152                         error_code = ERR_UNKNOWN;
1153                 }
1154                 goto send_ack;
1155         case NMSG_GET_TARGET_INFO:
1156                 fill_target_info(&target_info);
1157                 msg_reply = gen_target_info_reply(&target_info);
1158                 if (!msg_reply) {
1159                         LOGE("cannot generate reply message\n");
1160                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1161                         return -1;
1162                 }
1163                 if (send_reply(msg_reply) != 0) {
1164                         LOGE("Cannot send reply\n");
1165                 }
1166                 free(msg_reply);
1167                 reset_target_info(&target_info);
1168                 break;
1169         case NMSG_GET_SCREENSHOT:
1170                 return process_msg_get_screenshot(&msg_control);
1171         default:
1172                 LOGE("unknown message %d <0x%08X>\n", msg->id, msg->id);
1173         }
1174
1175         return 0;
1176
1177 send_ack:
1178         sendACKToHost(msg->id, error_code, 0, 0);
1179         if (msg_reply != NULL)
1180                 free(msg_reply);
1181         return (error_code == ERR_NO);
1182 }
1183
1184 // testing
1185
1186 static void print_app_info(struct app_info_t *app_info)
1187 {
1188         LOGI("application info=\n");
1189         LOGI("\tapp_type=<%d><0x%04X>\n"
1190                  "\tapp_id=<%s>\n"
1191                  "\texe_path=<%s>\n",
1192                  app_info->app_type,
1193                  app_info->app_type,
1194                  app_info->app_id,
1195                  app_info->exe_path
1196         );
1197 }
1198
1199 static void print_conf(struct conf_t *conf)
1200 {
1201         char buf[1024];
1202         memset(&buf[0], 0, 1024);
1203         feature_code_str(conf->use_features0, conf->use_features1, buf);
1204         LOGI("conf = \n");
1205         LOGI("\tuse_features = 0x%016LX : 0x%016LX \n(\t%s)\n",
1206              conf->use_features0, conf->use_features1, buf);
1207         LOGI(
1208                  "\tsystem_trace_period = %d ms\n"
1209                  "\tdata message period = %d ms\n",
1210                  conf->system_trace_period,
1211                  conf->data_message_period
1212                  );
1213 }
1214
1215 void print_replay_event(struct replay_event_t *ev, uint32_t num, char *tab)
1216 {
1217         LOGW("%s\t#%04d:time=0x%08X %08X, "
1218                 " id=0x%08X,"
1219                 " type=0x%08X,"
1220                 " code=0x%08X,"
1221                 " value=0x%08X\n",
1222                 tab,num,
1223                 (unsigned int)ev->ev.time.tv_sec,//timeval
1224                 (unsigned int)ev->ev.time.tv_usec,//timeval
1225                 ev->id,
1226                 ev->ev.type,//u16
1227                 ev->ev.code,//u16
1228                 ev->ev.value//s32
1229                 );
1230 }
1231
1232 void print_replay_event_seq(struct replay_event_seq_t *event_seq)
1233 {
1234         uint32_t i = 0;
1235         char *tab = "\t";
1236
1237         LOGI( "%senabled=0x%08X; "\
1238                 "time_start=0x%08X %08X; "\
1239                 "count=0x%08X\n",
1240                 tab,event_seq->enabled,
1241                 (unsigned int)event_seq->tv.tv_sec,
1242                 (unsigned int)event_seq->tv.tv_usec,
1243                 event_seq->event_num);
1244         for (i=0;i<event_seq->event_num;i++)
1245                 print_replay_event(&event_seq->events[i], i+1, tab);
1246
1247 }