[FIX] wrong pack size of system memory total/used
[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 static pthread_mutex_t stop_all_mutex = PTHREAD_MUTEX_INITIALIZER;
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 running_status_on(struct prof_session_t *prof_session)
547 {
548         prof_session->running_status = 1;
549 }
550
551 static void running_status_off(struct prof_session_t *prof_session)
552 {
553         prof_session->running_status = 0;
554 }
555
556 int check_running_status(struct prof_session_t *prof_session)
557 {
558         return prof_session->running_status;
559 }
560
561 static void reset_app_inst(struct user_space_inst_t *us_inst)
562 {
563         free_data_list((struct data_list_t **)&us_inst->app_inst_list);
564         us_inst->app_num = 0;
565         us_inst->app_inst_list = NULL;
566 }
567
568 static void reset_lib_inst(struct user_space_inst_t *us_inst)
569 {
570         free_data_list((struct data_list_t **)&us_inst->lib_inst_list);
571         us_inst->lib_num = 0;
572         us_inst->lib_inst_list = NULL;
573 }
574
575 static void reset_user_space_inst(struct user_space_inst_t *us_inst)
576 {
577         reset_app_inst(us_inst);
578         reset_lib_inst(us_inst);
579 }
580
581 void reset_system_info(struct system_info_t *sys_info)
582 {
583         if (sys_info->thread_load)
584                 free(sys_info->thread_load);
585         if (sys_info->process_load)
586                 free(sys_info->process_load);
587         if (sys_info->cpu_frequency)
588                 free(sys_info->cpu_frequency);
589         if (sys_info->cpu_load)
590                 free(sys_info->cpu_load);
591         memset(sys_info, 0, sizeof(*sys_info));
592 }
593
594 void init_prof_session(struct prof_session_t *prof_session)
595 {
596         memset(prof_session, 0, sizeof(*prof_session));
597 }
598
599 static void reset_prof_session(struct prof_session_t *prof_session)
600 {
601         reset_conf(&prof_session->conf);
602         reset_user_space_inst(&prof_session->user_space_inst);
603         reset_replay_event_seq(&prof_session->replay_event_seq);
604         running_status_off(prof_session);
605 }
606
607 static struct msg_t *gen_binary_info_reply(struct app_info_t *app_info)
608 {
609         uint32_t binary_type = get_binary_type(app_info->exe_path);
610         char binary_path[PATH_MAX];
611         struct msg_t *msg;
612         char *p = NULL;
613         uint32_t ret_id = ERR_NO;
614
615         get_build_dir(binary_path, app_info->exe_path);
616
617         if (binary_type == BINARY_TYPE_UNKNOWN) {
618                 LOGE("Binary is neither relocatable, nor executable\n");
619                 return NULL;
620         }
621
622         msg = malloc(sizeof(*msg) +
623                               sizeof(ret_id) +
624                               sizeof(binary_type) +
625                               strlen(binary_path) + 1);
626         if (!msg) {
627                 LOGE("Cannot alloc bin info msg\n");
628                 return NULL;
629         }
630
631         msg->id = NMSG_BINARY_INFO_ACK;
632         p = msg->payload;
633
634         pack_int(p, ret_id);
635         pack_int(p, binary_type);
636         pack_str(p, binary_path);
637
638         msg->len = p - msg->payload;
639
640         return msg;
641 }
642
643 static size_t str_array_getsize(const char **strings, size_t len)
644 {
645         /*!
646          * Calculate about of memory to place array
647          * of \0 delimited strings
648          */
649         size_t size = 0;
650         unsigned int index;
651         for (index = 0; index != len; ++index)
652                 size += strlen(strings[index]) + 1;
653         return size;
654 }
655
656
657 static struct msg_t *gen_target_info_reply(struct target_info_t *target_info)
658 {
659         struct msg_t *msg;
660         char *p = NULL;
661         uint32_t ret_id = ERR_NO;
662
663         msg = malloc(sizeof(*msg) +
664                      sizeof(ret_id) +
665                      sizeof(*target_info) -
666                      sizeof(target_info->network_type) +
667                      strlen(target_info->network_type) + 1 +
668                      sizeof(uint32_t) + /* devices count */
669                      str_array_getsize(supported_devices_strings,
670                                        supported_devices_count));
671         if (!msg) {
672                 LOGE("Cannot alloc target info msg\n");
673                 free(msg);
674                 return NULL;
675         }
676
677         msg->id = NMSG_GET_TARGET_INFO_ACK;
678         p = msg->payload;
679
680         pack_int(p, ret_id);
681         pack_int64(p, target_info->sys_mem_size);
682         pack_int64(p, target_info->storage_size);
683         pack_int(p, target_info->bluetooth_supp);
684         pack_int(p, target_info->gps_supp);
685         pack_int(p, target_info->wifi_supp);
686         pack_int(p, target_info->camera_count);
687         pack_str(p, target_info->network_type);
688         pack_int(p, target_info->max_brightness);
689         pack_int(p, target_info->cpu_core_count);
690         pack_int32(p, supported_devices_count);
691         p = pack_str_array(p, supported_devices_strings,
692                            supported_devices_count);
693
694         msg->len = p - msg->payload;
695
696         return msg;
697 }
698
699 static int send_reply(struct msg_t *msg)
700 {
701         printBuf((char *)msg, msg->len + sizeof (*msg));
702         if (send(manager.host.control_socket,
703                  msg, MSG_CMD_HDR_LEN + msg->len, MSG_NOSIGNAL) == -1) {
704                 LOGE("Cannot send reply : %s\n", strerror(errno));
705                 return -1;
706         }
707
708         return 0;
709 }
710
711 static void write_msg_error(const char *err_str)
712 {
713         struct msg_data_t *err_msg = gen_message_error(err_str);
714         write_to_buf(err_msg);
715         free_msg_data(err_msg);
716 }
717
718 int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
719                         char *payload, int payload_size)
720 {
721         if (manager.host.control_socket != -1) {
722                 struct msg_t *msg;
723                 uint32_t err = err_code;
724                 int loglen = sizeof(*msg) - sizeof(msg->payload) +
725                                          sizeof(err) + //return ID
726                                          payload_size;
727                 msg = malloc(loglen);
728                 char *p = msg->payload;
729
730                 //get ack message ID
731                 switch (resp) {
732                         case NMSG_KEEP_ALIVE:
733                                 resp = NMSG_KEEP_ALIVE_ACK;
734                                 break;
735                         case NMSG_START:
736                                 resp = NMSG_START_ACK;
737                                 break;
738                         case NMSG_STOP:
739                                 resp = NMSG_STOP_ACK;
740                                 break;
741                         case NMSG_CONFIG:
742                                 resp = NMSG_CONFIG_ACK;
743                                 break;
744                         case NMSG_BINARY_INFO:
745                                 resp = NMSG_BINARY_INFO_ACK;
746                                 break;
747                         case NMSG_GET_TARGET_INFO:
748                                 resp = NMSG_GET_TARGET_INFO_ACK;
749                                 break;
750                         case NMSG_SWAP_INST_ADD:
751                                 resp = NMSG_SWAP_INST_ADD_ACK;
752                                 break;
753                         case NMSG_SWAP_INST_REMOVE:
754                                 resp = NMSG_SWAP_INST_REMOVE_ACK;
755                                 break;
756                         default:
757                                 //TODO report error
758                                 free(msg);
759                                 return 1;
760                 }
761
762                 //set message id
763                 msg->id = resp;
764                 //set payload lenth
765                 msg->len = payload_size + sizeof(err);
766                 //set return id
767                 //*(uint32_t *)p = err; p+=sizeof(err);
768                 pack_int(p, err);
769                 //copy payload data
770                 memcpy(p, payload, payload_size);
771
772                 LOGI("ACK (%s) errcode<%s> payload=0x%08X; size=%d\n", msg_ID_str(resp),
773                                 msgErrStr(err_code), (int)payload, payload_size);
774                 printBuf((char *)msg, loglen);
775
776                 if (send(manager.host.control_socket, msg,
777                          loglen, MSG_NOSIGNAL) == -1) {
778                         LOGE("Cannot send reply: %s\n", strerror(errno));
779                         free(msg);
780                         return 1;
781                 }
782                 free(msg);
783                 return 0;
784         } else
785                 return 1;
786 }
787
788 struct msg_t *gen_stop_msg(void)
789 {
790         struct msg_t *res = malloc(sizeof(*res));
791         memset(res, 0, sizeof(*res));
792         res->id = NMSG_STOP;
793         res->len = 0;
794         return res;
795 }
796
797
798 enum ErrorCode stop_all_no_lock(void)
799 {
800         enum ErrorCode error_code = ERR_NO;
801         struct msg_t *msg;
802
803         // stop all only if it has not been called yet
804         if (check_running_status(&prof_session)) {
805                 msg = gen_stop_msg();
806                 terminate_all();
807                 stop_profiling();
808
809                 if (msg == NULL) {
810                         LOGE("cannot generate stop message\n");
811                         error_code = ERR_UNKNOWN;
812                         goto stop_all_exit;
813                 } else {
814                         if (ioctl_send_msg(msg) != 0) {
815                                 LOGE("ioctl send failed\n");
816                                 error_code = ERR_UNKNOWN;
817                                 free_msg(msg);
818                                 goto stop_all_exit;
819                         }
820                         free_msg(msg);
821                 }
822
823                 // we reset only app inst no lib no confing reset
824                 reset_app_inst(&prof_session.user_space_inst);
825                 stop_transfer();
826                 running_status_off(&prof_session);
827         } else
828                 LOGI("already stopped\n");
829
830 stop_all_exit:
831         LOGI("finished: ret = %d\n", error_code);
832         return error_code;
833 }
834
835 int stop_all_in_process(void)
836 {
837         return (pthread_mutex_trylock(&stop_all_mutex) != 0);
838 }
839
840 void stop_all_done(void)
841 {
842         pthread_mutex_unlock(&stop_all_mutex);
843 }
844
845 enum ErrorCode stop_all(void)
846 {
847         enum ErrorCode error_code = ERR_NO;
848
849         pthread_mutex_lock(&stop_all_mutex);
850         error_code = stop_all_no_lock();
851         pthread_mutex_unlock(&stop_all_mutex);
852
853         return error_code;
854 }
855
856 struct binary_ack {
857         uint32_t type;
858         char *binpath;
859         md5_byte_t digest[16];
860 };
861
862 static void binary_ack_free(struct binary_ack *ba)
863 {
864         if (ba)
865                 free(ba->binpath);
866         free(ba);
867 }
868
869 static size_t binary_ack_size(const struct binary_ack *ba)
870 {
871         /* MD5 is 16 bytes, so 16*2 hex digits */
872         return sizeof(uint32_t) + strlen(ba->binpath) + 1
873                 + 2*16 + 1;
874 }
875
876 static size_t binary_ack_pack(char *s, const struct binary_ack *ba)
877 {
878         unsigned int len = strlen(ba->binpath);
879         int i;
880         *(uint32_t *) s = ba->type;
881         s += sizeof(uint32_t);
882
883         if (len)
884                 memmove(s, ba->binpath, len);
885
886         *(s += len) = '\0';
887         s += 1;
888
889         for (i = 0; i!= 16; ++i) {
890                 sprintf(s, "%02x", ba->digest[i]);
891                 s += 2;
892         }
893         *s = '\0';
894         return sizeof(uint32_t) + len + 1 + 2*16 + 1;
895 }
896
897 static void get_file_md5sum(md5_byte_t digest[16], const char *filename)
898 {
899         char buffer[1024];
900         ssize_t size;
901         md5_state_t md5_state;
902         int fd = open(filename, O_RDONLY);
903
904         md5_init(&md5_state);
905         if (fd > 0)
906                 while ((size = read(fd, buffer, sizeof(buffer))) > 0)
907                         md5_append(&md5_state, buffer, size);
908
909         md5_finish(&md5_state, digest);
910         close(fd);
911 }
912
913 static const char* basename(const char *filename)
914 {
915         const char *p = strrchr(filename, '/');
916         return p ? p + 1 : NULL;
917 }
918 static struct binary_ack* binary_ack_alloc(const char *filename)
919 {
920         struct binary_ack *ba = malloc(sizeof(*ba));
921         char builddir[PATH_MAX];
922         char binpath[PATH_MAX];
923
924         ba->type = get_binary_type(filename);
925
926         get_build_dir(builddir, filename);
927
928         snprintf(binpath, sizeof(binpath), "%s/%s",
929                  builddir, basename(filename) ?: "");
930
931         ba->binpath = strdup(binpath);
932
933         get_file_md5sum(ba->digest, filename);
934
935         return ba;
936 }
937
938 static int process_msg_binary_info(struct msg_buf_t *msg)
939 {
940         uint32_t i, bincount;
941
942         if (!parse_int32(msg, &bincount)) {
943                 LOGE("MSG_BINARY_INFO error: No binaries count\n");
944                 return -1;
945         }
946
947         struct binary_ack *acks[bincount];
948         size_t total_size = 0;
949         for (i = 0; i != bincount; ++i) {
950                 const char *str = parse_string_inplace(msg);
951                 if (!str) {
952                         LOGE("MSG_BINARY_INFO error: No enough binaries\n");
953                         return -1;
954                 }
955                 acks[i] = binary_ack_alloc(str);
956                 total_size += binary_ack_size(acks[i]);
957         }
958         typedef uint32_t return_id;
959         typedef uint32_t binary_ack_count;
960         struct msg_t *msg_reply = malloc(sizeof(struct msg_t)
961                                          + sizeof(return_id)
962                                          + sizeof(binary_ack_count)
963                                          + total_size);
964         char *p = msg_reply->payload;
965
966         msg_reply->id = NMSG_BINARY_INFO_ACK;
967         msg_reply->len = total_size + sizeof(return_id)
968                                     + sizeof(binary_ack_count);
969
970         pack_int32(p, ERR_NO);
971         pack_int32(p, bincount);
972
973         for (i = 0; i != bincount; ++i) {
974                 p += binary_ack_pack(p, acks[i]);
975                 binary_ack_free(acks[i]);
976         }
977
978         int err = send_reply(msg_reply);
979         free(msg_reply);
980         return err;
981 }
982
983 static void get_serialized_time(uint32_t dst[2])
984 {
985         struct timeval tv;
986         gettimeofday(&tv, NULL);
987         dst[0] = tv.tv_sec;
988         dst[1] = tv.tv_usec * 1000;
989 }
990
991 static int process_msg_start(struct msg_buf_t *msg_control)
992 {
993         enum ErrorCode err_code = ERR_CANNOT_START_PROFILING;
994         struct msg_t *msg_reply;
995         uint32_t serialized_time[2];
996
997         if (!check_conf(&prof_session.conf)) {
998                 LOGE("wrong profile config\n");
999                 goto send_ack;
1000         }
1001
1002         if (msg_start(msg_control, &prof_session.user_space_inst,
1003                       &msg_reply, &err_code) != 0) {
1004                 LOGE("parse error\n");
1005                 goto send_ack;
1006         }
1007
1008         if (start_transfer() != 0) {
1009                 LOGE("Cannot start transfer\n");
1010                 goto send_ack;
1011         }
1012
1013         if (ioctl_send_msg(msg_reply) != 0) {
1014                 LOGE("cannot send message to device\n");
1015                 goto send_ack;
1016         }
1017
1018         running_status_on(&prof_session);
1019
1020         if (start_profiling() < 0) {
1021                 LOGE("cannot start profiling\n");
1022                 if (stop_all() != ERR_NO) {
1023                         LOGE("Stop failed\n");
1024                         write_msg_error("Stop failed");
1025                 }
1026                 goto send_ack;
1027         }
1028
1029         err_code = ERR_NO;
1030 send_ack:
1031         get_serialized_time(&serialized_time);
1032         sendACKToHost(NMSG_START, err_code, (void *)&serialized_time,
1033                       sizeof(serialized_time));
1034
1035         return -(err_code != ERR_NO);
1036 }
1037
1038 int host_message_handler(struct msg_t *msg)
1039 {
1040         struct app_info_t app_info;
1041         struct target_info_t target_info;
1042         struct msg_t *msg_reply = NULL;
1043         struct msg_buf_t msg_control;
1044         struct conf_t conf;
1045         enum ErrorCode error_code = ERR_NO;
1046
1047         int target_index;
1048         ssize_t sendlen;
1049         msg_target_t sendlog;
1050
1051         LOGI("MY HANDLE %s (%X)\n", msg_ID_str(msg->id), msg->id);
1052         init_parse_control(&msg_control, msg);
1053
1054         switch (msg->id) {
1055         case NMSG_KEEP_ALIVE:
1056                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1057                 break;
1058         case NMSG_START:
1059                 return process_msg_start(&msg_control);
1060         case NMSG_STOP:
1061                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1062                 if (stop_all() != ERR_NO) {
1063                         LOGE("Stop failed\n");
1064                         write_msg_error("Stop failed");
1065                 }
1066                 break;
1067         case NMSG_CONFIG:
1068                 error_code = ERR_NO;
1069                 if (!parse_msg_config(&msg_control, &conf)) {
1070                         LOGE("config parsing error\n");
1071                         sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
1072                         return -1;
1073                 }
1074                 if (reconfigure(conf) != 0) {
1075                         LOGE("Cannot change configuration\n");
1076                         return -1;
1077                 }
1078                 //write to device
1079                 if (ioctl_send_msg(msg) != 0) {
1080                         LOGE("ioctl send error\n");
1081                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1082                         return -1;
1083                 }
1084                 //send ack to host
1085                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1086                 // send config message to target process
1087                 sendlog.type = MSG_OPTION;
1088                 sendlog.length = sprintf(sendlog.data, "%lu",
1089                                      (unsigned long int) prof_session.conf.use_features0);
1090                 for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++)
1091                 {
1092                         if(manager.target[target_index].socket != -1)
1093                         {
1094                                 if (0 > send(manager.target[target_index].socket, &sendlog,
1095                                         sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length,
1096                                              MSG_NOSIGNAL))
1097                                         LOGE("fail to send data to target index(%d)\n", target_index);
1098                         }
1099                 }
1100                 break;
1101         case NMSG_BINARY_INFO:
1102                 return process_msg_binary_info(&msg_control);
1103         case NMSG_SWAP_INST_ADD:
1104                 if (msg_swap_inst_add(&msg_control, &prof_session.user_space_inst,
1105                                       &msg_reply, &error_code) != 0) {
1106                         LOGE("swap inst add\n");
1107                         goto send_ack;
1108                 }
1109                 if (msg_reply != NULL)
1110                         if (ioctl_send_msg(msg_reply) != 0) {
1111                                 error_code = ERR_UNKNOWN;
1112                                 LOGE("ioclt send error\n");
1113                         }
1114                 //send ack to host
1115                 goto send_ack;
1116         case NMSG_SWAP_INST_REMOVE:
1117                 if (msg_swap_inst_remove(&msg_control, &prof_session.user_space_inst,
1118                                          &msg_reply, &error_code) != 0) {
1119                         LOGE("swap inst remove\n");
1120                         error_code = ERR_UNKNOWN;
1121                         goto send_ack;
1122                 }
1123                 if (msg_reply != NULL) {
1124                         if (ioctl_send_msg(msg_reply) != 0)
1125                                 error_code = ERR_UNKNOWN;
1126                 } else {
1127                         error_code = ERR_UNKNOWN;
1128                 }
1129                 goto send_ack;
1130         case NMSG_GET_TARGET_INFO:
1131                 fill_target_info(&target_info);
1132                 msg_reply = gen_target_info_reply(&target_info);
1133                 if (!msg_reply) {
1134                         LOGE("cannot generate reply message\n");
1135                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1136                         return -1;
1137                 }
1138                 if (send_reply(msg_reply) != 0) {
1139                         LOGE("Cannot send reply\n");
1140                 }
1141                 free(msg_reply);
1142                 reset_target_info(&target_info);
1143                 break;
1144
1145         default:
1146                 LOGE("unknown message %d <0x%08X>\n", msg->id, msg->id);
1147         }
1148
1149         return 0;
1150
1151 send_ack:
1152         sendACKToHost(msg->id, error_code, 0, 0);
1153         if (msg_reply != NULL)
1154                 free(msg_reply);
1155         return (error_code == ERR_NO);
1156 }
1157
1158 // testing
1159
1160 static void print_app_info(struct app_info_t *app_info)
1161 {
1162         LOGI("application info=\n");
1163         LOGI("\tapp_type=<%d><0x%04X>\n"
1164                  "\tapp_id=<%s>\n"
1165                  "\texe_path=<%s>\n",
1166                  app_info->app_type,
1167                  app_info->app_type,
1168                  app_info->app_id,
1169                  app_info->exe_path
1170         );
1171 }
1172
1173 static void print_conf(struct conf_t *conf)
1174 {
1175         char buf[1024];
1176         memset(&buf[0], 0, 1024);
1177         feature_code_str(conf->use_features0, buf);
1178         LOGI("conf = \n");
1179         LOGI("\tuse_features0 = 0x%016LX (%s)\n", conf->use_features0, buf);
1180         LOGI("\tuse_features1 = 0x%016LX (%s)\n", conf->use_features1, buf);
1181         LOGI(
1182                  "\tsystem_trace_period = %d ms\n"
1183                  "\tdata message period = %d ms\n",
1184                  conf->system_trace_period,
1185                  conf->data_message_period
1186                  );
1187 }
1188
1189 void print_replay_event(struct replay_event_t *ev, uint32_t num, char *tab)
1190 {
1191         LOGW("%s\t#%04d:time=0x%08X %08X, "
1192                 " id=0x%08X,"
1193                 " type=0x%08X,"
1194                 " code=0x%08X,"
1195                 " value=0x%08X\n",
1196                 tab,num,
1197                 (unsigned int)ev->ev.time.tv_sec,//timeval
1198                 (unsigned int)ev->ev.time.tv_usec,//timeval
1199                 ev->id,
1200                 ev->ev.type,//u16
1201                 ev->ev.code,//u16
1202                 ev->ev.value//s32
1203                 );
1204 }
1205
1206 void print_replay_event_seq(struct replay_event_seq_t *event_seq)
1207 {
1208         uint32_t i = 0;
1209         char *tab = "\t";
1210
1211         LOGI( "%senabled=0x%08X; "\
1212                 "time_start=0x%08X %08X; "\
1213                 "count=0x%08X\n",
1214                 tab,event_seq->enabled,
1215                 (unsigned int)event_seq->tv.tv_sec,
1216                 (unsigned int)event_seq->tv.tv_usec,
1217                 event_seq->event_num);
1218         for (i=0;i<event_seq->event_num;i++)
1219                 print_replay_event(&event_seq->events[i], i+1, tab);
1220
1221 }