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