blob: f48280bb4e42a2706ca77e9ddd68a7e30429d9db [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*******************************************************************************
2* °æÈ¨ËùÓÐ (C)2016, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
3*
4* ÎļþÃû³Æ: ramdump.c
5* Îļþ±êʶ: ramdump.c
6* ÄÚÈÝÕªÒª: ramdump linuxµ¼³ö¹¤¾ß
7*
8* ÐÞ¸ÄÈÕÆÚ °æ±¾ºÅ Ð޸ıê¼Ç ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ
9* ------------------------------------------------------------------------------
10* 2016/3/10 V1.0 Create ´´½¨
11*
12*******************************************************************************/
13
14/*******************************************************************************
15* Í·Îļþ *
16*******************************************************************************/
17#include<stdlib.h>
18#include<stdio.h>
19#include<string.h>
20#include<sys/types.h>
21#include<sys/stat.h>
22#include<fcntl.h>
23#include<errno.h>
24#include<getopt.h>
25#include<stdarg.h>
26#include<termios.h>
27#include<stddef.h>
28#include<dirent.h>
29#include <unistd.h>
30#include<time.h>
31//#include<properties.h>
32//#include<cutils/properties.h>
33//#include<cutils/log.h>
34
35/*******************************************************************************
36* ³£Á¿¶¨Òå *
37*******************************************************************************/
38
39/*******************************************************************************
40* ºê¶¨Òå *
41*******************************************************************************/
42#define MODEM_TRAP_PATH "/dev/ttyUSB0"
43#define MODEM_TRAP_PATH2 "/dev/ttyUSB1"
44// #define MODEM_RAMDUMP_PATH "/data/local/log/Ramdump"
45#define RAMDUMP_DEFAULT_BAUD B115200
46#define RAMDUMP_DEFAULT_DELAY 1000
47#define USB_DIR_FILE_NAME_SIZE 1024
48#define LOG_TAG "Modem_Ramdump"
49#define USB_DIR_BASE "/sys/bus/usb/devices"
50#define USB_PID 0x0197
51#define SUCCESS 0
52#define FAIL -1
53
54//#define printf(...) ALOGE(__VA_ARGS__)
55
56/*Ramdump Ö¸ÁÒå*/
57#define DUMPFILE_LINK_REQ (UINT32)1 //ͬ²½ÇëÇó
58#define DUMPFILE_LINK_RSP (UINT32)2 //ͬ²½ÇëÇóÓ¦´ð£¬¸½´øramdumpÎļþÊýÄ¿
59#define DUMPFILE_FILE_REQ (UINT32)3 //ÇëÇóÖ¸¶¨±àºÅÎļþÐÅÏ¢
60#define DUMPFILE_FILE_RSP (UINT32)4 //Îļþ±àºÅÎļþÐÅÏ¢Ó¦´ð£¬¸½´ø´«ÊäÎļþÃû¼°´óС
61#define DUMPFILE_READ_REQ (UINT32)5 //ÇëÇó¶Áȡָ¶¨±àºÅÎļþÄÚÈÝ
62#define DUMPFILE_READ_RSP (UINT32)6 //ÎļþÄÚÈݶÁȡӦ´ð£¬¸½´øÎļþÄÚÈÝ
63#define DUMPFILE_END_REQ (UINT32)7 //´«Êä½áÊø
64#define DUMPFILE_END_RSP (UINT32)8 //´«Êä½áÊøÓ¦´ð
65#define DUMPFILE_CMD_FAIL (UINT32)9 //Ö¸Áî´íÈ¥
66#define DUMPFILE_NO_FAIL (UINT32)10 //Îļþ±àºÅ´íÎó
67#define DUMPFILE_LENGTH_FAIL (UINT32)11 //ÎļþλÖôóС´íÎó
68#define CMD_BUFFER_LEN (UINT32)16 //Ö¸Áî²Á·À¶¾
69#define FILENAME_LEN (UINT32)32 //ÎļþÃû³¤¶È
70#define FILENAME_MAX_LEN (UINT32)256 //ÎļþÃû×î´ó³¤¶È
71#define DATA_BLOCK_SIZE (0x40000) // Êý¾Ý»º³å´óС
72//#define DATA_BLOCK_SIZE (0x00800) // Êý¾Ý»º³å´óС,2k
73
74#define MIN(a, b) ((a)< (b) ? (a): (b))
75#define DEFAULT_RAMDUMP_FOLD "/home/dujing/code/v3/ramdump/ramdump_file/" //"/mnt/sdcard/ramdump"
76
77//#define ZTE_LOG_PATH "/home/dujing/code/v3/ramdump/zte_file"
78#define CPLOG_PATH "persist.service.ztelog.path"
79//#define CPLOG_TIMESTAMP_DIR "persist.service.ztelog.timedir"
80#define __FUNCTION__ "ramdumpfuc"
81/*******************************************************************************
82* Êý¾ÝÀàÐͶ¨Òå *
83*******************************************************************************/
84typedef struct {
85 char file_name[32];
86 unsigned int file_size;
87} file_info_t;
88typedef unsigned int UINT32;
89
90/*******************************************************************************
91* º¯ÊýÉùÃ÷ *
92*******************************************************************************/
93extern int dev_get_usbsys_val(const char *sys_filename, int base);
94extern int dev_strStartsWith(const char *line, const char *src);
95extern int dev_get_ttyport_by_syspath(char *syspath);
96extern int dev_get_device(void);
97
98/*******************************************************************************
99* ¾Ö²¿¾²Ì¬±äÁ¿¶¨Òå *
100*******************************************************************************/
101static int g_modem_fd = -1;
102static int g_reboot_flag = 0;
103static int g_moniter_time = 0;
104
105/*******************************************************************************
106* È«¾Ö±äÁ¿¶¨Òå *
107*******************************************************************************/
108int PROPERTY_VALUE_MAX = 256;
109extern int g_usb_dev;
110/*******************************************************************************
111* ¾Ö²¿º¯ÊýʵÏÖ *
112*******************************************************************************/
113static void mdp_print_array(const char* prefix, const char *buf, int length)
114{
115#if 0
116 int i = 0;
117 int len = MIN(length,16 );
118 printf("%s ", prefix );
119 for (i = 0; i< len; i++) {
120 printf("%02X ", buf[i]);
121 }
122 if (length > len)
123 printf("...");
124 printf("\n");
125#endif
126}
127
128static int tty_write(int fd, const char *buf, int size)
129{
130 int ret = 0;
131 int repeat_count = 0;
132WRITE:
133 ret = write(fd, buf, size);
134 if (0 == ret) {
135 printf("%s error: %s\n", __FUNCTION__, strerror(errno));
136 repeat_count += 1;
137 if (3 > repeat_count) {
138 sleep(1);
139 goto WRITE;
140 }
141 }
142 if (ret != size) {
143 printf("%s failed, size=%d, ret=%d\n", __FUNCTION__, size, ret);
144 return -1;
145 }
146 return 0;
147}
148
149static int tty_read(int fd, char *buf, int size, unsigned int delay_ms)
150{
151 int ret = -1;
152 int read_count = 0;
153 fd_set fds;
154 int repeat_count = 0;
155 struct timeval tv;
156 if (buf == NULL)
157 return -1;
158 tv.tv_sec = delay_ms / 1000;
159 tv.tv_usec = (delay_ms % 1000) * 1000;
160 FD_ZERO(&fds);//Çå¿Õfd_set¼¯ºÏ
161 FD_SET(fd, &fds);//½«¸ø¶¨µÄÃèÊö·ûfd¼ÓÈ뼯ºÏµ±ÖÐ
162READ:
163 ret = select(fd + 1, &fds, NULL, NULL, &tv);
164 if (ret > 0) {
165 read_count = read(fd, buf, size);
166 if (read_count <= 0) {
167 printf("%s read failed for ret=%d\n", __FUNCTION__, read_count);
168 return -1;
169 }
170 return read_count;
171 } else if (ret == 0) {
172 printf("%s select time out %dms\n", __FUNCTION__, delay_ms);
173 printf("%s timeout error: %s\n", __FUNCTION__, strerror(errno));
174 if (3 > repeat_count) {
175 repeat_count += 1;
176 sleep(1);
177 goto READ;
178 }
179 } else {
180 printf("%s select failed %s\n", __FUNCTION__, strerror(errno));
181 }
182 return -1;
183}
184
185static int mdp_send(const char *buf, int size)
186{
187 mdp_print_array(__FUNCTION__, buf, size);
188 return tty_write(g_modem_fd, buf, size);
189}
190
191static int mdp_receive(char *buf, int size)
192{
193 int count = 0;
194 int ret = 0;
195 int length = size;
196 char *pbuffer = buf;
197 while (length > 0) {
198 count = tty_read(g_modem_fd, pbuffer, size, RAMDUMP_DEFAULT_DELAY);
199 if (count < 0) {
200 return -1;
201 }
202 pbuffer += count;
203 length -= count;
204 }
205 mdp_print_array(__FUNCTION__, buf, size);
206 return size;
207}
208
209static int mdp_send_command(unsigned int cmd, unsigned int argc, ...)
210{
211 char buffer[CMD_BUFFER_LEN] = {0};
212 unsigned int i = 0;
213 unsigned int arg = 0;
214 UINT32 *pbuffer = (UINT32*)buffer;
215 *pbuffer = cmd;
216 va_list ap;
217 va_start(ap, argc);
218 for (i=0; i<argc; i++) {
219 arg = va_arg(ap, unsigned int);
220 *(++pbuffer) = arg;
221 }
222 va_end(ap);
223 return mdp_send(buffer, CMD_BUFFER_LEN);
224}
225
226static int mdp_receive_ack(unsigned int ack)
227{
228 int ret = 0;
229 unsigned int resp;
230 char buffer[64] = {0};
231 ret = mdp_receive((char *)&resp, sizeof(unsigned int));
232// ret = mdp_receive(buffer, 64);
233 if (ret > 0) {
234// resp = *(unsigned int*)buffer;
235 if (ack == resp)
236 return 0;
237 }
238 return -1;
239}
240
241static int init_devices(char* dev_path, speed_t speed)
242{
243 int fd = -1;
244 struct termios tios;
245 printf("%s\n", __FUNCTION__);
246 fd = open(dev_path, O_RDWR);
247 if (fd < 0) {
248 printf("Can't open %s(%s)\n", dev_path, strerror(errno));
249 return -1;
250 }
251 if (tcgetattr(fd, &tios) < 0) {
252 printf(" tcgetattr failed(%s)\n", strerror(errno));
253 return -1;
254 }
255 tios.c_cflag = CS8 | CREAD | CRTSCTS | CLOCAL;
256 tios.c_iflag = IGNPAR;
257 tios.c_oflag = 0;
258 tios.c_lflag = 0;
259 tios.c_cc[VTIME] = 0;
260 tios.c_cc[VMIN] = 1;
261 cfsetispeed(&tios, RAMDUMP_DEFAULT_BAUD);
262 cfsetospeed(&tios, RAMDUMP_DEFAULT_BAUD);
263 tcflush(fd, TCIFLUSH);
264 if (tcsetattr(fd,TCSANOW, &tios) < 0) {
265 printf(" tcgetattr failed(%s)\n", strerror(errno));
266 return -1;
267 }
268 return fd;
269}
270
271static int create_fold(char *fold)
272{
273 char buffer[256]= {0};
274 snprintf(buffer, 256, "mkdir -p %s\n", fold);
275 int ret = system(buffer);
276 if (ret < 0)
277 return -1;
278 return 0;
279}
280
281static int create_file(char* fold, char * path)
282{
283 int fd = -1;
284 DIR *pdir = NULL;
285 char file_name[FILENAME_MAX_LEN] = {0};
286 int ret = 0;
287 if ((fold==NULL) || (*fold=='\0'))
288 fold = DEFAULT_RAMDUMP_FOLD;
289 if ( (path==NULL) || (*path=='\0')) {
290 printf("%s path=NULL\n", __FUNCTION__);
291 return -1;
292 }
293 if ((pdir = opendir(fold)) == NULL) {
294 ret = create_fold(fold);
295 if (ret < 0) {
296 printf("%s create fold %s failed (%s)", __FUNCTION__, fold, strerror(errno));
297 return -1;
298 }
299 }
300 if (pdir != NULL)
301 closedir(pdir);
302 snprintf(file_name, FILENAME_MAX_LEN, "%s/%s", fold, path);
303 unlink(file_name);
304 printf("%s %s\n", __FUNCTION__, file_name);
305 fd = open(file_name, O_CREAT| O_RDWR, 0777);
306 if (fd < 0) {
307 printf("failed to create %s (%s)\n", path, strerror(errno));
308 }
309 return fd;
310}
311
312static int write_to_file(int fd, char*buffer, int size)
313{
314 int ret = 0;
315 if ((fd < 0) || (buffer==NULL) || (size<=0))
316 return -1;
317 ret = write(fd, buffer, size);
318 if (ret < size) {
319 printf("write to file failed, ret=%d, size=%d\n", ret, size);
320 return -1;
321 }
322 return 0;
323
324}
325
326static int dump_file(int index, char *fold)
327{
328 int ret = 0;
329 char path[256] = {0};
330 char cmd_buffer[CMD_BUFFER_LEN] = {0};
331 file_info_t file_info = {{0}, 0};
332 char data_buffer[DATA_BLOCK_SIZE] = {0};
333 int fd = 0;
334 int file_size, read_count, file_offset;
335
336 if ((ret = mdp_send_command(DUMPFILE_FILE_REQ, 1, index)) < 0) {
337 printf("%s failed to send command DUMPFILE_FILE_REQ\n", __FUNCTION__);
338 return -1;
339 }
340 if ((ret = mdp_receive_ack(DUMPFILE_FILE_RSP)) < 0) {
341 printf("%s failed to receive DUMPFILE_FILE_RSP\n", __FUNCTION__);
342 return -1;
343 }
344 if ((ret = mdp_receive((char*)&file_info, sizeof(file_info))) < 0) {
345 printf("%s failed to get fileinfo\n", __FUNCTION__);
346 return -1;
347 }
348 if ((fd = create_file(fold, file_info.file_name)) < 0) {
349 printf("failed to create file %s\n", file_info.file_name);
350 return -1;
351 }
352 printf("filename=%s\t size=%d\n", file_info.file_name, file_info.file_size);
353 file_size = file_info.file_size;
354 file_offset = read_count = 0;
355 while (file_size > 0) {
356 read_count = MIN(file_size, DATA_BLOCK_SIZE);
357 if (mdp_send_command(DUMPFILE_READ_REQ, 3, index, file_offset, read_count) < 0) {
358 printf("%s failed to send DUMPFILE_READ_REQ\n", __FUNCTION__);
359 ret = -1;
360 goto exit;
361 }
362 if (mdp_receive_ack(DUMPFILE_READ_RSP) < 0) {
363 printf("%s failed to receive ack DUMPFILE_READ_RSP\n", __FUNCTION__);
364 ret = -1;
365 goto exit;
366 }
367 if (mdp_receive(data_buffer, read_count) < 0) {
368 printf("failed to read file data\n");
369 ret = -1;
370 goto exit;
371 }
372 if (write_to_file(fd, data_buffer, read_count)< 0) {
373 printf("failed to write file data\n");
374 ret = -1;
375 goto exit;
376 }
377 file_offset += read_count;
378 file_size -= read_count;
379 }
380 ret = 0;
381exit:
382 close(fd);
383 return ret;;
384}
385
386static int do_modem_ramdump( char* tty, char*path)
387{
388 int ret = -1;
389 int file_number = 0;
390 int i = 0;
391
392 g_modem_fd = init_devices(tty, RAMDUMP_DEFAULT_BAUD);
393 if (g_modem_fd < 0) {
394 printf("failed to open %s\n", tty);
395 return -1;
396 }
397 if ((ret = mdp_send_command(DUMPFILE_LINK_REQ, 0)) < 0) {
398 printf("Send DUMPFILE_LINK_REQ failed\n");
399 ret = -1;
400 goto exit;
401 }
402 if ((ret = mdp_receive_ack(DUMPFILE_LINK_RSP)) < 0) {
403 printf("failed to receive DUMPFILE_LINK_RSP\n");
404 ret = -1;
405 goto exit;
406 }
407 ret = mdp_receive((char*)&file_number, sizeof(unsigned int));
408 if (ret < 0) {
409 printf("failed to get filenumber\n");
410 ret = -1;
411 goto exit;
412 }
413 printf("file_number = %d\n", file_number);
414 for (i = 0; i < file_number; i++) {
415 printf("dump file index=%d \n", i);
416 ret = dump_file(i, path);
417 if (ret < 0) {
418 printf("dump file index=%d failed\n", i);
419 ret = -1;
420 goto exit;
421 }
422 printf("dump file index=%d success\n", i);
423 }
424 if (g_reboot_flag == 1){
425 printf("ramdump except reboot enabled\n");
426 if ((ret = mdp_send_command(DUMPFILE_END_REQ, 0)) < 0) {
427 printf("failed to send DUMPFILE_END_REQ\n");
428 ret = -1;
429 goto exit;
430 }
431 mdp_receive_ack(DUMPFILE_END_RSP);
432 }
433 ret = 0;
434exit:
435 if (g_modem_fd > 0)
436 close(g_modem_fd);
437 return ret;
438}
439
440void broadcast_ramdump_result(int success)
441{
442 char command[256];
443 snprintf(command, 256, "am broadcast -a zte.com.cn.intent_modemramdump_finished --ez extra_success %s", (success == 0 ? "true" : "false"));//Android·¢Ë͹㲥ָÁî
444 printf("%s %s\n", __FUNCTION__, command);
445 system(command);
446}
447
448static void compress_and_rm_fold(char *pfold, char *time_str)
449{
450 char buffer[512] = {0};
451 int ret = 0;
452
453 //sunjy add
454 //delete duplicate file which preffix is g_current_file_index;
455 snprintf(buffer, 512, "cd %s; busybox rm -rvf %s\n", pfold, "*.tgz");
456 printf("%s %s\n", __FUNCTION__, buffer);
457 system(buffer);
458
459 char preffix[256] = {0};
460 char str[256] = {0};
461 strcat(preffix, time_str);
462 strcpy(time_str, preffix);
463
464 printf("%s %s %s\n", __FUNCTION__, pfold, time_str);
465 snprintf(buffer, 512, "cd %s; busybox tar -zcf %s.tgz %s/*\n", pfold, time_str, time_str);
466 printf("%s %s\n", __FUNCTION__, buffer);
467 ret = system(buffer);
468 if(ret != 0){
469 printf("compress failed, delete the unfinished compressed file\n");
470 snprintf(buffer, 512, "cd %s; busybox rm -rf %s.tgz \n", pfold, time_str);
471 }else {
472 printf("compress finished, delete the source fold\n");
473 snprintf(buffer, 512, "cd %s; busybox rm -rf %s\n", pfold, time_str);
474 // property_set("persist.service.ramdump.index", str); (ºóÐø´ò¿ª£©
475
476 // property_get("persist.service.ramdump.index", str, "6"); OPEN LATER
477 //printf("%s %s %s\n", __FUNCTION__, "persist.service.ramdump.index=", str);
478 }
479 printf("%s %s\n", __FUNCTION__, buffer);
480 system(buffer);
481}
482
483static int get_time_str(char *buf, size_t size)
484{
485 struct tm cur_tm;
486 time_t now = time(NULL);
487 if (NULL==buf || size<=0)
488 return -1;
489 localtime_r(&now, &cur_tm);
490 strftime(buf, size, "%Y_%m%d_%H%M%S", &cur_tm);
491 printf("%s %s\n", __FUNCTION__, buf);
492 return 0;
493}
494
495static int get_ramdump_fold_name(char *ramdump_path, size_t size, char *prefix, char *time_buffer)
496{
497 if (ramdump_path == NULL || size <= 0 || time_buffer == NULL)
498 return -1;
499 //sunjy add
500 //modify path,like "sdcard0/GoTaLog/Ramdump/index.yyyymmdd_hhmmss"
501 //char logTime[30] = {0};
502 //property_get(CPLOG_PATH, ramdump_path, ZTE_LOG_PATH);
503
504 strcat(ramdump_path, prefix);
505 strcat(ramdump_path, "/");
506 strcat(ramdump_path, time_buffer);
507
508 //snprintf(ramdump_path, size, "%s/%s", prefix, time_buffer);
509 printf("%s %s\n", __FUNCTION__, ramdump_path);
510 return 0;
511}
512
513static int ramdump_export(char *dump_path)
514{
515 int ret = -1;
516 int i;
517 char dev_tty[256] = {0};
518
519 for (i = 0; i <= 255; i++) {
520 snprintf(dev_tty, 256, "/dev/ttyUSB%d", i);
521 if (access(dev_tty, F_OK) < 0){
522 continue;
523 }
524 printf("try to get the ramdump data from %s\n", dev_tty);
525 ret = do_modem_ramdump(dev_tty, dump_path);
526 if (ret >= 0) {
527 printf("get the ramdump data from %s success\n", dev_tty);
528 //compress_and_rm_fold(DEFAULT_RAMDUMP_FOLD, time_str);
529 break;
530 } else if (ret == -1) {
531 printf("try to repeat do_modem_ramdump begin\n");
532 ret = do_modem_ramdump(dev_tty, dump_path);
533 if (ret >= 0) {
534 printf("get the ramdump data from %s success\n", dev_tty);
535 //compress_and_rm_fold(DEFAULT_RAMDUMP_FOLD, time_str);
536 break;
537 }else{
538 printf("get the ramdump data from %s failed\n", dev_tty);
539 }
540 }
541 }
542 return ret;
543}
544
545static int ramdump_mainloop(int moniter_time, char *dump_path)
546{
547 int ret = -1;
548 char dev_tty[256] = {0};
549
550 while(1)
551 {
552 if ((ret == -1) && (moniter_time >= 0))
553 sleep(moniter_time);
554 else
555 break;
556 ret = dev_get_device();
557 }
558 if (g_usb_dev < 0)
559 return -1;
560
561 snprintf(dev_tty, 256, "/dev/ttyUSB%d", g_usb_dev);
562 ret = do_modem_ramdump(dev_tty, dump_path);
563 if (ret >= 0) {
564 printf("get the ramdump data from %s success\n", dev_tty);
565 } else if (ret == -1) {
566 printf("try to repeat do_modem_ramdump begin\n");
567 ret = do_modem_ramdump(dev_tty, dump_path);
568 if (ret >= 0) {
569 printf("get the ramdump data from %s success\n", dev_tty);
570 }else{
571 printf("get the ramdump data from %s failed\n", dev_tty);
572 }
573 }
574 return ret;
575}
576
577/*******************************************************************************
578* È«¾Öº¯ÊýʵÏÖ *
579*******************************************************************************/
580int main(int argc, char* argv[])
581{
582 int ret = -1;
583 int opt = 0;
584 int dump_path_flag = 0;
585 char dump_path[256] = {0};
586 char time_str[64] = {0};
587
588 // property_set("ctl.stop", "ztemodemlog");
589 //sleep(1);
590 if(get_time_str(time_str, 64) < 0){
591 printf("Can't get the time str\n");
592 return -1;
593 }
594
595 if (argc == 1){
596 get_ramdump_fold_name(dump_path, 256, DEFAULT_RAMDUMP_FOLD, time_str);
597 dump_path_flag = 1;
598 ret = ramdump_export(dump_path);
599 return ret;
600 }
601 ret = -1;
602 while((opt = getopt(argc, argv, ":p:rt:m")) != -1){
603 switch(opt){
604 case 'p':
605 {
606 ret = get_ramdump_fold_name(dump_path, 256, optarg, time_str);
607 dump_path_flag = 1;
608 if (ret < 0) {
609 printf("Can't get the ramdump fold path\n");
610 return -1;
611 }
612 break;
613 }
614 case 'r':
615 {
616 g_reboot_flag = 1;
617 break;
618 }
619 case 't':
620 {
621 g_moniter_time = atoi(optarg);
622 }
623 case 'm':
624 {
625 printf("begin to monitor ramdump!\n");
626 if (dump_path_flag == 0){
627 get_ramdump_fold_name(dump_path, 256, DEFAULT_RAMDUMP_FOLD, time_str);
628 dump_path_flag = 1;
629 }
630 ret = ramdump_mainloop(g_moniter_time, dump_path);
631 return ret;
632 }
633 case '?':
634 printf("invailed arguments!\n");
635 return -1;
636 }
637 }
638 if (dump_path_flag == 0){
639 get_ramdump_fold_name(dump_path, 256, DEFAULT_RAMDUMP_FOLD, time_str);
640 dump_path_flag = 1;
641 }
642 ret = ramdump_export(dump_path);
643 return ret;
644}
645