Merge branch 'swap_protocol' of ssh://106.109.8.71/srv/git/sdk/dynamic-analysis-manag...
[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 "daemon.h"
42 #include "sys_stat.h"
43 #include "transfer_thread.h"
44 #include "elf.h"
45 #include "ioctl_commands.h"
46 #include "debug.h"
47
48 #include <sys/stat.h>
49 #include <fcntl.h>
50 #include <unistd.h>
51
52
53
54 void inline free_msg(struct msg_t *msg)
55 {
56         free(msg);
57 }
58 static uint32_t msg_size_with_out_replays = 0;
59
60 struct prof_session_t prof_session;
61
62 static void print_app_info( struct app_info_t *app_info);
63 static void print_conf(struct conf_t * conf);
64 //DEBUG FUNCTIONS
65 #define dstr(x) #x
66
67 #define check_and_return(par,check) if ( par == check ) {return dstr(check);}
68 #define check_2(a1,a2) check_and_return(ID,a1) else check_and_return(ID,a2)
69 #define check_4(a1,a2,a3,a4) check_2(a1,a2) else check_2(a3,a4)
70 #define check_8(a1,a2,a3,a4,a5,a6,a7,a8) check_4(a1,a2,a3,a4) else check_4(a5,a6,a7,a8)
71
72 #define check_all(a1, ...) check_and_return(ID,a1) //#else check_all(__VA_ARGS__)
73 char* msg_ID_str ( enum HostMessageT ID)
74 {
75         check_8(
76                 NMSG_KEEP_ALIVE,
77                 NMSG_START,
78                 NMSG_STOP,
79                 NMSG_CONFIG,
80                 0,
81                 NMSG_BINARY_INFO,
82                 NMSG_GET_TARGET_INFO,
83                 NMSG_SWAP_INST_ADD
84                 )
85         else
86         check_8(
87                 NMSG_SWAP_INST_REMOVE,
88                 NMSG_KEEP_ALIVE_ACK,
89                 NMSG_START_ACK,
90                 NMSG_STOP_ACK,
91
92                 NMSG_CONFIG_ACK,
93                 NMSG_BINARY_INFO_ACK,
94                 NMSG_SWAP_INST_ACK,
95                 NMSG_GET_TARGET_INFO_ACK
96                 )
97         else
98         check_8(
99                 NMSG_SWAP_INST_ADD_ACK,
100                 NMSG_SWAP_INST_REMOVE_ACK,
101                 NMSG_PROCESS_INFO,
102                 NMSG_TERMINATE,
103
104                 NMSG_ERROR,
105                 NMSG_SAMPLE,
106                 NMSG_SYSTEM,
107                 NMSG_IMAGE
108                 )
109         else
110         check_8(
111                 NMSG_RECORD,
112                 NMSG_FUNCTION_ENTRY,
113                 NMSG_FUNCTION_EXIT,
114                 NMSG_CONTEXT_SWITCH_ENTRY,
115
116                 NMSG_CONTEXT_SWITCH_EXIT,
117                 NMSG_PROBE,
118                 NMSG_PROBE_MEMORY,
119                 NMSG_PROBE_UICONTROL
120                 )
121         else
122         check_8(
123                 NMSG_PROBE_UIEVENT,
124                 NMSG_PROBE_RESOURCE,
125                 NMSG_PROBE_LIFECYCLE,
126                 NMSG_PROBE_SCREENSHOT,
127
128                 NMSG_PROBE_SCENE,
129                 NMSG_PROBE_THREAD,
130                 NMSG_PROBE_CUSTOM,
131                 NMSG_PROBE_SYNC
132         ) else
133         return "HZ";
134 }
135
136
137 static char *msgErrStr(enum ErrorCode err)
138 {
139         switch (err) {
140         case ERR_NO:
141                 return "success";
142         case ERR_LOCKFILE_CREATE_FAILED:
143                 return "lock file create failed";
144         case ERR_ALREADY_RUNNING:
145                 return "already running";
146         case ERR_INITIALIZE_SYSTEM_INFO_FAILED:
147                 return "initialize system info failed";
148         case ERR_HOST_SERVER_SOCKET_CREATE_FAILED:
149                 return "host server socket create failed";
150         case ERR_TARGET_SERVER_SOCKET_CREATE_FAILED:
151                 return "target server socket create failed";
152         case ERR_SIGNAL_MASK_SETTING_FAILED: //TODO del (old parametr)
153                 return "ERR SIGNAL MASK SETTING FAILED";
154         case ERR_WRONG_MESSAGE_FORMAT:
155                 return "wrong message format";
156         case ERR_WRONG_MESSAGE_TYPE:
157                 return "wrong message type";
158         case ERR_WRONG_MESSAGE_DATA:
159                 return "wrong message data";
160         case ERR_CANNOT_START_PROFILING:
161                 return "cannot start profiling";
162         case ERR_SERV_SOCK_CREATE:
163                 return "server socket creation failed (written in /tmp/da.port file)";
164         case ERR_SERV_SOCK_BIND:
165                 return "server socket bind failed (written in /tmp/da.port file)";
166         case ERR_SERV_SOCK_LISTEN:
167                 return "server socket listen failed (written in /tmp/da.port file)";
168         case ERR_UNKNOWN:
169         default:
170                 return "unknown error";
171         }
172         return "unknown error";
173 }
174
175
176 #define print_feature(f,in,to,delim) if (f & in)\
177                                                                 {\
178                                                                         sprintf(to, dstr(f) delim );\
179                                                                         to+=strlen( dstr(f) delim );\
180                                                                 }
181 #define print_feature_a(f) print_feature(f,feature,to,", ")
182 void feature_code_str(uint32_t feature, char * to)
183 {
184         print_feature_a(FL_CPU);
185         print_feature_a(FL_MEMORY);
186         print_feature_a(FL_FUNCTION_PROFILING);
187         print_feature_a(FL_MEMORY_ALLCATION_PROBING);
188         print_feature_a(FL_FILE_API_PROBING);
189         print_feature_a(FL_THREAD_API_PROBING);
190         print_feature_a(FL_OSP_UI_API_PROBING);
191         print_feature_a(FL_SCREENSHOT);
192         print_feature_a(FL_USER_EVENT);
193         print_feature_a(FL_RECORDING);
194         print_feature_a(FL_SYSTCALL_FILE);
195         print_feature_a(FL_SYSTCALL_IPC);
196         print_feature_a(FL_SYSTCALL_PROCESS);
197         print_feature_a(FL_SYSTCALL_SIGNAL);
198         print_feature_a(FL_SYSTCALL_NETWORK);
199         print_feature_a(FL_SYSTCALL_DESC);
200         print_feature_a(FL_CONTEXT_SWITCH);
201         print_feature_a(FL_NETWORK_API_PROBING);
202         print_feature_a(FL_OPENGL_API_PROBING);
203
204 }
205
206
207 //PARSE FUNCTIONS
208 inline uint32_t get_avail_msg_size(struct msg_buf_t *msg)
209 {
210         return (uint32_t)(msg->end - msg->cur_pos);
211 }
212
213 inline uint32_t get_msg_cur_size(struct msg_buf_t *msg)
214 {
215         return (uint32_t) (msg->cur_pos - msg->payload);
216 }
217
218 static int parse_string(struct msg_buf_t *msg, char **str)
219 {
220         parse_deb("size = %d\n", get_avail_msg_size(msg));
221         int len = strlen(msg->cur_pos) + 1;
222
223         if (get_avail_msg_size(msg) < len)
224                 return 0;
225
226         *str = strdup(msg->cur_pos);
227         parse_deb("<%s>\n",*str);
228         msg->cur_pos += len;
229         return 1;
230 }
231
232 static int parse_int32(struct msg_buf_t *msg, uint32_t *val)
233 {
234         parse_deb("size = %d\n", get_avail_msg_size(msg));
235         if (get_avail_msg_size(msg) < sizeof(*val))
236                 return 0;
237         *val = *(uint32_t *)msg->cur_pos;
238         msg->cur_pos += sizeof(uint32_t);
239
240
241         parse_deb("<%d><0x%08X>\n",*val,*val);
242         return 1;
243 }
244
245 static int parse_int64(struct msg_buf_t *msg, uint64_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
251         *val = *(uint64_t *)msg->cur_pos;
252
253         parse_deb("<%llu><0x%016llX>\n",*val,*val);
254         msg->cur_pos += sizeof(uint64_t);
255         return 1;
256 }
257
258 static int parse_app_info(struct msg_buf_t *msg,
259                                struct app_info_t *app_info)
260 {
261
262         parse_deb("parse_app_info\n");
263         if (!parse_int32(msg, &app_info->app_type)){
264                 LOGE("app type parsing error\n");
265                 return 0;
266         }
267
268         if (!parse_string(msg, &app_info->app_id)){
269                 LOGE("app id parsing error\n");
270                 return 0;
271         }
272
273         if (!parse_string(msg, &app_info->exe_path)) {
274                 LOGE("app info parsing error\n");
275                 return 0;
276         }
277
278 //      print_app_info(app_info);
279
280         return 1;
281 }
282
283 static int parse_conf(struct msg_buf_t *msg, struct conf_t *conf)
284 {
285
286         parse_deb("parse_conf\n");
287         if (!parse_int64(msg, &conf->use_features0)) {
288                 LOGE("use features0 parsing error\n");
289                 return 0;
290         }
291
292         if (!parse_int64(msg, &conf->use_features1)) {
293                 LOGE("use features1 parsing error\n");
294                 return 0;
295         }
296
297         if (!parse_int32( msg, &conf->system_trace_period)) {
298                 LOGE("system trace period parsing error\n");
299                 return 0;
300         }
301
302         if (!parse_int32( msg, &conf->data_message_period)) {
303                 LOGE("data message period parsing error\n");
304                 return 0;
305         }
306         //print_conf(conf);
307         return 1;
308 }
309
310 static int parse_us_inst_func(struct msg_buf_t *msg , struct us_func_inst_t * dest)
311 {
312
313         if (!parse_int64(msg, &(dest->func_addr))) {
314                 LOGE("func addr parsing error\n");
315                 return 0;
316         }
317
318         if (!parse_string(msg, &dest->args)) {
319                 LOGE("args format parsing error\n");
320                 return 0;
321         }
322         return 1;
323
324 }
325
326 static int parse_func_inst_list(struct msg_buf_t *msg,
327                             uint32_t *num,
328                             struct us_func_inst_t ** us_func_inst_list)
329 {
330         uint32_t i = 0;
331         if (!parse_int32( msg, num)) {
332                 LOGE("func num parsing error\n");
333                 return 0;
334         }
335         //parse user space function list
336
337         parse_deb("us_func_inst_list size = %d * %d\n",(*num) , (int)sizeof(**us_func_inst_list) );
338         *us_func_inst_list =
339                 (struct us_func_inst_t *)
340                 malloc( (*num) * sizeof(**us_func_inst_list) );
341         if (!*us_func_inst_list){
342                 LOGE("func alloc error\n");
343                 return 0;
344         };
345
346         for ( i = 0; i < *num; i++){
347                 if (!parse_us_inst_func( msg, &((* us_func_inst_list)[i]))){
348                         LOGE("parse us inst func #%d failed\n", i + 1);
349                         return 0;
350                 }
351         }
352
353         return 1;
354 }
355
356 static int parse_us_inst_lib(struct msg_buf_t *msg, struct us_lib_inst_t * dest)
357 {
358
359         if (!parse_string(msg, &(dest)->bin_path)) {
360                 LOGE("bin path parsing error\n");
361                 return 0;
362         }
363
364         if (!parse_func_inst_list(msg, &dest->func_num, &dest->us_func_inst_list)) {
365                 LOGE("funcs parsing error\n");
366                 return 0;
367         }
368         return 1;
369
370 }
371
372 static int parse_lib_inst_list(struct msg_buf_t *msg,
373                             uint32_t *num,
374                             struct us_lib_inst_t ** us_lib_inst_list)
375 {
376         uint32_t i = 0;
377         if (!parse_int32( msg, num)) {
378                 LOGE("lib num parsing error\n");
379                 return 0;
380         }
381
382         parse_deb("lib_list size = %d\n", (*num) * (int)sizeof(**us_lib_inst_list) );
383         *us_lib_inst_list =
384                 (struct us_lib_inst_t *)
385                 malloc( (*num) * sizeof(**us_lib_inst_list) );
386         if (!*us_lib_inst_list){
387                 LOGE("lib alloc error\n");
388                 return 0;
389         };
390         for ( i = 0; i < *num; i++){
391                 if (!parse_us_inst_lib( msg, &( (*us_lib_inst_list)[i] ) )){
392                         LOGE("parse is inst lib #%d failed\n", i + 1);
393                         return 0;
394                 }
395         }
396         return 1;
397 }
398
399 static int parse_app_inst(struct msg_buf_t *msg,
400                             struct app_inst_t *app_inst)
401 {
402         if (!parse_int32( msg, &app_inst->app_type)) {
403                 LOGE("app type parsing error\n");
404                 return 0;
405         }
406         if (!parse_string( msg, &app_inst->app_id)) {
407                 LOGE("app id parsing error\n");
408                 return 0;
409         }
410         if (!parse_string( msg, &app_inst->exec_path)) {
411                 LOGE("exec path parsing error\n");
412                 return 0;
413         }
414         if (!parse_func_inst_list( msg, &app_inst->func_num , &(app_inst->us_func_inst_list))) {
415                 LOGE("funcs parsing error\n");
416                 return 0;
417         }
418
419         parse_deb(">=%04X : %s, %s, %d\n",
420              app_inst->app_type, app_inst->app_id, app_inst->exec_path , num);
421
422         if (!parse_lib_inst_list( msg, &app_inst->lib_num , &app_inst->us_lib_inst_list)) {
423                 LOGE("libs parsing error\n");
424                 return 0;
425         }
426
427         return 1;
428 }
429
430 int parse_user_space_inst(struct msg_buf_t *msg,
431                             struct user_space_inst_t *user_space_inst)
432 {
433         parse_deb("parse_user_space_inst\n");
434         uint32_t num = 0 , i = 0;
435         struct app_inst_t * list = 0;
436
437         if (!parse_int32 ( msg, &num )) {
438                 LOGE("app num parsing error\n");
439                 return 0;
440         }
441
442         parse_deb("%d * %d\n",(int) sizeof(*(user_space_inst->app_inst_list)), num);
443         if ( num != 0 ) {
444                 list = (struct app_inst_t *) malloc (
445                         sizeof(*(user_space_inst->app_inst_list)) * num);
446                 if ( !list ) {
447                         LOGE("apps alloc error\n");
448                         return 0;
449                 };
450
451                 for ( i = 0; i < num; i++){
452                         if (!parse_app_inst( msg, &(list[i]) )){
453                                 LOGE("parse app inst #%d failed\n", i + 1);
454                                 return 0;
455                         }
456                 };
457
458                 user_space_inst->app_num = num;
459                 user_space_inst->app_inst_list = list;
460         }
461         return 1;
462 }
463
464 //REPLAY EVENTS PARSE
465 static int parse_timeval(struct msg_buf_t *msg, struct timeval *tv)
466 {
467         uint32_t nsec = 0;
468
469         parse_deb("time\n");
470
471         // FIXME: is sec/usec order correct?
472         if (!parse_int32(msg, &nsec)) {
473                 LOGE("usec parsing error\n");
474                 return 0;
475         }
476         tv->tv_usec = nsec / 1000;
477
478         if (!parse_int32(msg, (uint32_t *)&tv->tv_sec)) {
479                 LOGE("sec parsing error\n");
480                 return 0;
481         }
482
483         return 1;
484 }
485
486 static int parse_replay_event(struct msg_buf_t *msg,
487                                     struct replay_event_t *re)
488 {
489
490         if (!parse_timeval(msg, &re->ev.time)) {
491                 LOGE("time parsing error\n");
492                 return 0;
493         }
494
495         if (!parse_int32(msg, &re->id)) {
496                 LOGE("id parsing error\n");
497                 return 0;
498         }
499
500         if (!parse_int32(msg, (uint32_t *)&re->ev.type)) {
501                 LOGE("type parsing error\n");
502                 return 0;
503         }
504
505         if (!parse_int32(msg, (uint32_t *)&re->ev.code)) {
506                 LOGE("code parsing error\n");
507                 return 0;
508         }
509
510         if (!parse_int32(msg, (uint32_t *)&re->ev.value)) {
511                 LOGE("value parsing error\n");
512                 return 0;
513         }
514
515         return 1;
516 }
517
518 void reset_replay_event_seq(struct replay_event_seq_t *res)
519 {
520         res->enabled = 0;
521         res->tv = (struct timeval){0, 0};
522         res->event_num = 0;
523         free(res->events);
524 }
525
526 static int parse_replay_event_seq(struct msg_buf_t *msg,
527                                     struct replay_event_seq_t *res)
528 {
529         LOGI("parse_replay_event_seq\n");
530
531         int i = 0;
532         parse_deb("REPLAY\n");
533         if (!parse_int32(msg, &res->enabled)) {
534                 LOGE("enabled parsing error\n");
535                 return 0;
536         }
537
538         if(res->enabled == 0){
539                 parse_deb("disable\n");
540                 return 1;
541         }
542
543         parse_deb("time main\n");
544         if (!parse_timeval(msg, &res->tv)) {
545                 LOGE("time parsing error\n");
546                 return 0;
547         }
548
549         parse_deb("count\n");
550         if (!parse_int32(msg, &res->event_num)) {
551                 LOGE("event num parsing error\n");
552                 return 0;
553         }
554         parse_deb("events num=%d\n", res->event_num);
555
556         res->events = (struct replay_event_t *)malloc(res->event_num *
557                                                       sizeof(*res->events));
558         if (!res->events) {
559                 LOGE("events alloc error\n");
560                 return 0;
561         }
562
563         for (i = 0; i < res->event_num; i++) {
564                 parse_deb("sub_rep\n");
565                 if (!parse_replay_event(msg, &res->events[i])) {
566                         LOGE("event #%d parsing error\n", i + 1);
567                         free(res->events);
568                         res->event_num = 0;
569                         return 0;
570                 }
571         }
572
573         return 1;
574 }
575
576 //*REPLAY EVENT PARSE
577
578 static int parse_prof_session(struct msg_buf_t *msg,
579                               struct prof_session_t *prof_session)
580 {
581         LOGI("parse_prof_session\n");
582         if (!parse_app_info(msg, &prof_session->app_info)) {
583                 LOGE("app info parsing error\n");
584                 return 1;
585         }
586         if (!parse_conf(msg, &prof_session->conf)) {
587                 LOGE("conf parsing error\n");
588                 return 1;
589         }
590
591         if (!parse_user_space_inst(msg, &prof_session->user_space_inst)) {
592                 LOGE("user space inst parsing error\n");
593                 return 1;
594         }
595
596         msg_size_with_out_replays = get_msg_cur_size(msg);
597         if (!parse_replay_event_seq(msg, &prof_session->replay_event_seq)) {
598                 LOGE("replay parsing error\n");
599                 return 1;
600         }
601
602         //print_prof_session(prof_session);
603         return 0;
604 }
605
606 int get_sys_mem_size(uint32_t *sys_mem_size){
607         struct sysinfo info;
608         sysinfo(&info);
609         *sys_mem_size = info.totalram;
610         return 0;
611 }
612
613 static int parse_msg_config(struct msg_buf_t * msg_payload,
614                               struct conf_t * conf)
615 {
616         if (!parse_conf(msg_payload, conf)) {
617                 LOGE("conf parsing error\n");
618                 return 0;
619         }
620
621         print_conf(conf);
622         return 1;
623 }
624
625 static int parse_msg_binary_info(struct msg_buf_t * msg_payload,
626                               struct app_info_t *app_info)
627 {
628         if (!parse_app_info(msg_payload, app_info)) {
629                 LOGE("app info parsing error\n");
630                 return 0;
631         }
632
633         print_app_info(app_info);
634         return 1;
635 }
636
637 static void init_parse_control(struct msg_buf_t *buf, struct msg_t *msg)
638 {
639         LOGI("init parse control\n");
640         buf->payload = msg->payload;
641         buf->len = msg->len;
642         buf->end = msg->payload + msg->len;
643         buf->cur_pos = msg->payload;
644         LOGI("init parse control done\n");
645 }
646
647 //This function concat 2 user space lists
648 // this function clean "from" pointer
649 static void concat_add_user_space_inst(struct user_space_inst_t *from,
650                                                                 struct user_space_inst_t *to)
651 {
652         struct app_inst_t *new_app_inst_list = NULL;
653         uint32_t size;
654         void *p;
655
656         if (from->app_num == 0)
657                 return;
658
659         new_app_inst_list = malloc((from->app_num + to->app_num) * sizeof(*new_app_inst_list));
660         p = new_app_inst_list;
661
662         size = from->app_num * sizeof(*new_app_inst_list);
663         memcpy(p, from->app_inst_list, size);
664         p +=size;
665
666         size = to->app_num * sizeof(*new_app_inst_list);
667         memcpy(p, to->app_inst_list, size);
668         p +=size;
669
670         free(to->app_inst_list);
671         to->app_inst_list = new_app_inst_list;
672
673         to->app_num += from->app_num;
674         return;
675 }
676
677 static void cut_replay_events(struct msg_t *msg){
678
679         LOGI("msg_size_with_out_replays = %d \n",msg_size_with_out_replays);
680         msg->len = msg_size_with_out_replays;
681
682 }
683
684 static void reset_app_info(struct app_info_t *app_info)
685 {
686         if (app_info->app_id != NULL)
687                 free(app_info->app_id);
688         if (app_info->exe_path != NULL)
689                 free(app_info->exe_path);
690         memset(app_info, 0, sizeof(*app_info));
691 }
692
693 static void reset_target_info(struct target_info_t *target_info)
694 {
695         free(target_info->network_type);
696 }
697
698 static void reset_conf(struct conf_t *conf)
699 {
700         memset(conf, 0, sizeof(*conf));
701 }
702
703 static void reset_func_inst_list(uint32_t func_num,
704                                  struct us_func_inst_t *funcs)
705 {
706         int i = 0;
707
708         for (i = 0; i < func_num; i++) {
709                 funcs[i].func_addr = 0;
710                 free(funcs[i].args);
711         }
712 }
713
714 static void reset_lib_inst_list(uint32_t lib_num, struct us_lib_inst_t *libs)
715 {
716         int i = 0;
717
718         for (i = 0; i < lib_num; i++) {
719                 free(libs[i].bin_path);
720                 reset_func_inst_list(libs[i].func_num,
721                                      libs[i].us_func_inst_list);
722         }
723 }
724
725 static void reset_app_inst(struct app_inst_t *app_inst)
726 {
727         app_inst->app_type = 0;
728         free(app_inst->app_id);
729         free(app_inst->exec_path);
730         reset_func_inst_list(app_inst->func_num,
731                              app_inst->us_func_inst_list);
732         app_inst->func_num = 0;
733         free(app_inst->us_func_inst_list);
734         reset_lib_inst_list(app_inst->lib_num, app_inst->us_lib_inst_list);
735         app_inst->lib_num = 0;
736         free(app_inst->us_lib_inst_list);
737 }
738
739 static void reset_user_space_inst(struct user_space_inst_t *us)
740 {
741         int i = 0;
742
743         for (i = 0; i < us->app_num; i++)
744                 reset_app_inst(&us->app_inst_list[i]);
745         if (us->app_inst_list != NULL){
746                 free(us->app_inst_list);
747                 us->app_inst_list = NULL;
748         }
749         us->app_num = 0;
750 }
751
752 void reset_system_info(struct system_info_t *sys_info)
753 {
754         if (sys_info->thread_load)
755                 free(sys_info->thread_load);
756         if (sys_info->process_load)
757                 free(sys_info->process_load);
758         if (sys_info->cpu_frequency)
759                 free(sys_info->cpu_frequency);
760         if (sys_info->cpu_load)
761                 free(sys_info->cpu_load);
762         memset(sys_info, 0, sizeof(*sys_info));
763 }
764
765 static void reset_prof_session(struct prof_session_t *prof_session)
766 {
767         reset_app_info(&prof_session->app_info);
768         reset_conf(&prof_session->conf);
769         reset_user_space_inst(&prof_session->user_space_inst);
770 }
771
772 static struct msg_t *gen_binary_info_reply(struct app_info_t *app_info)
773 {
774         uint32_t binary_type = get_binary_type(app_info->exe_path);
775         char binary_path[PATH_MAX];
776         struct msg_t *msg;
777         char *p = NULL;
778         uint32_t ret_id = ERR_NO;
779
780         get_build_dir(binary_path, app_info->exe_path);
781
782         if (binary_type == BINARY_TYPE_UNKNOWN) {
783                 LOGE("Binary is neither relocatable, nor executable\n");
784                 return NULL;
785         }
786
787         msg = malloc(sizeof(*msg) +
788                               sizeof(ret_id) +
789                               sizeof(binary_type) +
790                               strlen(binary_path) + 1);
791         if (!msg) {
792                 LOGE("Cannot alloc bin info msg\n");
793                 return NULL;
794         }
795
796         msg->id = NMSG_BINARY_INFO_ACK;
797         p = msg->payload;
798
799         pack_int(p, ret_id);
800         pack_int(p, binary_type);
801         pack_str(p, binary_path);
802
803         msg->len = p - msg->payload;
804
805         return msg;
806 }
807
808 static struct msg_t *gen_target_info_reply(struct target_info_t *target_info)
809 {
810         struct msg_t *msg;
811         char *p = NULL;
812         uint32_t ret_id = ERR_NO;
813
814         msg = malloc(sizeof(*msg) +
815                               sizeof(ret_id) +
816                               sizeof(*target_info) -
817                               sizeof(target_info->network_type) +
818                               strlen(target_info->network_type) + 1);
819         if (!msg) {
820                 LOGE("Cannot alloc target info msg\n");
821                 free(msg);
822                 return NULL;
823         }
824
825         msg->id = NMSG_GET_TARGET_INFO_ACK;
826         p = msg->payload;
827
828         pack_int(p, ret_id);
829         pack_int(p, target_info->sys_mem_size);
830         pack_int(p, target_info->storage_size);
831         pack_int(p, target_info->bluetooth_supp);
832         pack_int(p, target_info->gps_supp);
833         pack_int(p, target_info->wifi_supp);
834         pack_int(p, target_info->camera_count);
835         pack_str(p, target_info->network_type);
836         pack_int(p, target_info->max_brightness);
837         pack_int(p, target_info->cpu_core_count);
838
839         msg->len = p - msg->payload;
840
841         return msg;
842 }
843
844 static int send_reply(struct msg_t *msg)
845 {
846         if (send(manager.host.control_socket,
847                  msg, MSG_CMD_HDR_LEN + msg->len, MSG_NOSIGNAL) == -1) {
848                 LOGE("Cannot send reply : %s\n", strerror(errno));
849                 return 1;
850         }
851
852         return 0;
853 }
854
855 static int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
856                         char *payload, int payload_size)
857 {
858         if (manager.host.control_socket != -1)
859         {
860                 struct msg_t *msg;
861                 uint32_t err = err_code;
862                 int loglen = sizeof(*msg) - sizeof(msg->payload) +
863                                          sizeof(err) + //return ID
864                                          payload_size;
865                 msg = malloc(loglen);
866                 char *p = msg->payload;
867
868                 //get ack message ID
869                 switch (resp) {
870                         case NMSG_KEEP_ALIVE:
871                                 resp = NMSG_KEEP_ALIVE_ACK;
872                                 break;
873                         case NMSG_START:
874                                 resp = NMSG_START_ACK;
875                                 break;
876                         case NMSG_STOP:
877                                 resp = NMSG_STOP_ACK;
878                                 break;
879                         case NMSG_CONFIG:
880                                 resp = NMSG_CONFIG_ACK;
881                                 break;
882                         case NMSG_BINARY_INFO:
883                                 resp = NMSG_BINARY_INFO_ACK;
884                                 break;
885                         case NMSG_GET_TARGET_INFO:
886                                 resp = NMSG_GET_TARGET_INFO_ACK;
887                                 break;
888                         case NMSG_SWAP_INST_ADD:
889                                 resp = NMSG_SWAP_INST_ADD_ACK;
890                                 break;
891                         case NMSG_SWAP_INST_REMOVE:
892                                 resp = NMSG_SWAP_INST_REMOVE_ACK;
893                                 break;
894                         default:
895                                 //TODO report error
896                                 free(msg);
897                                 return 1;
898                 }
899
900                 //set message id
901                 msg->id = resp;
902                 //set payload lenth
903                 msg->len = payload_size + sizeof(err);
904                 //set return id
905                 //*(uint32_t *)p = err; p+=sizeof(err);
906                 pack_int(p, err)
907                 //copy payload data
908                 memcpy(p, payload, payload_size);
909
910                 LOGI("ACK (%s) errcode<%s> payload=%d; size=%d\n", msg_ID_str(resp),
911                                 msgErrStr(err_code), (int)payload, payload_size);
912                 printBuf((char *)msg, loglen);
913
914                 if (send(manager.host.control_socket, msg,
915                          loglen, MSG_NOSIGNAL) == -1) {
916                         LOGE("Cannot send reply: %s\n", strerror(errno));
917                         free(msg);
918                         return 1;
919                 }
920                 free(msg);
921                 return 0;
922         }
923         else
924                 return 1;
925 }
926
927 struct msg_t *gen_stop_msg(void){
928         struct msg_t *res = malloc(sizeof(*res));
929         memset(res, 0, sizeof(*res));
930         res->id = NMSG_STOP;
931         res->len = 0;
932         return res;
933 }
934
935 enum ErrorCode stop_all(void)
936 {
937         LOGI("entry\n");
938         enum ErrorCode error_code = ERR_NO;
939         struct msg_t *msg = gen_stop_msg();
940
941         terminate_all();
942         stop_profiling();
943
944         if (msg == NULL){
945                 LOGE("cannot generate stop message\n");
946                 return ERR_UNKNOWN;
947         } else {
948                 if (ioctl_send_msg(msg) != 0){
949                         LOGE("ioctl send filed\n");
950                         error_code = ERR_UNKNOWN;
951                 }
952                 free_msg(msg);
953         }
954
955         reset_prof_session(&prof_session);
956         stop_transfer();
957
958         LOGI("finished\n");
959         return error_code;
960 }
961
962 int host_message_handler(struct msg_t *msg)
963 {
964         struct app_info_t app_info;
965         struct target_info_t target_info;
966         struct msg_t *msg_reply;
967         struct msg_buf_t msg_control;
968         struct user_space_inst_t user_space_inst;
969         struct conf_t conf;
970         enum ErrorCode error_code;
971
972         LOGI("MY HANDLE %s (%X)\n", msg_ID_str(msg->id), msg->id);
973         init_parse_control(&msg_control, msg);
974
975         switch (msg->id) {
976         case NMSG_KEEP_ALIVE:
977                 sendACKToHost(msg->id, ERR_NO, 0, 0);
978                 break;
979         case NMSG_START:
980                 if (parse_prof_session(&msg_control, &prof_session) != 0) {
981                         LOGE("prof session parsing error\n");
982                         sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
983                         return -1;
984                 }
985
986                 // TODO: launch translator thread
987                 if (start_transfer() != 0) {
988                         LOGE("Cannot start transfer\n");
989                         return -1;
990                 }
991
992
993                 // TODO: apply_prof_session()
994
995                 //write to device
996
997                 //response to control sockete
998                 cut_replay_events(msg);
999                 if (ioctl_send_msg(msg) != 0){
1000                         LOGE("cannot send message to device\n");
1001                         sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING);
1002                         // response to control socket
1003                         sendACKToHost(msg->id, ERR_CANNOT_START_PROFILING, 0, 0);
1004                         return -1;
1005                 }
1006
1007                 if (start_profiling() < 0) {
1008                         LOGE("cannot start profiling\n");
1009                         sendACKToHost(msg->id, ERR_CANNOT_START_PROFILING, 0, 0);
1010                         return -1;
1011                 }
1012
1013                 // TODO: start app launch timer
1014
1015
1016                 // success
1017                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1018                 break;
1019         case NMSG_STOP:
1020                 error_code = stop_all();
1021                 //send ack to host
1022                 sendACKToHost(msg->id, error_code, 0, 0);
1023                 break;
1024         case NMSG_CONFIG:
1025                 error_code=ERR_NO;
1026                 if (!parse_msg_config(&msg_control, &conf)) {
1027                         LOGE("config parsing error\n");
1028                         sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
1029                         return -1;
1030                 }
1031                 if (reconfigure(conf) != 0) {
1032                         LOGE("Cannot change configuration\n");
1033                         return -1;
1034                 }
1035                 //write to device
1036                 if (ioctl_send_msg(msg) != 0){
1037                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1038                         return -1;
1039                 }
1040                 //send ack to host
1041                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1042                 break;
1043         case NMSG_BINARY_INFO:
1044                 if (!parse_msg_binary_info(&msg_control, &app_info)) {
1045                         LOGE("binary info parsing error\n");
1046                         sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
1047                         return -1;
1048                 }
1049                 msg_reply = gen_binary_info_reply(&app_info);
1050                 if (!msg_reply) {
1051                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1052                         return -1;
1053                 }
1054
1055                 if (send_reply(msg_reply) != 0) {
1056                         LOGE("Cannot send reply\n");
1057                 }
1058
1059                 reset_app_info(&app_info);
1060                 free(msg_reply);
1061                 break;
1062         case NMSG_SWAP_INST_ADD:
1063                 if (!parse_user_space_inst(&msg_control,
1064                                            &user_space_inst)) {
1065                         LOGE("user space inst parsing error\n");
1066                         sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
1067                         return -1;
1068                 }
1069                 // TODO: apply_prof_session()
1070                 // warning concat_add_user_space_inst free user_space_inst
1071                 // so, data will not be availible
1072                 concat_add_user_space_inst(&user_space_inst, &prof_session.user_space_inst);
1073                 //write to device
1074                 if (ioctl_send_msg(msg) != 0){
1075                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1076                         return -1;
1077                 }
1078                 //send ack to host
1079                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1080                 // TODO release user_space_inst
1081                 break;
1082         case NMSG_SWAP_INST_REMOVE:
1083                 if (!parse_user_space_inst(&msg_control,
1084                                            &prof_session.user_space_inst)){
1085                         sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
1086                         LOGE("user space inst parsing error\n");
1087                         return -1;
1088                 }
1089                 if (ioctl_send_msg(msg) != 0){
1090                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1091                         return -1;
1092                 }
1093                 // TODO: apply_prof_session()
1094                 sendACKToHost(msg->id, ERR_NO, 0, 0);
1095                 break;
1096         case NMSG_GET_TARGET_INFO:
1097                 fill_target_info(&target_info);
1098                 msg_reply = gen_target_info_reply(&target_info);
1099                 if (!msg_reply) {
1100                         sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1101                         return -1;
1102                 }
1103                 if (send_reply(msg_reply) != 0) {
1104                         LOGE("Cannot send reply\n");
1105                 }
1106                 free(msg_reply);
1107                 reset_target_info(&target_info);
1108                 break;
1109
1110         default:
1111                 LOGE("unknown message %d <0x%08X>\n", msg->id, msg->id);
1112         }
1113
1114         return 0;
1115 }
1116
1117 // testing
1118
1119 static void print_app_info( struct app_info_t *app_info)
1120 {
1121         LOGI("application info=\n");
1122         LOGI("\tapp_type=<%d><0x%04X>\n"
1123                  "\tapp_id=<%s>\n"
1124                  "\texe_path=<%s>\n",
1125                  app_info->app_type,
1126                  app_info->app_type,
1127                  app_info->app_id,
1128                  app_info->exe_path
1129         );
1130 }
1131
1132 static void print_conf(struct conf_t * conf)
1133 {
1134         char buf[1024];
1135         memset(&buf[0],0,1024);
1136         feature_code_str(conf->use_features0, buf);
1137         LOGI("conf = \n");
1138         LOGI("\tuse_features0 = 0x%016LX (%s)\n", conf->use_features0, buf);
1139         LOGI("\tuse_features1 = 0x%016LX (%s)\n", conf->use_features1, buf);
1140         LOGI(
1141                  "\tsystem_trace_period = %d ms\n"
1142                  "\tdata message period = %d ms\n",
1143                  conf->system_trace_period,
1144                  conf->data_message_period
1145                  );
1146 }
1147
1148 void print_replay_event( struct replay_event_t *ev, uint32_t num, char *tab)
1149 {
1150         LOGW("%s\t#%04d:time=0x%08X %08X, "
1151                 " id=0x%08X,"
1152                 " type=0x%08X,"
1153                 " code=0x%08X,"
1154                 " value=0x%08X\n",
1155                 tab,num,
1156                 (unsigned int)ev->ev.time.tv_sec,//timeval
1157                 (unsigned int)ev->ev.time.tv_usec,//timeval
1158                 ev->id,
1159                 ev->ev.type,//u16
1160                 ev->ev.code,//u16
1161                 ev->ev.value//s32
1162                 );
1163 }
1164
1165 void print_replay_event_seq( struct replay_event_seq_t *event_seq)
1166 {
1167         uint32_t i = 0;
1168         char *tab="\t";
1169
1170         LOGI( "%senabled=0x%08X; "\
1171                 "time_start=0x%08X %08X; "\
1172                 "count=0x%08X\n",
1173                 tab,event_seq->enabled,
1174                 (unsigned int)event_seq->tv.tv_sec,
1175                 (unsigned int)event_seq->tv.tv_usec,
1176                 event_seq->event_num);
1177         for (i=0;i<event_seq->event_num;i++)
1178                 print_replay_event(&event_seq->events[i], i+1, tab);
1179
1180 }