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