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