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"
57 static pthread_mutex_t stop_all_mutex = PTHREAD_MUTEX_INITIALIZER;
59 static void inline free_msg(struct msg_t *msg)
64 struct prof_session_t prof_session;
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);
82 check_and_return(NMSG_GET_PROCESS_ADD_INFO);
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);
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);
110 static char *msgErrStr(enum ErrorCode err)
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)";
143 return "unknown error";
148 #define print_feature(f,in,to,delim) \
150 if (strlen(dstr(f) delim) + 1 < buflen ) { \
151 lenin = snprintf(to, buflen, dstr(f) delim ); \
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,
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);
199 LOGE("Not enought mem to print\n");
206 static inline uint32_t get_avail_msg_size(struct msg_buf_t *msg)
208 return (uint32_t)(msg->end - msg->cur_pos);
211 static inline uint32_t get_msg_cur_size(struct msg_buf_t *msg)
213 return (uint32_t) (msg->cur_pos - msg->payload);
216 int parse_string(struct msg_buf_t *msg, char **str)
218 parse_deb("size = %d\n", get_avail_msg_size(msg));
219 int len = strlen(msg->cur_pos) + 1;
221 if (get_avail_msg_size(msg) < len)
224 *str = strdup(msg->cur_pos);
225 parse_deb("<%s>\n", *str);
230 static const char* parse_string_inplace(struct msg_buf_t *msg)
232 const char *str = msg->cur_pos;
233 int avail_size = get_avail_msg_size(msg);
234 int len = strnlen(str, avail_size);
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.
241 if (len == avail_size)
244 msg->cur_pos += len + 1;
248 int parse_string_no_alloc(struct msg_buf_t *msg, char *str)
250 parse_deb("size = %d\n", get_avail_msg_size(msg));
251 int len = strlen(msg->cur_pos) + 1;
253 if (get_avail_msg_size(msg) < len)
256 memcpy(str, msg->cur_pos, len);
257 parse_deb("<%s>\n", str);
262 int parse_int8(struct msg_buf_t *msg, uint8_t *val)
264 parse_deb("size = %d\n", get_avail_msg_size(msg));
265 if (get_avail_msg_size(msg) < sizeof(*val))
267 *val = *(uint8_t *)msg->cur_pos;
268 msg->cur_pos += sizeof(uint8_t);
270 parse_deb("<%d><0x%08X>\n", *val, *val);
276 int parse_int32(struct msg_buf_t *msg, uint32_t *val)
278 parse_deb("size = %d\n", get_avail_msg_size(msg));
279 if (get_avail_msg_size(msg) < sizeof(*val))
281 *val = *(uint32_t *)msg->cur_pos;
282 msg->cur_pos += sizeof(uint32_t);
285 parse_deb("<%d><0x%08X>\n", *val, *val);
290 int parse_int64(struct msg_buf_t *msg, uint64_t *val)
292 parse_deb("size = %d\n", get_avail_msg_size(msg));
293 if (get_avail_msg_size(msg) < sizeof(*val))
296 *val = *(uint64_t *)msg->cur_pos;
298 parse_deb("<%llu><0x%016llX>\n", *val, *val);
299 msg->cur_pos += sizeof(uint64_t);
303 static int parse_conf(struct msg_buf_t *msg, struct conf_t *conf)
306 parse_deb("parse_conf\n");
307 if (!parse_int64(msg, &conf->use_features0)) {
308 LOGE("use features0 error\n");
312 if (!parse_int64(msg, &conf->use_features1)) {
313 LOGE("use features1 parsing error\n");
316 //Check features value
317 if (!check_conf_features(conf->use_features0, conf->use_features1)) {
318 LOGE("check features fail\n");
322 if (!parse_int32( msg, &conf->system_trace_period) ||
323 !check_conf_systrace_period(conf->system_trace_period))
325 LOGE("system trace period error\n");
329 if (!parse_int32( msg, &conf->data_message_period) ||
330 !check_conf_datamsg_period(conf->data_message_period))
332 LOGE("data message period error\n");
339 //REPLAY EVENTS PARSE
340 static int parse_timeval(struct msg_buf_t *msg, struct timeval *tv)
346 if (!parse_int32(msg, (uint32_t *)&tv->tv_sec)) {
347 LOGE("sec parsing error\n");
351 if (!parse_int32(msg, &nsec)) {
352 LOGE("usec parsing error\n");
355 tv->tv_usec = nsec / 1000;
360 static int parse_replay_event(struct msg_buf_t *msg,
361 struct replay_event_t *re)
365 if (!parse_timeval(msg, &re->ev.time)) {
366 LOGE("time parsing error\n");
370 if (!parse_int32(msg, &re->id)) {
371 LOGE("id parsing error\n");
375 /* FIXME ev.type, ev.code should be uint16_t */
376 if (!parse_int32(msg, &dummy)) {
377 LOGE("type parsing error\n");
380 re->ev.type = (uint16_t)dummy;
382 if (!parse_int32(msg, &dummy)) {
383 LOGE("code parsing error\n");
386 re->ev.code = (uint16_t)dummy;
388 if (!parse_int32(msg, (uint32_t *)&re->ev.value)) {
389 LOGE("value parsing error\n");
396 void reset_replay_event_seq(struct replay_event_seq_t *res)
399 res->tv = (struct timeval){0, 0};
400 if (res->event_num != 0)
405 int parse_replay_event_seq(struct msg_buf_t *msg,
406 struct replay_event_seq_t *res)
409 parse_deb("REPLAY\n");
410 if (!parse_int32(msg, &res->enabled)) {
411 LOGE("enabled parsing error\n");
415 if(res->enabled == 0) {
416 parse_deb("disable\n");
420 parse_deb("time main\n");
421 if (!parse_timeval(msg, &res->tv)) {
422 LOGE("time parsing error\n");
426 parse_deb("count\n");
427 if (!parse_int32(msg, &res->event_num)) {
428 LOGE("event num parsing error\n");
431 parse_deb("events num=%d\n", res->event_num);
433 LOGI("Replay events: count = %u; total_size = %u\n",
434 res->event_num, res->event_num * sizeof(*res->events));
436 res->events = (struct replay_event_t *)malloc(res->event_num *
437 sizeof(*res->events));
439 LOGE("events alloc error\n");
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);
456 //*REPLAY EVENT PARSE
458 static int parse_msg_config(struct msg_buf_t *msg_payload,
461 if (!parse_conf(msg_payload, conf)) {
462 LOGE("conf parsing error\n");
470 static void init_parse_control(struct msg_buf_t *buf, struct msg_t *msg)
472 buf->payload = msg->payload;
474 buf->end = msg->payload + msg->len;
475 buf->cur_pos = msg->payload;
478 static void reset_target_info(struct target_info_t *target_info)
483 static void running_status_on(struct prof_session_t *prof_session)
485 prof_session->running_status = 1;
488 static void running_status_off(struct prof_session_t *prof_session)
490 prof_session->running_status = 0;
493 int check_running_status(const struct prof_session_t *prof_session)
495 return prof_session->running_status;
498 static void reset_app_inst(struct user_space_inst_t *us_inst)
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;
505 void reset_system_info(struct system_info_t *sys_info)
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));
514 void init_prof_session(struct prof_session_t *prof_session)
516 memset(prof_session, 0, sizeof(*prof_session));
519 static size_t str_array_getsize(const char **strings, size_t len)
522 * Calculate about of memory to place array
523 * of \0 delimited strings
527 for (index = 0; index != len; ++index)
528 size += strlen(strings[index]) + 1;
533 static struct msg_t *gen_target_info_reply(struct target_info_t *target_info)
537 uint32_t ret_id = ERR_NO;
539 msg = malloc(sizeof(*msg) +
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));
548 LOGE("Cannot alloc target info msg\n");
553 msg->id = NMSG_GET_TARGET_INFO_ACK;
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);
570 msg->len = p - msg->payload;
575 static int send_reply(struct msg_t *msg)
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);
588 static void write_msg_error(const char *err_str)
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);
596 static enum HostMessageT get_ack_msg_id(const enum HostMessageT id)
599 case NMSG_KEEP_ALIVE:
600 return NMSG_KEEP_ALIVE_ACK;
602 return NMSG_START_ACK;
604 return NMSG_STOP_ACK;
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;
618 LOGE("Fatal: unknown message ID [0x%X]\n", id);
623 int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
624 char *payload, int payload_size)
626 if (manager.host.control_socket != -1) {
628 uint32_t err = err_code;
629 int loglen = sizeof(*msg) - sizeof(msg->payload) +
630 sizeof(err) + //return ID
632 msg = malloc(loglen);
633 char *p = msg->payload;
635 resp = get_ack_msg_id(resp);
640 msg->len = payload_size + sizeof(err);
644 memcpy(p, payload, payload_size);
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);
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);
663 static struct msg_t *gen_stop_msg(void)
665 struct msg_t *res = malloc(sizeof(*res));
666 memset(res, 0, sizeof(*res));
673 enum ErrorCode stop_all_no_lock(void)
675 enum ErrorCode error_code = ERR_NO;
678 // stop all only if it has not been called yet
679 if (check_running_status(&prof_session)) {
680 msg = gen_stop_msg();
686 LOGE("cannot generate stop message\n");
687 error_code = ERR_UNKNOWN;
690 if (ioctl_send_msg(msg) != 0) {
691 LOGE("ioctl send failed\n");
692 error_code = ERR_UNKNOWN;
699 // we reset only app inst no lib no confing reset
700 reset_app_inst(&prof_session.user_space_inst);
702 running_status_off(&prof_session);
704 LOGI("already stopped\n");
707 LOGI("finished: ret = %d\n", error_code);
711 int stop_all_in_process(void)
713 return (pthread_mutex_trylock(&stop_all_mutex) != 0);
716 void stop_all_done(void)
718 pthread_mutex_unlock(&stop_all_mutex);
721 static void stop_web_apps(void)
723 const struct app_info_t *app_info;
724 struct app_list_t *app = NULL;
726 app_info = app_info_get_first(&app);
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);
734 enum ErrorCode stop_all(void)
736 enum ErrorCode error_code = ERR_NO;
740 pthread_mutex_lock(&stop_all_mutex);
741 error_code = stop_all_no_lock();
742 pthread_mutex_unlock(&stop_all_mutex);
750 md5_byte_t digest[16];
753 static void binary_ack_free(struct binary_ack *ba)
760 static size_t binary_ack_size(const struct binary_ack *ba)
762 /* MD5 is 16 bytes, so 16*2 hex digits */
763 return sizeof(uint32_t) + strlen(ba->binpath) + 1
767 static size_t binary_ack_pack(char *s, const struct binary_ack *ba)
769 unsigned int len = strlen(ba->binpath) + 1;
771 *(uint32_t *) s = ba->type;
772 s += sizeof(uint32_t);
775 memcpy(s, ba->binpath, len);
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
782 snprintf(s, 3, "%02x", ba->digest[i]);
787 return sizeof(uint32_t) + len + 2*16 + 1;
790 static void get_file_md5sum(md5_byte_t digest[16], const char *filename)
792 md5_byte_t buffer[1024];
794 md5_state_t md5_state;
795 int fd = open(filename, O_RDONLY);
797 md5_init(&md5_state);
799 while ((size = read(fd, buffer, sizeof(buffer))) > 0)
800 md5_append(&md5_state, buffer, size);
803 LOGW("File does not exists <%s>\n", filename);
806 md5_finish(&md5_state, digest);
809 static const char* basename(const char *filename)
811 const char *p = strrchr(filename, '/');
812 return p ? p + 1 : NULL;
816 * Checks whether it is Windows-style path or not.
818 * @return 1 if path is Windows-style one, 0 otherwise.
820 static int check_windows_path(const char *path)
825 if (len > 3 && isalpha(path[0]) && !(strncmp(&(path[1]), ":\\", 2)))
831 static struct binary_ack* binary_ack_alloc(const char *filename)
833 struct binary_ack *ba = malloc(sizeof(*ba));
835 char builddir[PATH_MAX];
836 char binpath[PATH_MAX];
841 if (stat(filename, &decoy) == 0) {
842 ba->type = get_binary_type(filename);
844 if (ba->type != BINARY_TYPE_UNKNOWN)
845 get_build_dir(builddir, filename);
847 if (builddir[0] != '\0')
848 snprintf(binpath, sizeof(binpath), check_windows_path(builddir) ?
849 "%s\\%s" : "%s/%s", builddir, basename(filename) ?: "");
851 ba->binpath = strdup(binpath);
852 get_file_md5sum(ba->digest, filename);
854 ba->type = BINARY_TYPE_FILE_NOT_EXIST;
855 ba->binpath = strdup(filename);
856 memset(ba->digest, 0x00, sizeof(ba->digest));
862 static int process_msg_binary_info(struct msg_buf_t *msg)
864 uint32_t i, bincount;
865 enum ErrorCode error_code = ERR_NO;
867 printBuf(msg->cur_pos, msg->len);
869 if (!parse_int32(msg, &bincount)) {
870 LOGE("MSG_BINARY_INFO error: No binaries count\n");
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);
880 LOGE("MSG_BINARY_INFO error: No enough binaries\n");
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);
893 if (new->binpath[0] == '\0')
894 LOGW("section '.debug_str' not found in <%s>\n", str);
896 total_size += binary_ack_size(new);
898 typedef uint32_t return_id;
899 typedef uint32_t binary_ack_count;
900 struct msg_t *msg_reply = malloc(sizeof(struct msg_t)
902 + sizeof(binary_ack_count)
904 char *p = msg_reply->payload;
906 msg_reply->id = NMSG_BINARY_INFO_ACK;
907 msg_reply->len = total_size + sizeof(return_id)
908 + sizeof(binary_ack_count);
910 pack_int32(p, error_code);
911 pack_int32(p, bincount);
913 for (i = 0; i != bincount; ++i) {
914 p += binary_ack_pack(p, acks[i]);
915 binary_ack_free(acks[i]);
918 printBuf(msg_reply, msg_reply->len + sizeof(*msg_reply));
919 int err = send_reply(msg_reply);
924 static void get_serialized_time(uint32_t dst[2])
927 gettimeofday(&tv, NULL);
929 dst[1] = tv.tv_usec * 1000;
932 static int process_msg_start(struct msg_buf_t *msg_control)
934 enum ErrorCode err_code = ERR_CANNOT_START_PROFILING;
935 struct msg_t *msg_reply = NULL;
936 uint32_t serialized_time[2];
938 //get start profiling time
939 get_serialized_time(serialized_time);
941 if (check_running_status(&prof_session) == 1) {
942 LOGW("Profiling has already been started\n");
943 err_code = ERR_ALREADY_RUNNING;
947 if (!check_conf(&prof_session.conf)) {
948 LOGE("wrong profile config\n");
952 if (msg_start(msg_control, &prof_session.user_space_inst,
953 &msg_reply, &err_code) != 0) {
954 LOGE("parse error\n");
958 if (prepare_profiling() != 0) {
959 LOGE("failed to prepare profiling\n");
963 if (start_transfer() != 0) {
964 LOGE("Cannot start transfer\n");
968 //get time right before ioctl for more accurate start time value
969 get_serialized_time(serialized_time);
971 if (ioctl_send_msg(msg_reply) != 0) {
972 LOGE("cannot send message to device\n");
976 running_status_on(&prof_session);
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");
989 sendACKToHost(NMSG_START, err_code, (void *)&serialized_time,
990 sizeof(serialized_time));
991 if (msg_reply != NULL)
993 return -(err_code != ERR_NO);
996 int send_msg_to_sock(int sock, struct msg_target_t *msg)
1002 n = sizeof(struct _msg_target_t) + msg->length;
1003 ret = send(sock, msg, n, MSG_NOSIGNAL);
1005 LOGE("fail to send data to socket(%d) n=%u, ret=%d\n",
1013 int recv_msg_from_sock(int sock, struct msg_target_t *msg)
1017 ret = recv(sock, msg, MSG_HEADER_LEN, MSG_WAITALL);
1018 if (ret != MSG_HEADER_LEN)
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;
1025 ret = recv(sock, (char *)msg_data + MSG_HEADER_LEN,
1030 /* TODO: check msg_data->len */
1031 ret = recv(sock, msg_data->payload,
1032 msg_data->len, MSG_WAITALL);
1034 if (ret != msg_data->len)
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)
1050 static int process_msg_get_screenshot(struct msg_buf_t *msg_control)
1053 struct msg_target_t sendlog;
1054 enum ErrorCode err_code = ERR_UNKNOWN;
1056 // send config message to target process
1057 sendlog.type = MSG_CAPTURE_SCREEN;
1059 log_len = sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length;
1061 if (target_send_msg_to_all(&sendlog) == 1)
1064 return -(err_code != ERR_NO);
1067 static char *get_process_cmd_line(uint32_t pid)
1069 char buf[MAX_FILENAME];
1073 snprintf(buf, sizeof(buf), "/proc/%u/cmdline", pid);
1074 f = open(buf, O_RDONLY);
1076 count = read(f, buf, sizeof(buf));
1077 if (count >= sizeof(buf))
1078 count = sizeof(buf) - 1;
1082 LOGE("file not found <%s>\n", buf);
1088 static int process_msg_get_process_add_info(struct msg_buf_t *msg)
1090 uint32_t i, count, total_len;
1091 uint32_t *pidarr = NULL;
1092 char **cmd_line_arr = NULL;
1094 struct msg_target_t sendlog;
1095 enum ErrorCode err_code = ERR_UNKNOWN;
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;
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);
1111 if (cmd_line_arr == NULL) {
1112 LOGE("can not alloc cmd line array (%u)", count);
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);
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;
1130 payload = malloc(total_len);
1131 if (payload == NULL)
1133 /* pack payload data */
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]);
1152 sendACKToHost(NMSG_GET_PROCESS_ADD_INFO, err_code, payload, total_len);
1155 if (payload != NULL) {
1160 if (pidarr != NULL) {
1165 if (cmd_line_arr != NULL) {
1167 cmd_line_arr = NULL;
1170 return -(err_code != ERR_NO);
1173 int host_message_handler(struct msg_t *msg)
1175 struct target_info_t target_info;
1176 struct msg_t *msg_reply = NULL;
1177 struct msg_buf_t msg_control;
1179 enum ErrorCode error_code = ERR_NO;
1182 struct msg_target_t sendlog;
1184 LOGI("MY HANDLE %s (%X)\n", msg_ID_str(msg->id), msg->id);
1185 init_parse_control(&msg_control, msg);
1188 case NMSG_KEEP_ALIVE:
1189 sendACKToHost(msg->id, ERR_NO, 0, 0);
1192 return process_msg_start(&msg_control);
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");
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);
1207 if (reconfigure(conf) != 0) {
1208 LOGE("Cannot change configuration\n");
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;
1220 feature0 &= ~FL_SYSTEM_ENERGY;
1221 feature0 &= ~FL_SYSTEM_ENERGY_OLD;
1223 *((uint64_t *)msg->payload) = feature0;
1225 if (ioctl_send_msg(msg) != 0) {
1226 LOGE("ioctl send error\n");
1227 sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
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),
1236 (unsigned long long)
1237 prof_session.conf.use_features0) + 1;
1238 target_send_msg_to_all(&sendlog);
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");
1248 if (msg_reply != NULL)
1249 if (ioctl_send_msg(msg_reply) != 0) {
1250 error_code = ERR_UNKNOWN;
1251 LOGE("ioclt send error\n");
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;
1262 if (msg_reply != NULL) {
1263 if (ioctl_send_msg(msg_reply) != 0)
1264 error_code = ERR_UNKNOWN;
1266 error_code = ERR_UNKNOWN;
1269 case NMSG_GET_TARGET_INFO:
1270 fill_target_info(&target_info);
1271 msg_reply = gen_target_info_reply(&target_info);
1273 LOGE("cannot generate reply message\n");
1274 sendACKToHost(msg->id, ERR_UNKNOWN, 0, 0);
1277 if (send_reply(msg_reply) != 0) {
1278 LOGE("Cannot send reply\n");
1281 reset_target_info(&target_info);
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);
1288 LOGE("unknown message %d <0x%08X>\n", msg->id, msg->id);
1289 error_code = ERR_WRONG_MESSAGE_TYPE;
1296 sendACKToHost(msg->id, error_code, 0, 0);
1297 if (msg_reply != NULL)
1299 return (error_code == ERR_NO);
1304 static void print_conf(struct conf_t *conf)
1307 memset(&buf[0], 0, 1024);
1308 feature_code_str(conf->use_features0, conf->use_features1, buf, sizeof(buf));
1310 LOGI("\tuse_features = 0x%016LX : 0x%016LX \n(\t%s)\n",
1311 conf->use_features0, conf->use_features1, buf);
1313 "\tsystem_trace_period = %d ms\n"
1314 "\tdata message period = %d ms\n",
1315 conf->system_trace_period,
1316 conf->data_message_period
1320 void print_replay_event(struct replay_event_t *ev, uint32_t num, char *tab)
1322 LOGW("%s\t#%04d:time=0x%08X %08X, "
1328 (unsigned int)ev->ev.time.tv_sec,//timeval
1329 (unsigned int)ev->ev.time.tv_usec,//timeval