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