[FIX] kill app before start profiling
[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_int32(p, ret_id);
635         pack_int32(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_int32(p, ret_id);
681         pack_int64(p, target_info->sys_mem_size);
682         pack_int64(p, target_info->storage_size);
683         pack_int32(p, target_info->bluetooth_supp);
684         pack_int32(p, target_info->gps_supp);
685         pack_int32(p, target_info->wifi_supp);
686         pack_int32(p, target_info->camera_count);
687         pack_str(p, target_info->network_type);
688         pack_int32(p, target_info->max_brightness);
689         pack_int32(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                 pack_int32(p, err);
768                 //copy payload data
769                 memcpy(p, payload, payload_size);
770
771                 LOGI("ACK (%s) errcode<%s> payload=0x%08X; size=%d\n", msg_ID_str(resp),
772                                 msgErrStr(err_code), (int)payload, payload_size);
773                 printBuf((char *)msg, loglen);
774
775                 if (send(manager.host.control_socket, msg,
776                          loglen, MSG_NOSIGNAL) == -1) {
777                         LOGE("Cannot send reply: %s\n", strerror(errno));
778                         free(msg);
779                         return 1;
780                 }
781                 free(msg);
782                 return 0;
783         } else
784                 return 1;
785 }
786
787 struct msg_t *gen_stop_msg(void)
788 {
789         struct msg_t *res = malloc(sizeof(*res));
790         memset(res, 0, sizeof(*res));
791         res->id = NMSG_STOP;
792         res->len = 0;
793         return res;
794 }
795
796
797 enum ErrorCode stop_all_no_lock(void)
798 {
799         enum ErrorCode error_code = ERR_NO;
800         struct msg_t *msg;
801
802         // stop all only if it has not been called yet
803         if (check_running_status(&prof_session)) {
804                 msg = gen_stop_msg();
805                 terminate_all();
806                 stop_profiling();
807
808                 if (msg == NULL) {
809                         LOGE("cannot generate stop message\n");
810                         error_code = ERR_UNKNOWN;
811                         goto stop_all_exit;
812                 } else {
813                         if (ioctl_send_msg(msg) != 0) {
814                                 LOGE("ioctl send failed\n");
815                                 error_code = ERR_UNKNOWN;
816                                 free_msg(msg);
817                                 goto stop_all_exit;
818                         }
819                         free_msg(msg);
820                 }
821
822                 // we reset only app inst no lib no confing reset
823                 reset_app_inst(&prof_session.user_space_inst);
824                 stop_transfer();
825                 running_status_off(&prof_session);
826         } else
827                 LOGI("already stopped\n");
828
829 stop_all_exit:
830         LOGI("finished: ret = %d\n", error_code);
831         return error_code;
832 }
833
834 int stop_all_in_process(void)
835 {
836         return (pthread_mutex_trylock(&stop_all_mutex) != 0);
837 }
838
839 void stop_all_done(void)
840 {
841         pthread_mutex_unlock(&stop_all_mutex);
842 }
843
844 enum ErrorCode stop_all(void)
845 {
846         enum ErrorCode error_code = ERR_NO;
847
848         pthread_mutex_lock(&stop_all_mutex);
849         error_code = stop_all_no_lock();
850         pthread_mutex_unlock(&stop_all_mutex);
851
852         return error_code;
853 }
854
855 struct binary_ack {
856         uint32_t type;
857         char *binpath;
858         md5_byte_t digest[16];
859 };
860
861 static void binary_ack_free(struct binary_ack *ba)
862 {
863         if (ba)
864                 free(ba->binpath);
865         free(ba);
866 }
867
868 static size_t binary_ack_size(const struct binary_ack *ba)
869 {
870         /* MD5 is 16 bytes, so 16*2 hex digits */
871         return sizeof(uint32_t) + strlen(ba->binpath) + 1
872                 + 2*16 + 1;
873 }
874
875 static size_t binary_ack_pack(char *s, const struct binary_ack *ba)
876 {
877         unsigned int len = strlen(ba->binpath);
878         int i;
879         *(uint32_t *) s = ba->type;
880         s += sizeof(uint32_t);
881
882         if (len)
883                 memmove(s, ba->binpath, len);
884
885         *(s += len) = '\0';
886         s += 1;
887
888         for (i = 0; i!= 16; ++i) {
889                 sprintf(s, "%02x", ba->digest[i]);
890                 s += 2;
891         }
892         *s = '\0';
893         return sizeof(uint32_t) + len + 1 + 2*16 + 1;
894 }
895
896 static void get_file_md5sum(md5_byte_t digest[16], const char *filename)
897 {
898         char buffer[1024];
899         ssize_t size;
900         md5_state_t md5_state;
901         int fd = open(filename, O_RDONLY);
902
903         md5_init(&md5_state);
904         if (fd > 0)
905                 while ((size = read(fd, buffer, sizeof(buffer))) > 0)
906                         md5_append(&md5_state, buffer, size);
907
908         md5_finish(&md5_state, digest);
909         close(fd);
910 }
911
912 static const char* basename(const char *filename)
913 {
914         const char *p = strrchr(filename, '/');
915         return p ? p + 1 : NULL;
916 }
917 static struct binary_ack* binary_ack_alloc(const char *filename)
918 {
919         struct binary_ack *ba = malloc(sizeof(*ba));
920         char builddir[PATH_MAX];
921         char binpath[PATH_MAX];
922
923         ba->type = get_binary_type(filename);
924
925         get_build_dir(builddir, filename);
926
927         snprintf(binpath, sizeof(binpath), "%s/%s",
928                  builddir, basename(filename) ?: "");
929
930         ba->binpath = strdup(binpath);
931
932         get_file_md5sum(ba->digest, filename);
933
934         return ba;
935 }
936
937 static int process_msg_binary_info(struct msg_buf_t *msg)
938 {
939         uint32_t i, bincount;
940
941         if (!parse_int32(msg, &bincount)) {
942                 LOGE("MSG_BINARY_INFO error: No binaries count\n");
943                 return -1;
944         }
945
946         struct binary_ack *acks[bincount];
947         size_t total_size = 0;
948         for (i = 0; i != bincount; ++i) {
949                 const char *str = parse_string_inplace(msg);
950                 if (!str) {
951                         LOGE("MSG_BINARY_INFO error: No enough binaries\n");
952                         return -1;
953                 }
954                 acks[i] = binary_ack_alloc(str);
955                 total_size += binary_ack_size(acks[i]);
956         }
957         typedef uint32_t return_id;
958         typedef uint32_t binary_ack_count;
959         struct msg_t *msg_reply = malloc(sizeof(struct msg_t)
960                                          + sizeof(return_id)
961                                          + sizeof(binary_ack_count)
962                                          + total_size);
963         char *p = msg_reply->payload;
964
965         msg_reply->id = NMSG_BINARY_INFO_ACK;
966         msg_reply->len = total_size + sizeof(return_id)
967                                     + sizeof(binary_ack_count);
968
969         pack_int32(p, ERR_NO);
970         pack_int32(p, bincount);
971
972         for (i = 0; i != bincount; ++i) {
973                 p += binary_ack_pack(p, acks[i]);
974                 binary_ack_free(acks[i]);
975         }
976
977         int err = send_reply(msg_reply);
978         free(msg_reply);
979         return err;
980 }
981
982 static void get_serialized_time(uint32_t dst[2])
983 {
984         struct timeval tv;
985         gettimeofday(&tv, NULL);
986         dst[0] = tv.tv_sec;
987         dst[1] = tv.tv_usec * 1000;
988 }
989
990 static int process_msg_start(struct msg_buf_t *msg_control)
991 {
992         enum ErrorCode err_code = ERR_CANNOT_START_PROFILING;
993         struct msg_t *msg_reply;
994         uint32_t serialized_time[2];
995
996         if (check_running_status(&prof_session.conf) == 1) {
997                 LOGW("Profiling has already been started\n");
998                 goto send_ack;
999         }
1000
1001         if (!check_conf(&prof_session.conf)) {
1002                 LOGE("wrong profile config\n");
1003                 goto send_ack;
1004         }
1005
1006         if (msg_start(msg_control, &prof_session.user_space_inst,
1007                       &msg_reply, &err_code) != 0) {
1008                 LOGE("parse error\n");
1009                 goto send_ack;
1010         }
1011
1012         if (start_transfer() != 0) {
1013                 LOGE("Cannot start transfer\n");
1014                 goto send_ack;
1015         }
1016
1017         if (prepare_profiling() != 0) {
1018                 LOGE("failed to prepare profiling\n");
1019                 goto send_ack;
1020         }
1021
1022         if (ioctl_send_msg(msg_reply) != 0) {
1023                 LOGE("cannot send message to device\n");
1024                 goto send_ack;
1025         }
1026
1027         running_status_on(&prof_session);
1028
1029         if (start_profiling() < 0) {
1030                 LOGE("cannot start profiling\n");
1031                 if (stop_all() != ERR_NO) {
1032                         LOGE("Stop failed\n");
1033                         write_msg_error("Stop failed");
1034                 }
1035                 goto send_ack;
1036         }
1037
1038         err_code = ERR_NO;
1039 send_ack:
1040         get_serialized_time(&serialized_time);
1041         sendACKToHost(NMSG_START, err_code, (void *)&serialized_time,
1042                       sizeof(serialized_time));
1043
1044         return -(err_code != ERR_NO);
1045 }
1046
1047 int host_message_handler(struct msg_t *msg)
1048 {
1049         struct app_info_t app_info;
1050         struct target_info_t target_info;
1051         struct msg_t *msg_reply = NULL;
1052         struct msg_buf_t msg_control;
1053         struct conf_t conf;
1054         enum ErrorCode error_code = ERR_NO;
1055
1056         int target_index;
1057         ssize_t sendlen;
1058         msg_target_t sendlog;
1059
1060         LOGI("MY HANDLE %s (%X)\n", msg_ID_str(msg->id), msg->id);
1061         init_parse_control(&msg_control, msg);
1062
1063         switch (msg->id) {
1064         case NMSG_KEEP_ALIVE:
1065                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1066                 break;
1067         case NMSG_START:
1068                 return process_msg_start(&msg_control);
1069         case NMSG_STOP:
1070                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1071                 if (stop_all() != ERR_NO) {
1072                         LOGE("Stop failed\n");
1073                         write_msg_error("Stop failed");
1074                 }
1075                 break;
1076         case NMSG_CONFIG:
1077                 error_code = ERR_NO;
1078                 if (!parse_msg_config(&msg_control, &conf)) {
1079                         LOGE("config parsing error\n");
1080                         sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
1081                         return -1;
1082                 }
1083                 if (reconfigure(conf) != 0) {
1084                         LOGE("Cannot change configuration\n");
1085                         return -1;
1086                 }
1087                 //write to device
1088                 if (ioctl_send_msg(msg) != 0) {
1089                         LOGE("ioctl send error\n");
1090                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1091                         return -1;
1092                 }
1093                 //send ack to host
1094                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1095                 // send config message to target process
1096                 sendlog.type = MSG_OPTION;
1097                 sendlog.length = sprintf(sendlog.data, "%lu",
1098                                      (unsigned long int) prof_session.conf.use_features0);
1099                 for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++)
1100                 {
1101                         if(manager.target[target_index].socket != -1)
1102                         {
1103                                 if (0 > send(manager.target[target_index].socket, &sendlog,
1104                                         sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length,
1105                                              MSG_NOSIGNAL))
1106                                         LOGE("fail to send data to target index(%d)\n", target_index);
1107                         }
1108                 }
1109                 break;
1110         case NMSG_BINARY_INFO:
1111                 return process_msg_binary_info(&msg_control);
1112         case NMSG_SWAP_INST_ADD:
1113                 if (msg_swap_inst_add(&msg_control, &prof_session.user_space_inst,
1114                                       &msg_reply, &error_code) != 0) {
1115                         LOGE("swap inst add\n");
1116                         goto send_ack;
1117                 }
1118                 if (msg_reply != NULL)
1119                         if (ioctl_send_msg(msg_reply) != 0) {
1120                                 error_code = ERR_UNKNOWN;
1121                                 LOGE("ioclt send error\n");
1122                         }
1123                 //send ack to host
1124                 goto send_ack;
1125         case NMSG_SWAP_INST_REMOVE:
1126                 if (msg_swap_inst_remove(&msg_control, &prof_session.user_space_inst,
1127                                          &msg_reply, &error_code) != 0) {
1128                         LOGE("swap inst remove\n");
1129                         error_code = ERR_UNKNOWN;
1130                         goto send_ack;
1131                 }
1132                 if (msg_reply != NULL) {
1133                         if (ioctl_send_msg(msg_reply) != 0)
1134                                 error_code = ERR_UNKNOWN;
1135                 } else {
1136                         error_code = ERR_UNKNOWN;
1137                 }
1138                 goto send_ack;
1139         case NMSG_GET_TARGET_INFO:
1140                 fill_target_info(&target_info);
1141                 msg_reply = gen_target_info_reply(&target_info);
1142                 if (!msg_reply) {
1143                         LOGE("cannot generate reply message\n");
1144                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1145                         return -1;
1146                 }
1147                 if (send_reply(msg_reply) != 0) {
1148                         LOGE("Cannot send reply\n");
1149                 }
1150                 free(msg_reply);
1151                 reset_target_info(&target_info);
1152                 break;
1153
1154         default:
1155                 LOGE("unknown message %d <0x%08X>\n", msg->id, msg->id);
1156         }
1157
1158         return 0;
1159
1160 send_ack:
1161         sendACKToHost(msg->id, error_code, 0, 0);
1162         if (msg_reply != NULL)
1163                 free(msg_reply);
1164         return (error_code == ERR_NO);
1165 }
1166
1167 // testing
1168
1169 static void print_app_info(struct app_info_t *app_info)
1170 {
1171         LOGI("application info=\n");
1172         LOGI("\tapp_type=<%d><0x%04X>\n"
1173                  "\tapp_id=<%s>\n"
1174                  "\texe_path=<%s>\n",
1175                  app_info->app_type,
1176                  app_info->app_type,
1177                  app_info->app_id,
1178                  app_info->exe_path
1179         );
1180 }
1181
1182 static void print_conf(struct conf_t *conf)
1183 {
1184         char buf[1024];
1185         memset(&buf[0], 0, 1024);
1186         feature_code_str(conf->use_features0, buf);
1187         LOGI("conf = \n");
1188         LOGI("\tuse_features0 = 0x%016LX (%s)\n", conf->use_features0, buf);
1189         LOGI("\tuse_features1 = 0x%016LX (%s)\n", conf->use_features1, buf);
1190         LOGI(
1191                  "\tsystem_trace_period = %d ms\n"
1192                  "\tdata message period = %d ms\n",
1193                  conf->system_trace_period,
1194                  conf->data_message_period
1195                  );
1196 }
1197
1198 void print_replay_event(struct replay_event_t *ev, uint32_t num, char *tab)
1199 {
1200         LOGW("%s\t#%04d:time=0x%08X %08X, "
1201                 " id=0x%08X,"
1202                 " type=0x%08X,"
1203                 " code=0x%08X,"
1204                 " value=0x%08X\n",
1205                 tab,num,
1206                 (unsigned int)ev->ev.time.tv_sec,//timeval
1207                 (unsigned int)ev->ev.time.tv_usec,//timeval
1208                 ev->id,
1209                 ev->ev.type,//u16
1210                 ev->ev.code,//u16
1211                 ev->ev.value//s32
1212                 );
1213 }
1214
1215 void print_replay_event_seq(struct replay_event_seq_t *event_seq)
1216 {
1217         uint32_t i = 0;
1218         char *tab = "\t";
1219
1220         LOGI( "%senabled=0x%08X; "\
1221                 "time_start=0x%08X %08X; "\
1222                 "count=0x%08X\n",
1223                 tab,event_seq->enabled,
1224                 (unsigned int)event_seq->tv.tv_sec,
1225                 (unsigned int)event_seq->tv.tv_usec,
1226                 event_seq->event_num);
1227         for (i=0;i<event_seq->event_num;i++)
1228                 print_replay_event(&event_seq->events[i], i+1, tab);
1229
1230 }