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"
42 #include "da_protocol_check.h"
45 #include "transfer_thread.h"
47 #include "ioctl_commands.h"
56 static pthread_mutex_t stop_all_mutex = PTHREAD_MUTEX_INITIALIZER;
58 void inline free_msg(struct msg_t *msg)
63 struct prof_session_t prof_session;
65 static void print_app_info(struct app_info_t *app_info);
66 static void print_conf(struct conf_t *conf);
69 #define check_and_return(check) if ( ID == check ) {return dstr(check);}
71 char *msg_ID_str(enum HostMessageT ID)
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);
83 check_and_return(NMSG_KEEP_ALIVE_ACK);
84 check_and_return(NMSG_START_ACK);
85 check_and_return(NMSG_STOP_ACK);
86 check_and_return(NMSG_CONFIG_ACK);
87 check_and_return(NMSG_BINARY_INFO_ACK);
88 check_and_return(NMSG_SWAP_INST_ACK);
89 check_and_return(NMSG_GET_TARGET_INFO_ACK);
90 check_and_return(NMSG_SWAP_INST_ADD_ACK);
91 check_and_return(NMSG_SWAP_INST_REMOVE_ACK);
93 check_and_return(NMSG_PROCESS_INFO);
94 check_and_return(NMSG_TERMINATE);
95 check_and_return(NMSG_ERROR);
96 check_and_return(NMSG_SAMPLE);
97 check_and_return(NMSG_SYSTEM);
98 check_and_return(NMSG_IMAGE);
99 check_and_return(NMSG_RECORD);
100 check_and_return(NMSG_FUNCTION_ENTRY);
101 check_and_return(NMSG_FUNCTION_EXIT);
102 check_and_return(NMSG_CONTEXT_SWITCH_ENTRY);
103 check_and_return(NMSG_CONTEXT_SWITCH_EXIT);
108 static char *msgErrStr(enum ErrorCode err)
113 case ERR_LOCKFILE_CREATE_FAILED:
114 return "lock file create failed";
115 case ERR_ALREADY_RUNNING:
116 return "already running";
117 case ERR_INITIALIZE_SYSTEM_INFO_FAILED:
118 return "initialize system info failed";
119 case ERR_HOST_SERVER_SOCKET_CREATE_FAILED:
120 return "host server socket create failed";
121 case ERR_TARGET_SERVER_SOCKET_CREATE_FAILED:
122 return "target server socket create failed";
123 case ERR_SIGNAL_MASK_SETTING_FAILED: //TODO del (old parametr)
124 return "ERR SIGNAL MASK SETTING FAILED";
125 case ERR_WRONG_MESSAGE_FORMAT:
126 return "wrong message format";
127 case ERR_WRONG_MESSAGE_TYPE:
128 return "wrong message type";
129 case ERR_WRONG_MESSAGE_DATA:
130 return "wrong message data";
131 case ERR_CANNOT_START_PROFILING:
132 return "cannot start profiling";
133 case ERR_SERV_SOCK_CREATE:
134 return "server socket creation failed (written in /tmp/da.port file)";
135 case ERR_SERV_SOCK_BIND:
136 return "server socket bind failed (written in /tmp/da.port file)";
137 case ERR_SERV_SOCK_LISTEN:
138 return "server socket listen failed (written in /tmp/da.port file)";
141 return "unknown error";
143 return "unknown error";
147 #define print_feature(f,in,to,delim) \
149 sprintf(to, dstr(f) delim ); \
150 to+=strlen( dstr(f) delim ); \
152 #define print_feature_0(f) print_feature(f, feature0, to, ", \n\t")
153 void feature_code_str(uint64_t feature0, uint64_t feature1, char *to)
155 print_feature_0(FL_CPU);
156 print_feature_0(FL_MEMORY);
157 print_feature_0(FL_FUNCTION_PROFILING);
158 print_feature_0(FL_MEMORY_ALLOC_PROBING);
159 print_feature_0(FL_FILE_API_PROBING);
160 print_feature_0(FL_THREAD_API_PROBING);
161 print_feature_0(FL_OSP_UI_API_PROBING);
162 print_feature_0(FL_SCREENSHOT);
163 print_feature_0(FL_USER_EVENT);
164 print_feature_0(FL_RECORDING);
165 print_feature_0(FL_SYSTCALL_FILE);
166 print_feature_0(FL_SYSTCALL_IPC);
167 print_feature_0(FL_SYSTCALL_PROCESS);
168 print_feature_0(FL_SYSTCALL_SIGNAL);
169 print_feature_0(FL_SYSTCALL_NETWORK);
170 print_feature_0(FL_SYSTCALL_DESC);
171 print_feature_0(FL_CONTEXT_SWITCH);
172 print_feature_0(FL_NETWORK_API_PROBING);
173 print_feature_0(FL_OPENGL_API_PROBING);
174 print_feature_0(FL_MEMORY_ALLOC_ALWAYS_PROBING);
175 print_feature_0(FL_FILE_API_ALWAYS_PROBING);
176 print_feature_0(FL_THREAD_API_ALWAYS_PROBING);
177 print_feature_0(FL_OSP_UI_API_ALWAYS_PROBING);
178 print_feature_0(FL_NETWORK_API_ALWAYS_PROBING);
179 print_feature_0(FL_OPENGL_API_ALWAYS_PROBING);
184 inline uint32_t get_avail_msg_size(struct msg_buf_t *msg)
186 return (uint32_t)(msg->end - msg->cur_pos);
189 inline uint32_t get_msg_cur_size(struct msg_buf_t *msg)
191 return (uint32_t) (msg->cur_pos - msg->payload);
194 int parse_string(struct msg_buf_t *msg, char **str)
196 parse_deb("size = %d\n", get_avail_msg_size(msg));
197 int len = strlen(msg->cur_pos) + 1;
199 if (get_avail_msg_size(msg) < len)
202 *str = strdup(msg->cur_pos);
203 parse_deb("<%s>\n", *str);
208 static const char* parse_string_inplace(struct msg_buf_t *msg)
210 const char *str = msg->cur_pos;
211 int avail_size = get_avail_msg_size(msg);
212 int len = strnlen(str, avail_size);
214 /* Malformed string or exhaused buffer. Strlen is at least one byte
215 * less, that availiable space. If it is not, string is lacking
216 * terminating null char.
219 if (len == avail_size)
222 msg->cur_pos += len + 1;
226 int parse_string_no_alloc(struct msg_buf_t *msg, char *str)
228 parse_deb("size = %d\n", get_avail_msg_size(msg));
229 int len = strlen(msg->cur_pos) + 1;
231 if (get_avail_msg_size(msg) < len)
234 memcpy(str, msg->cur_pos, len);
235 parse_deb("<%s>\n", str);
240 int parse_int8(struct msg_buf_t *msg, uint8_t *val)
242 parse_deb("size = %d\n", get_avail_msg_size(msg));
243 if (get_avail_msg_size(msg) < sizeof(*val))
245 *val = *(uint8_t *)msg->cur_pos;
246 msg->cur_pos += sizeof(uint8_t);
248 parse_deb("<%d><0x%08X>\n", *val, *val);
254 int parse_int32(struct msg_buf_t *msg, uint32_t *val)
256 parse_deb("size = %d\n", get_avail_msg_size(msg));
257 if (get_avail_msg_size(msg) < sizeof(*val))
259 *val = *(uint32_t *)msg->cur_pos;
260 msg->cur_pos += sizeof(uint32_t);
263 parse_deb("<%d><0x%08X>\n", *val, *val);
268 int parse_int64(struct msg_buf_t *msg, uint64_t *val)
270 parse_deb("size = %d\n", get_avail_msg_size(msg));
271 if (get_avail_msg_size(msg) < sizeof(*val))
274 *val = *(uint64_t *)msg->cur_pos;
276 parse_deb("<%llu><0x%016llX>\n", *val, *val);
277 msg->cur_pos += sizeof(uint64_t);
281 static void strip_args(const char *cmd, char *path)
283 char *bin_end = strchr(cmd, ' ');
288 size_t binname_len = bin_end - cmd;
289 memcpy(path, cmd, binname_len);
290 path[binname_len] = '\0';
294 static int parse_app_info(struct msg_buf_t *msg,
295 struct app_info_t *app_info)
297 char bin_path[MAX_FILENAME];
300 parse_deb("parse_app_info\n");
301 if (!parse_int32(msg, &app_info->app_type) ||
302 !check_app_type(app_info->app_type))
304 LOGE("app type error\n");
308 if (!parse_string(msg, &app_info->app_id) ||
309 !check_app_id(app_info->app_type, app_info->app_id))
311 LOGE("app id parsing error\n");
314 //Applicaion exe path
315 if (!parse_string(msg, &app_info->exe_path)) {
316 LOGE("app info parsing error\n");
319 strip_args(app_info->exe_path, bin_path);
320 if (!check_exec_path(bin_path)) {
321 LOGE("app info parsing error\n");
324 // print_app_info(app_info);
328 static int parse_conf(struct msg_buf_t *msg, struct conf_t *conf)
331 parse_deb("parse_conf\n");
332 if (!parse_int64(msg, &conf->use_features0)) {
333 LOGE("use features0 error\n");
337 if (!parse_int64(msg, &conf->use_features1)) {
338 LOGE("use features1 parsing error\n");
341 //Check features value
342 if (!check_conf_features(conf->use_features0, conf->use_features1)) {
343 LOGE("check features fail\n");
347 if (!parse_int32( msg, &conf->system_trace_period) ||
348 !check_conf_systrace_period(conf->system_trace_period))
350 LOGE("system trace period error\n");
354 if (!parse_int32( msg, &conf->data_message_period) ||
355 !check_conf_datamsg_period(conf->data_message_period))
357 LOGE("data message period error\n");
364 //REPLAY EVENTS PARSE
365 static int parse_timeval(struct msg_buf_t *msg, struct timeval *tv)
371 if (!parse_int32(msg, (uint32_t *)&tv->tv_sec)) {
372 LOGE("sec parsing error\n");
376 if (!parse_int32(msg, &nsec)) {
377 LOGE("usec parsing error\n");
380 tv->tv_usec = nsec / 1000;
385 static int parse_replay_event(struct msg_buf_t *msg,
386 struct replay_event_t *re)
389 if (!parse_timeval(msg, &re->ev.time)) {
390 LOGE("time parsing error\n");
394 if (!parse_int32(msg, &re->id)) {
395 LOGE("id parsing error\n");
399 if (!parse_int32(msg, (uint32_t *)&re->ev.type)) {
400 LOGE("type parsing error\n");
404 if (!parse_int32(msg, (uint32_t *)&re->ev.code)) {
405 LOGE("code parsing error\n");
409 if (!parse_int32(msg, (uint32_t *)&re->ev.value)) {
410 LOGE("value parsing error\n");
417 void reset_replay_event_seq(struct replay_event_seq_t *res)
420 res->tv = (struct timeval){0, 0};
421 if (res->event_num != 0)
426 int parse_replay_event_seq(struct msg_buf_t *msg,
427 struct replay_event_seq_t *res)
430 parse_deb("REPLAY\n");
431 if (!parse_int32(msg, &res->enabled)) {
432 LOGE("enabled parsing error\n");
436 if(res->enabled == 0) {
437 parse_deb("disable\n");
441 parse_deb("time main\n");
442 if (!parse_timeval(msg, &res->tv)) {
443 LOGE("time parsing error\n");
447 parse_deb("count\n");
448 if (!parse_int32(msg, &res->event_num)) {
449 LOGE("event num parsing error\n");
452 parse_deb("events num=%d\n", res->event_num);
454 res->events = (struct replay_event_t *)malloc(res->event_num *
455 sizeof(*res->events));
457 LOGE("events alloc error\n");
461 for (i = 0; i < res->event_num; i++) {
462 parse_deb("sub_rep\n");
463 if (!parse_replay_event(msg, &res->events[i])) {
464 LOGE("event #%d parsing error\n", i + 1);
474 //*REPLAY EVENT PARSE
476 int get_sys_mem_size(uint32_t *sys_mem_size){
479 *sys_mem_size = info.totalram;
483 static int parse_msg_config(struct msg_buf_t *msg_payload,
486 if (!parse_conf(msg_payload, conf)) {
487 LOGE("conf parsing error\n");
495 static int parse_msg_binary_info(struct msg_buf_t *msg_payload,
496 struct app_info_t *app_info)
498 if (!parse_app_info(msg_payload, app_info)) {
499 LOGE("app info parsing error\n");
503 print_app_info(app_info);
507 static void init_parse_control(struct msg_buf_t *buf, struct msg_t *msg)
509 buf->payload = msg->payload;
511 buf->end = msg->payload + msg->len;
512 buf->cur_pos = msg->payload;
515 static void reset_app_info(struct app_info_t *app_info)
517 if (app_info->app_id != NULL)
518 free(app_info->app_id);
519 if (app_info->exe_path != NULL)
520 free(app_info->exe_path);
521 memset(app_info, 0, sizeof(*app_info));
524 static void reset_target_info(struct target_info_t *target_info)
529 static void reset_conf(struct conf_t *conf)
531 memset(conf, 0, sizeof(*conf));
534 static void running_status_on(struct prof_session_t *prof_session)
536 prof_session->running_status = 1;
539 static void running_status_off(struct prof_session_t *prof_session)
541 prof_session->running_status = 0;
544 int check_running_status(const struct prof_session_t *prof_session)
546 return prof_session->running_status;
549 static void reset_app_inst(struct user_space_inst_t *us_inst)
551 free_data_list((struct data_list_t **)&us_inst->app_inst_list);
552 us_inst->app_num = 0;
553 us_inst->app_inst_list = NULL;
556 static void reset_lib_inst(struct user_space_inst_t *us_inst)
558 free_data_list((struct data_list_t **)&us_inst->lib_inst_list);
559 us_inst->lib_num = 0;
560 us_inst->lib_inst_list = NULL;
563 static void reset_user_space_inst(struct user_space_inst_t *us_inst)
565 reset_app_inst(us_inst);
566 reset_lib_inst(us_inst);
569 void reset_system_info(struct system_info_t *sys_info)
571 if (sys_info->thread_load)
572 free(sys_info->thread_load);
573 if (sys_info->process_load)
574 free(sys_info->process_load);
575 if (sys_info->cpu_frequency)
576 free(sys_info->cpu_frequency);
577 if (sys_info->cpu_load)
578 free(sys_info->cpu_load);
579 memset(sys_info, 0, sizeof(*sys_info));
582 void init_prof_session(struct prof_session_t *prof_session)
584 memset(prof_session, 0, sizeof(*prof_session));
587 static void reset_prof_session(struct prof_session_t *prof_session)
589 reset_conf(&prof_session->conf);
590 reset_user_space_inst(&prof_session->user_space_inst);
591 reset_replay_event_seq(&prof_session->replay_event_seq);
592 running_status_off(prof_session);
595 static struct msg_t *gen_binary_info_reply(struct app_info_t *app_info)
597 uint32_t binary_type = get_binary_type(app_info->exe_path);
598 char binary_path[PATH_MAX];
601 uint32_t ret_id = ERR_NO;
603 get_build_dir(binary_path, app_info->exe_path);
605 if (binary_type == BINARY_TYPE_UNKNOWN) {
606 LOGE("Binary is neither relocatable, nor executable\n");
610 msg = malloc(sizeof(*msg) +
612 sizeof(binary_type) +
613 strlen(binary_path) + 1);
615 LOGE("Cannot alloc bin info msg\n");
619 msg->id = NMSG_BINARY_INFO_ACK;
622 pack_int32(p, ret_id);
623 pack_int32(p, binary_type);
624 pack_str(p, binary_path);
626 msg->len = p - msg->payload;
631 static size_t str_array_getsize(const char **strings, size_t len)
634 * Calculate about of memory to place array
635 * of \0 delimited strings
639 for (index = 0; index != len; ++index)
640 size += strlen(strings[index]) + 1;
645 static struct msg_t *gen_target_info_reply(struct target_info_t *target_info)
649 uint32_t ret_id = ERR_NO;
651 msg = malloc(sizeof(*msg) +
653 sizeof(*target_info) -
654 sizeof(target_info->network_type) +
655 strlen(target_info->network_type) + 1 +
656 sizeof(uint32_t) + /* devices count */
657 str_array_getsize(supported_devices_strings,
658 supported_devices_count));
660 LOGE("Cannot alloc target info msg\n");
665 msg->id = NMSG_GET_TARGET_INFO_ACK;
668 pack_int32(p, ret_id);
669 pack_int64(p, target_info->sys_mem_size);
670 pack_int64(p, target_info->storage_size);
671 pack_int32(p, target_info->bluetooth_supp);
672 pack_int32(p, target_info->gps_supp);
673 pack_int32(p, target_info->wifi_supp);
674 pack_int32(p, target_info->camera_count);
675 pack_str(p, target_info->network_type);
676 pack_int32(p, target_info->max_brightness);
677 pack_int32(p, target_info->cpu_core_count);
678 pack_int32(p, supported_devices_count);
679 p = pack_str_array(p, supported_devices_strings,
680 supported_devices_count);
682 msg->len = p - msg->payload;
687 static int send_reply(struct msg_t *msg)
689 printBuf((char *)msg, msg->len + sizeof (*msg));
690 if (send(manager.host.control_socket,
691 msg, MSG_CMD_HDR_LEN + msg->len, MSG_NOSIGNAL) == -1) {
692 LOGE("Cannot send reply : %s\n", strerror(errno));
699 static void write_msg_error(const char *err_str)
701 struct msg_data_t *err_msg = gen_message_error(err_str);
702 write_to_buf(err_msg);
703 free_msg_data(err_msg);
706 static enum HostMessageT get_ack_msg_id(const enum HostMessageT id)
709 case NMSG_KEEP_ALIVE:
710 return NMSG_KEEP_ALIVE_ACK;
712 return NMSG_START_ACK;
714 return NMSG_STOP_ACK;
716 return NMSG_CONFIG_ACK;
717 case NMSG_BINARY_INFO:
718 return NMSG_BINARY_INFO_ACK;
719 case NMSG_GET_TARGET_INFO:
720 return NMSG_GET_TARGET_INFO_ACK;
721 case NMSG_SWAP_INST_ADD:
722 return NMSG_SWAP_INST_ADD_ACK;
723 case NMSG_SWAP_INST_REMOVE:
724 return NMSG_SWAP_INST_REMOVE_ACK;
726 LOGE("Fatal: unknown message ID [0x%X]\n", id);
731 int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
732 char *payload, int payload_size)
734 if (manager.host.control_socket != -1) {
736 uint32_t err = err_code;
737 int loglen = sizeof(*msg) - sizeof(msg->payload) +
738 sizeof(err) + //return ID
740 msg = malloc(loglen);
741 char *p = msg->payload;
743 resp = get_ack_msg_id(resp);
748 msg->len = payload_size + sizeof(err);
752 memcpy(p, payload, payload_size);
754 LOGI("ACK (%s) errcode<%s> payload=0x%08X; size=%d\n", msg_ID_str(resp),
755 msgErrStr(err_code), (int)payload, payload_size);
756 printBuf((char *)msg, loglen);
758 if (send(manager.host.control_socket, msg,
759 loglen, MSG_NOSIGNAL) == -1) {
760 LOGE("Cannot send reply: %s\n", strerror(errno));
770 struct msg_t *gen_stop_msg(void)
772 struct msg_t *res = malloc(sizeof(*res));
773 memset(res, 0, sizeof(*res));
780 enum ErrorCode stop_all_no_lock(void)
782 enum ErrorCode error_code = ERR_NO;
785 // stop all only if it has not been called yet
786 if (check_running_status(&prof_session)) {
787 msg = gen_stop_msg();
792 LOGE("cannot generate stop message\n");
793 error_code = ERR_UNKNOWN;
796 if (ioctl_send_msg(msg) != 0) {
797 LOGE("ioctl send failed\n");
798 error_code = ERR_UNKNOWN;
805 // we reset only app inst no lib no confing reset
806 reset_app_inst(&prof_session.user_space_inst);
808 running_status_off(&prof_session);
810 LOGI("already stopped\n");
813 LOGI("finished: ret = %d\n", error_code);
817 int stop_all_in_process(void)
819 return (pthread_mutex_trylock(&stop_all_mutex) != 0);
822 void stop_all_done(void)
824 pthread_mutex_unlock(&stop_all_mutex);
827 enum ErrorCode stop_all(void)
829 enum ErrorCode error_code = ERR_NO;
831 pthread_mutex_lock(&stop_all_mutex);
832 error_code = stop_all_no_lock();
833 pthread_mutex_unlock(&stop_all_mutex);
841 md5_byte_t digest[16];
844 static void binary_ack_free(struct binary_ack *ba)
851 static size_t binary_ack_size(const struct binary_ack *ba)
853 /* MD5 is 16 bytes, so 16*2 hex digits */
854 return sizeof(uint32_t) + strlen(ba->binpath) + 1
858 static size_t binary_ack_pack(char *s, const struct binary_ack *ba)
860 unsigned int len = strlen(ba->binpath);
862 *(uint32_t *) s = ba->type;
863 s += sizeof(uint32_t);
866 memmove(s, ba->binpath, len);
871 for (i = 0; i!= 16; ++i) {
872 sprintf(s, "%02x", ba->digest[i]);
876 return sizeof(uint32_t) + len + 1 + 2*16 + 1;
879 static void get_file_md5sum(md5_byte_t digest[16], const char *filename)
881 md5_byte_t buffer[1024];
883 md5_state_t md5_state;
884 int fd = open(filename, O_RDONLY);
886 md5_init(&md5_state);
888 while ((size = read(fd, buffer, sizeof(buffer))) > 0)
889 md5_append(&md5_state, buffer, size);
891 md5_finish(&md5_state, digest);
895 static const char* basename(const char *filename)
897 const char *p = strrchr(filename, '/');
898 return p ? p + 1 : NULL;
900 static struct binary_ack* binary_ack_alloc(const char *filename)
902 struct binary_ack *ba = malloc(sizeof(*ba));
903 char builddir[PATH_MAX];
904 char binpath[PATH_MAX];
906 ba->type = get_binary_type(filename);
908 get_build_dir(builddir, filename);
910 snprintf(binpath, sizeof(binpath), "%s/%s",
911 builddir, basename(filename) ?: "");
913 ba->binpath = strdup(binpath);
915 get_file_md5sum(ba->digest, filename);
920 static int process_msg_binary_info(struct msg_buf_t *msg)
922 uint32_t i, bincount;
924 if (!parse_int32(msg, &bincount)) {
925 LOGE("MSG_BINARY_INFO error: No binaries count\n");
929 struct binary_ack *acks[bincount];
930 size_t total_size = 0;
931 for (i = 0; i != bincount; ++i) {
932 const char *str = parse_string_inplace(msg);
934 LOGE("MSG_BINARY_INFO error: No enough binaries\n");
937 acks[i] = binary_ack_alloc(str);
938 total_size += binary_ack_size(acks[i]);
940 typedef uint32_t return_id;
941 typedef uint32_t binary_ack_count;
942 struct msg_t *msg_reply = malloc(sizeof(struct msg_t)
944 + sizeof(binary_ack_count)
946 char *p = msg_reply->payload;
948 msg_reply->id = NMSG_BINARY_INFO_ACK;
949 msg_reply->len = total_size + sizeof(return_id)
950 + sizeof(binary_ack_count);
952 pack_int32(p, ERR_NO);
953 pack_int32(p, bincount);
955 for (i = 0; i != bincount; ++i) {
956 p += binary_ack_pack(p, acks[i]);
957 binary_ack_free(acks[i]);
960 int err = send_reply(msg_reply);
965 static void get_serialized_time(uint32_t dst[2])
968 gettimeofday(&tv, NULL);
970 dst[1] = tv.tv_usec * 1000;
973 static int process_msg_start(struct msg_buf_t *msg_control)
975 enum ErrorCode err_code = ERR_CANNOT_START_PROFILING;
976 struct msg_t *msg_reply;
977 uint32_t serialized_time[2];
979 if (check_running_status(&prof_session) == 1) {
980 LOGW("Profiling has already been started\n");
984 if (!check_conf(&prof_session.conf)) {
985 LOGE("wrong profile config\n");
989 if (msg_start(msg_control, &prof_session.user_space_inst,
990 &msg_reply, &err_code) != 0) {
991 LOGE("parse error\n");
995 if (prepare_profiling() != 0) {
996 LOGE("failed to prepare profiling\n");
1000 if (start_transfer() != 0) {
1001 LOGE("Cannot start transfer\n");
1005 if (ioctl_send_msg(msg_reply) != 0) {
1006 LOGE("cannot send message to device\n");
1010 running_status_on(&prof_session);
1012 if (start_profiling() < 0) {
1013 LOGE("cannot start profiling\n");
1014 if (stop_all() != ERR_NO) {
1015 LOGE("Stop failed\n");
1016 write_msg_error("Stop failed");
1023 get_serialized_time(serialized_time);
1024 sendACKToHost(NMSG_START, err_code, (void *)&serialized_time,
1025 sizeof(serialized_time));
1027 return -(err_code != ERR_NO);
1030 int process_msg_get_screenshot(struct msg_buf_t *msg_control)
1035 msg_target_t sendlog;
1036 enum ErrorCode err_code = ERR_UNKNOWN;
1038 // send config message to target process
1039 sendlog.type = MSG_CAPTURE_SCREEN;
1040 sendlog.length = sprintf(sendlog.data, "");
1041 log_len = sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length;
1043 for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++) {
1044 sock = manager.target[target_index].socket;
1046 if (send(sock, &sendlog, log_len, MSG_NOSIGNAL) == -1) {
1047 LOGE("fail to send data to target index(%d)\n",
1056 return -(err_code != ERR_NO);
1059 int host_message_handler(struct msg_t *msg)
1061 struct target_info_t target_info;
1062 struct msg_t *msg_reply = NULL;
1063 struct msg_buf_t msg_control;
1065 enum ErrorCode error_code = ERR_NO;
1068 msg_target_t sendlog;
1070 LOGI("MY HANDLE %s (%X)\n", msg_ID_str(msg->id), msg->id);
1071 init_parse_control(&msg_control, msg);
1074 case NMSG_KEEP_ALIVE:
1075 sendACKToHost(msg->id, ERR_NO, 0, 0);
1078 return process_msg_start(&msg_control);
1080 sendACKToHost(msg->id, ERR_NO, 0, 0);
1081 if (stop_all() != ERR_NO) {
1082 LOGE("Stop failed\n");
1083 write_msg_error("Stop failed");
1087 error_code = ERR_NO;
1088 if (!parse_msg_config(&msg_control, &conf)) {
1089 LOGE("config parsing error\n");
1090 sendACKToHost(msg->id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
1093 if (reconfigure(conf) != 0) {
1094 LOGE("Cannot change configuration\n");
1098 if (ioctl_send_msg(msg) != 0) {
1099 LOGE("ioctl send error\n");
1100 sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1104 sendACKToHost(msg->id, ERR_NO, 0, 0);
1105 // send config message to target process
1106 sendlog.type = MSG_OPTION;
1107 sendlog.length = sprintf(sendlog.data, "%llu",
1108 (unsigned long long) prof_session.conf.use_features0);
1109 for (target_index = 0; target_index < MAX_TARGET_COUNT; target_index++)
1111 if(manager.target[target_index].socket != -1)
1113 if (0 > send(manager.target[target_index].socket, &sendlog,
1114 sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length,
1116 LOGE("fail to send data to target index(%d)\n", target_index);
1120 case NMSG_BINARY_INFO:
1121 return process_msg_binary_info(&msg_control);
1122 case NMSG_SWAP_INST_ADD:
1123 if (msg_swap_inst_add(&msg_control, &prof_session.user_space_inst,
1124 &msg_reply, &error_code) != 0) {
1125 LOGE("swap inst add\n");
1128 if (msg_reply != NULL)
1129 if (ioctl_send_msg(msg_reply) != 0) {
1130 error_code = ERR_UNKNOWN;
1131 LOGE("ioclt send error\n");
1135 case NMSG_SWAP_INST_REMOVE:
1136 if (msg_swap_inst_remove(&msg_control, &prof_session.user_space_inst,
1137 &msg_reply, &error_code) != 0) {
1138 LOGE("swap inst remove\n");
1139 error_code = ERR_UNKNOWN;
1142 if (msg_reply != NULL) {
1143 if (ioctl_send_msg(msg_reply) != 0)
1144 error_code = ERR_UNKNOWN;
1146 error_code = ERR_UNKNOWN;
1149 case NMSG_GET_TARGET_INFO:
1150 fill_target_info(&target_info);
1151 msg_reply = gen_target_info_reply(&target_info);
1153 LOGE("cannot generate reply message\n");
1154 sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1157 if (send_reply(msg_reply) != 0) {
1158 LOGE("Cannot send reply\n");
1161 reset_target_info(&target_info);
1163 case NMSG_GET_SCREENSHOT:
1164 return process_msg_get_screenshot(&msg_control);
1166 LOGE("unknown message %d <0x%08X>\n", msg->id, msg->id);
1172 sendACKToHost(msg->id, error_code, 0, 0);
1173 if (msg_reply != NULL)
1175 return (error_code == ERR_NO);
1180 static void print_app_info(struct app_info_t *app_info)
1182 LOGI("application info=\n");
1183 LOGI("\tapp_type=<%d><0x%04X>\n"
1185 "\texe_path=<%s>\n",
1193 static void print_conf(struct conf_t *conf)
1196 memset(&buf[0], 0, 1024);
1197 feature_code_str(conf->use_features0, conf->use_features1, buf);
1199 LOGI("\tuse_features = 0x%016LX : 0x%016LX \n(\t%s)\n",
1200 conf->use_features0, conf->use_features1, buf);
1202 "\tsystem_trace_period = %d ms\n"
1203 "\tdata message period = %d ms\n",
1204 conf->system_trace_period,
1205 conf->data_message_period
1209 void print_replay_event(struct replay_event_t *ev, uint32_t num, char *tab)
1211 LOGW("%s\t#%04d:time=0x%08X %08X, "
1217 (unsigned int)ev->ev.time.tv_sec,//timeval
1218 (unsigned int)ev->ev.time.tv_usec,//timeval
1226 void print_replay_event_seq(struct replay_event_seq_t *event_seq)
1231 LOGI( "%senabled=0x%08X; "\
1232 "time_start=0x%08X %08X; "\
1234 tab,event_seq->enabled,
1235 (unsigned int)event_seq->tv.tv_sec,
1236 (unsigned int)event_seq->tv.tv_usec,
1237 event_seq->event_num);
1238 for (i=0;i<event_seq->event_num;i++)
1239 print_replay_event(&event_seq->events[i], i+1, tab);