4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
8 * Cherepanov Vitaliy <v.cherepanov@samsung.com>
9 * Nikita Kalyazin <n.kalyazin@samsung.com>
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
15 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 * - Samsung RnD Institute Russia
35 #include <sys/types.h>
36 #include <sys/socket.h>
38 #include <sys/sysinfo.h>
40 #include "da_protocol.h"
41 #include "da_protocol_check.h"
44 #include "transfer_thread.h"
46 #include "ioctl_commands.h"
56 void inline free_msg(struct msg_t *msg)
60 static uint32_t msg_size_with_out_replays = 0;
62 struct prof_session_t prof_session;
64 static void print_app_info( struct app_info_t *app_info);
65 static void print_conf(struct conf_t * conf);
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)
74 #define check_all(a1, ...) check_and_return(ID,a1) //#else check_all(__VA_ARGS__)
75 char* msg_ID_str ( enum HostMessageT ID)
89 NMSG_SWAP_INST_REMOVE,
97 NMSG_GET_TARGET_INFO_ACK
101 NMSG_SWAP_INST_ADD_ACK,
102 NMSG_SWAP_INST_REMOVE_ACK,
116 NMSG_CONTEXT_SWITCH_ENTRY,
118 NMSG_CONTEXT_SWITCH_EXIT,
127 NMSG_PROBE_LIFECYCLE,
128 NMSG_PROBE_SCREENSHOT,
139 static char *msgErrStr(enum ErrorCode err)
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)";
172 return "unknown error";
174 return "unknown error";
178 #define print_feature(f,in,to,delim) if (f & in)\
180 sprintf(to, dstr(f) delim );\
181 to+=strlen( dstr(f) delim );\
183 #define print_feature_a(f) print_feature(f,feature,to,", ")
184 void feature_code_str(uint32_t feature, char * to)
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);
210 inline uint32_t get_avail_msg_size(struct msg_buf_t *msg)
212 return (uint32_t)(msg->end - msg->cur_pos);
215 inline uint32_t get_msg_cur_size(struct msg_buf_t *msg)
217 return (uint32_t) (msg->cur_pos - msg->payload);
220 static int parse_string(struct msg_buf_t *msg, char **str)
222 parse_deb("size = %d\n", get_avail_msg_size(msg));
223 int len = strlen(msg->cur_pos) + 1;
225 if (get_avail_msg_size(msg) < len)
228 *str = strdup(msg->cur_pos);
229 parse_deb("<%s>\n",*str);
234 static const char* parse_string_inplace(struct msg_buf_t *msg)
236 const char *str = msg->cur_pos;
237 int avail_size = get_avail_msg_size(msg);
238 int len = strnlen(str, avail_size);
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.
245 if (len == avail_size)
248 msg->cur_pos += len + 1;
252 static int parse_int32(struct msg_buf_t *msg, uint32_t *val)
254 parse_deb("size = %d\n", get_avail_msg_size(msg));
255 if (get_avail_msg_size(msg) < sizeof(*val))
257 *val = *(uint32_t *)msg->cur_pos;
258 msg->cur_pos += sizeof(uint32_t);
261 parse_deb("<%d><0x%08X>\n",*val,*val);
265 static int parse_int64(struct msg_buf_t *msg, uint64_t *val)
267 parse_deb("size = %d\n", get_avail_msg_size(msg));
268 if (get_avail_msg_size(msg) < sizeof(*val))
271 *val = *(uint64_t *)msg->cur_pos;
273 parse_deb("<%llu><0x%016llX>\n",*val,*val);
274 msg->cur_pos += sizeof(uint64_t);
278 static void strip_args(const char *cmd, char *path)
280 char *bin_end = strchr(cmd, ' ');
285 size_t binname_len = bin_end - cmd;
286 memcpy(path, cmd, binname_len);
287 path[binname_len] = '\0';
291 static int parse_app_info(struct msg_buf_t *msg,
292 struct app_info_t *app_info)
294 char bin_path[MAX_FILENAME];
297 parse_deb("parse_app_info\n");
298 if (!parse_int32(msg, &app_info->app_type) ||
299 !check_app_type(app_info->app_type))
301 LOGE("app type error\n");
306 if (!parse_string(msg, &app_info->app_id) ||
307 !check_app_id(app_info->app_type, app_info->app_id))
309 LOGE("app id parsing error\n");
313 //Applicaion exe path
314 if (!parse_string(msg, &app_info->exe_path)) {
315 LOGE("app info parsing error\n");
318 strip_args(app_info->exe_path, bin_path);
319 if (!check_exec_path(bin_path)) {
320 LOGE("app info parsing error\n");
324 // print_app_info(app_info);
329 static int parse_conf(struct msg_buf_t *msg, struct conf_t *conf)
332 parse_deb("parse_conf\n");
333 if (!parse_int64(msg, &conf->use_features0)) {
334 LOGE("use features0 error\n");
338 if (!parse_int64(msg, &conf->use_features1)) {
339 LOGE("use features1 parsing error\n");
343 //Check features value
344 if (!check_conf_features(conf->use_features0, conf->use_features1)) {
345 LOGE("check features fail\n");
349 if (!parse_int32( msg, &conf->system_trace_period) ||
350 !check_conf_systrace_period(conf->system_trace_period))
352 LOGE("system trace period error\n");
356 if (!parse_int32( msg, &conf->data_message_period) ||
357 !check_conf_datamsg_period(conf->data_message_period))
359 LOGE("data message period error\n");
366 static int parse_us_inst_func(struct msg_buf_t *msg , struct us_func_inst_t * dest)
369 if (!parse_int64(msg, &(dest->func_addr))) {
370 LOGE("func addr parsing error\n");
374 if (!parse_string(msg, &dest->args) ||
375 !check_us_inst_func_args(dest->args))
377 LOGE("args format parsing error\n");
384 static int parse_func_inst_list(struct msg_buf_t *msg,
386 struct us_func_inst_t ** us_func_inst_list)
389 if (!parse_int32(msg, num) ||
390 !check_us_app_inst_func_count(*num))
392 LOGE("func num parsing error\n");
395 //parse user space function list
397 parse_deb("us_func_inst_list size = %d * %d\n",(*num),
398 (int)sizeof(**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");
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);
418 static int parse_us_inst_lib(struct msg_buf_t *msg, struct us_lib_inst_t * dest)
421 if (!parse_string(msg, &(dest)->bin_path) ||
422 !check_exec_path(dest->bin_path))
424 LOGE("bin path parsing error\n");
428 if (!parse_func_inst_list(msg, &dest->func_num, &dest->us_func_inst_list)) {
429 LOGE("funcs parsing error\n");
436 static int parse_lib_inst_list(struct msg_buf_t *msg,
438 struct us_lib_inst_t ** us_lib_inst_list)
441 if (!parse_int32(msg, num) ||
442 !check_lib_inst_count(*num))
444 LOGE("lib num parsing error\n");
448 parse_deb("lib_list size = %d\n", (*num) * (int)sizeof(**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");
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);
466 static int parse_app_inst(struct msg_buf_t *msg,
467 struct app_inst_t *app_inst)
469 if (!parse_int32(msg, &app_inst->app_type) ||
470 !check_app_type(app_inst->app_type))
472 LOGE("app type parsing error\n");
475 if (!parse_string(msg, &app_inst->app_id) ||
476 !check_app_id(app_inst->app_type, app_inst->app_id))
478 LOGE("app id parsing error\n");
481 if (!parse_string(msg, &app_inst->exec_path) ||
482 !check_exec_path(app_inst->exec_path))
484 LOGE("exec path parsing error\n");
487 if (!parse_func_inst_list(msg, &app_inst->func_num, &(app_inst->us_func_inst_list))) {
488 LOGE("funcs parsing error\n");
492 parse_deb(">=%04X : %s, %s\n",
493 app_inst->app_type, app_inst->app_id, app_inst->exec_path);
495 if (!parse_lib_inst_list( msg, &app_inst->lib_num , &app_inst->us_lib_inst_list)) {
496 LOGE("libs parsing error\n");
503 int parse_user_space_inst(struct msg_buf_t *msg,
504 struct user_space_inst_t *user_space_inst)
506 parse_deb("parse_user_space_inst\n");
507 uint32_t num = 0 , i = 0;
508 struct app_inst_t * list = 0;
510 if (!parse_int32 ( msg, &num ) ||
511 !check_us_app_count(num))
513 LOGE("app num error\n");
517 parse_deb("%d * %d\n",(int) sizeof(*(user_space_inst->app_inst_list)), num);
519 list = (struct app_inst_t *) malloc (
520 sizeof(*(user_space_inst->app_inst_list)) * num);
522 LOGE("apps alloc error\n");
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);
534 user_space_inst->app_num = num;
535 user_space_inst->app_inst_list = list;
540 //REPLAY EVENTS PARSE
541 static int parse_timeval(struct msg_buf_t *msg, struct timeval *tv)
547 if (!parse_int32(msg, (uint32_t *)&tv->tv_sec)) {
548 LOGE("sec parsing error\n");
552 if (!parse_int32(msg, &nsec)) {
553 LOGE("usec parsing error\n");
556 tv->tv_usec = nsec / 1000;
561 static int parse_replay_event(struct msg_buf_t *msg,
562 struct replay_event_t *re)
565 if (!parse_timeval(msg, &re->ev.time)) {
566 LOGE("time parsing error\n");
570 if (!parse_int32(msg, &re->id)) {
571 LOGE("id parsing error\n");
575 if (!parse_int32(msg, (uint32_t *)&re->ev.type)) {
576 LOGE("type parsing error\n");
580 if (!parse_int32(msg, (uint32_t *)&re->ev.code)) {
581 LOGE("code parsing error\n");
585 if (!parse_int32(msg, (uint32_t *)&re->ev.value)) {
586 LOGE("value parsing error\n");
593 void reset_replay_event_seq(struct replay_event_seq_t *res)
596 res->tv = (struct timeval){0, 0};
597 if (res->event_num != 0)
602 static int parse_replay_event_seq(struct msg_buf_t *msg,
603 struct replay_event_seq_t *res)
605 LOGI("parse_replay_event_seq\n");
608 parse_deb("REPLAY\n");
609 if (!parse_int32(msg, &res->enabled)) {
610 LOGE("enabled parsing error\n");
614 if(res->enabled == 0){
615 parse_deb("disable\n");
619 parse_deb("time main\n");
620 if (!parse_timeval(msg, &res->tv)) {
621 LOGE("time parsing error\n");
625 parse_deb("count\n");
626 if (!parse_int32(msg, &res->event_num)) {
627 LOGE("event num parsing error\n");
630 parse_deb("events num=%d\n", res->event_num);
632 res->events = (struct replay_event_t *)malloc(res->event_num *
633 sizeof(*res->events));
635 LOGE("events alloc error\n");
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);
652 //*REPLAY EVENT PARSE
654 static int parse_prof_session(struct msg_buf_t *msg,
655 struct prof_session_t *prof_session)
657 LOGI("parse_prof_session\n");
658 if (!parse_app_info(msg, &prof_session->app_info)) {
659 LOGE("app info parsing error\n");
662 if (!parse_conf(msg, &prof_session->conf)) {
663 LOGE("conf parsing error\n");
667 if (!parse_user_space_inst(msg, &prof_session->user_space_inst)) {
668 LOGE("user space inst parsing error\n");
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");
678 //print_prof_session(prof_session);
682 int get_sys_mem_size(uint32_t *sys_mem_size){
685 *sys_mem_size = info.totalram;
689 static int parse_msg_config(struct msg_buf_t * msg_payload,
690 struct conf_t * conf)
692 if (!parse_conf(msg_payload, conf)) {
693 LOGE("conf parsing error\n");
701 static int parse_msg_binary_info(struct msg_buf_t * msg_payload,
702 struct app_info_t *app_info)
704 if (!parse_app_info(msg_payload, app_info)) {
705 LOGE("app info parsing error\n");
709 print_app_info(app_info);
713 static void init_parse_control(struct msg_buf_t *buf, struct msg_t *msg)
715 LOGI("init parse control\n");
716 buf->payload = msg->payload;
718 buf->end = msg->payload + msg->len;
719 buf->cur_pos = msg->payload;
720 LOGI("init parse control done\n");
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)
728 struct app_inst_t *new_app_inst_list = NULL;
732 if (from->app_num == 0)
735 new_app_inst_list = malloc((from->app_num + to->app_num) * sizeof(*new_app_inst_list));
736 p = new_app_inst_list;
738 size = from->app_num * sizeof(*new_app_inst_list);
739 memcpy(p, from->app_inst_list, size);
742 size = to->app_num * sizeof(*new_app_inst_list);
743 memcpy(p, to->app_inst_list, size);
746 free(to->app_inst_list);
747 to->app_inst_list = new_app_inst_list;
749 to->app_num += from->app_num;
753 static void cut_replay_events(struct msg_t *msg){
755 LOGI("msg_size_with_out_replays = %d \n",msg_size_with_out_replays);
756 msg->len = msg_size_with_out_replays;
760 static void reset_app_info(struct app_info_t *app_info)
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));
769 static void reset_target_info(struct target_info_t *target_info)
774 static void reset_conf(struct conf_t *conf)
776 memset(conf, 0, sizeof(*conf));
779 static void reset_func_inst_list(uint32_t func_num,
780 struct us_func_inst_t *funcs)
784 for (i = 0; i < func_num; i++) {
785 funcs[i].func_addr = 0;
790 static void reset_lib_inst_list(uint32_t lib_num, struct us_lib_inst_t *libs)
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);
801 static void reset_app_inst(struct app_inst_t *app_inst)
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);
815 static void reset_user_space_inst(struct user_space_inst_t *us)
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;
828 void reset_system_info(struct system_info_t *sys_info)
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));
841 static void reset_prof_session(struct prof_session_t *prof_session)
843 reset_app_info(&prof_session->app_info);
844 reset_conf(&prof_session->conf);
845 reset_user_space_inst(&prof_session->user_space_inst);
848 static struct msg_t *gen_binary_info_reply(struct app_info_t *app_info)
850 uint32_t binary_type = get_binary_type(app_info->exe_path);
851 char binary_path[PATH_MAX];
854 uint32_t ret_id = ERR_NO;
856 get_build_dir(binary_path, app_info->exe_path);
858 if (binary_type == BINARY_TYPE_UNKNOWN) {
859 LOGE("Binary is neither relocatable, nor executable\n");
863 msg = malloc(sizeof(*msg) +
865 sizeof(binary_type) +
866 strlen(binary_path) + 1);
868 LOGE("Cannot alloc bin info msg\n");
872 msg->id = NMSG_BINARY_INFO_ACK;
876 pack_int(p, binary_type);
877 pack_str(p, binary_path);
879 msg->len = p - msg->payload;
884 static size_t str_array_getsize(const char **strings, size_t len)
887 * Calculate about of memory to place array
888 * of \0 delimited strings
892 for (index = 0; index != len; ++index)
893 size += strlen(strings[index]) + 1;
898 static struct msg_t *gen_target_info_reply(struct target_info_t *target_info)
902 uint32_t ret_id = ERR_NO;
904 msg = malloc(sizeof(*msg) +
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));
913 LOGE("Cannot alloc target info msg\n");
918 msg->id = NMSG_GET_TARGET_INFO_ACK;
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);
935 msg->len = p - msg->payload;
940 static int send_reply(struct msg_t *msg)
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));
952 static void write_msg_error(const char *err_str)
954 struct msg_data_t *err_msg = gen_message_error(err_str);
955 write_to_buf(err_msg);
956 free_msg_data(err_msg);
959 int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
960 char *payload, int payload_size)
962 if (manager.host.control_socket != -1)
965 uint32_t err = err_code;
966 int loglen = sizeof(*msg) - sizeof(msg->payload) +
967 sizeof(err) + //return ID
969 msg = malloc(loglen);
970 char *p = msg->payload;
974 case NMSG_KEEP_ALIVE:
975 resp = NMSG_KEEP_ALIVE_ACK;
978 resp = NMSG_START_ACK;
981 resp = NMSG_STOP_ACK;
984 resp = NMSG_CONFIG_ACK;
986 case NMSG_BINARY_INFO:
987 resp = NMSG_BINARY_INFO_ACK;
989 case NMSG_GET_TARGET_INFO:
990 resp = NMSG_GET_TARGET_INFO_ACK;
992 case NMSG_SWAP_INST_ADD:
993 resp = NMSG_SWAP_INST_ADD_ACK;
995 case NMSG_SWAP_INST_REMOVE:
996 resp = NMSG_SWAP_INST_REMOVE_ACK;
1007 msg->len = payload_size + sizeof(err);
1009 //*(uint32_t *)p = err; p+=sizeof(err);
1012 memcpy(p, payload, payload_size);
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);
1018 if (send(manager.host.control_socket, msg,
1019 loglen, MSG_NOSIGNAL) == -1) {
1020 LOGE("Cannot send reply: %s\n", strerror(errno));
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;
1039 enum ErrorCode stop_all(void)
1042 enum ErrorCode error_code = ERR_NO;
1043 struct msg_t *msg = gen_stop_msg();
1049 LOGE("cannot generate stop message\n");
1052 if (ioctl_send_msg(msg) != 0){
1053 LOGE("ioctl send filed\n");
1054 error_code = ERR_UNKNOWN;
1059 reset_prof_session(&prof_session);
1068 md5_byte_t digest[16];
1071 static void binary_ack_free(struct binary_ack *ba)
1077 static size_t binary_ack_size(const struct binary_ack *ba)
1079 /* MD5 is 16 bytes, so 16*2 hex digits */
1080 return sizeof(uint32_t) + strlen(ba->binpath) + 1
1084 static size_t binary_ack_pack(char *s, const struct binary_ack *ba)
1086 unsigned int len = strlen(ba->binpath);
1088 *(uint32_t *) s = ba->type;
1089 s += sizeof(uint32_t);
1092 memmove(s, ba->binpath, len);
1097 for (i = 0; i!= 16; ++i) {
1098 sprintf(s, "%02x", ba->digest[i]);
1102 return sizeof(uint32_t) + len + 1 + 2*16 + 1;
1105 static void get_file_md5sum(md5_byte_t digest[16], const char *filename)
1109 md5_state_t md5_state;
1110 int fd = open(filename, O_RDONLY);
1112 md5_init(&md5_state);
1114 while ((size = read(fd, buffer, sizeof(buffer))) > 0)
1115 md5_append(&md5_state, buffer, size);
1117 md5_finish(&md5_state, digest);
1121 static struct binary_ack* binary_ack_alloc(const char *filename)
1123 struct binary_ack *ba = malloc(sizeof(*ba));
1124 char binpath[PATH_MAX];
1125 ba->type = get_binary_type(filename);
1127 get_build_dir(binpath, filename);
1128 ba->binpath = strdup(binpath);
1130 get_file_md5sum(ba->digest, filename);
1135 static int process_msg_binary_info(struct msg_buf_t *msg)
1137 uint32_t i, bincount;
1139 if (!parse_int32(msg, &bincount)) {
1140 LOGE("MSG_BINARY_INFO error: No binaries count\n");
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);
1149 LOGE("MSG_BINARY_INFO error: No enough binaries\n");
1152 acks[i] = binary_ack_alloc(str);
1153 total_size += binary_ack_size(acks[i]);
1156 struct msg_t* msg_reply = malloc(8 + total_size);
1157 char *p = msg_reply->payload;
1159 msg_reply->id = NMSG_BINARY_INFO_ACK;
1160 msg_reply->len = total_size;
1162 for (i = 0; i != bincount; ++i) {
1163 p += binary_ack_pack(p, acks[i]);
1164 binary_ack_free(acks[i]);
1167 int err = send_reply(msg_reply);
1172 int host_message_handler(struct msg_t *msg)
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;
1180 enum ErrorCode error_code;
1184 msg_target_t sendlog;
1186 LOGI("MY HANDLE %s (%X)\n", msg_ID_str(msg->id), msg->id);
1187 init_parse_control(&msg_control, msg);
1190 case NMSG_KEEP_ALIVE:
1191 sendACKToHost(msg->id, ERR_NO, 0, 0);
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);
1200 if (start_transfer() != 0) {
1201 LOGE("Cannot start transfer\n");
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);
1214 if (start_profiling() < 0) {
1215 LOGE("cannot start profiling\n");
1216 sendACKToHost(msg->id, ERR_CANNOT_START_PROFILING, 0, 0);
1220 // TODO: start app launch timer
1224 sendACKToHost(msg->id, ERR_NO, 0, 0);
1227 sendACKToHost(msg->id, ERR_NO, 0, 0);
1228 if (stop_all() != ERR_NO)
1229 write_msg_error("Stop failed");
1233 if (!parse_msg_config(&msg_control, &conf)) {
1234 LOGE("config parsing error\n");
1235 sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
1238 if (reconfigure(conf) != 0) {
1239 LOGE("Cannot change configuration\n");
1243 if (ioctl_send_msg(msg) != 0){
1244 sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1248 sendACKToHost(msg->id, ERR_NO, 0, 0);
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++)
1256 if(manager.target[target_index].socket != -1)
1258 if (0 > send(manager.target[target_index].socket, &sendlog,
1259 sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length,
1261 LOGE("fail to send data to target index(%d)\n", target_index);
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);
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);
1279 if (ioctl_send_msg(msg) != 0){
1280 sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1284 sendACKToHost(msg->id, ERR_NO, 0, 0);
1285 // TODO release user_space_inst
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");
1294 if (ioctl_send_msg(msg) != 0){
1295 sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1298 // TODO: apply_prof_session()
1299 sendACKToHost(msg->id, ERR_NO, 0, 0);
1301 case NMSG_GET_TARGET_INFO:
1302 fill_target_info(&target_info);
1303 msg_reply = gen_target_info_reply(&target_info);
1305 LOGE("cannot generate reply message\n");
1306 sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1309 if (send_reply(msg_reply) != 0) {
1310 LOGE("Cannot send reply\n");
1313 reset_target_info(&target_info);
1317 LOGE("unknown message %d <0x%08X>\n", msg->id, msg->id);
1325 static void print_app_info( struct app_info_t *app_info)
1327 LOGI("application info=\n");
1328 LOGI("\tapp_type=<%d><0x%04X>\n"
1330 "\texe_path=<%s>\n",
1338 static void print_conf(struct conf_t * conf)
1341 memset(&buf[0],0,1024);
1342 feature_code_str(conf->use_features0, buf);
1344 LOGI("\tuse_features0 = 0x%016LX (%s)\n", conf->use_features0, buf);
1345 LOGI("\tuse_features1 = 0x%016LX (%s)\n", conf->use_features1, buf);
1347 "\tsystem_trace_period = %d ms\n"
1348 "\tdata message period = %d ms\n",
1349 conf->system_trace_period,
1350 conf->data_message_period
1354 void print_replay_event( struct replay_event_t *ev, uint32_t num, char *tab)
1356 LOGW("%s\t#%04d:time=0x%08X %08X, "
1362 (unsigned int)ev->ev.time.tv_sec,//timeval
1363 (unsigned int)ev->ev.time.tv_usec,//timeval
1371 void print_replay_event_seq( struct replay_event_seq_t *event_seq)
1376 LOGI( "%senabled=0x%08X; "\
1377 "time_start=0x%08X %08X; "\
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);