blob: 0e9c52b0377f82cc1c12991eff87271ee6f3e1d9 [file] [log] [blame]
/**
*
* @file cp_ramdump.c
* @brief
* This file is part of ZCAT.
* zcatÓ¦Óòãlog_agent´¦Àícp_ramdumpÉ豸
*
* @details
* @author Tools Team.
* @email
* @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
* @warning
* @date 2019/02/02
* @version 1.1
* @pre
* @post
*
* @par
* Change History :
* ---------------------------------------------------------------------------
* date version author description
* ---------------------------------------------------------------------------
* 2017/07/17 1.0 hou.bing Create file
* 2019/02/02 1.1 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
* ---------------------------------------------------------------------------
*
*
*/
#if 0
#include "log_agent.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <getopt.h>
#include <stdarg.h>
#include <termios.h>
#include <stddef.h>
#include <dirent.h>
#include <time.h>
#include <pthread.h>
/**
* Êý¾Ý½á¹¹¶¨Òå
*/
typedef struct {
char file_name[32];
unsigned int file_size;
} file_info_t;
/**
* È«¾Ö±äÁ¿ºÍºê¶¨Òå
*/
#define LOG_TAG "Modem_Ramdump"
#define ZTE_LOG_PATH "/mnt/sdcard/ZTELog"
#define RAMDUMP_LOG_PATH "/mnt/sdcard/ZTELog/Ramdump"
#define DEFAULT_RAMDUMP_PATH "/sdcard/ZTELog/ramdump"
#define USB_RAMDUMP_FLAG_FILE_NAME "/sys/dwc_usb/usbconfig/ramdumpFlag"
// #define MODEM_RAMDUMP_PATH "/data/local/log/Ramdump"
pthread_t get_ramdump_thread = 0;
//typedef unsigned int UINT32;
int ramdump_fd = -1;
#define RAMDUMP_DEFAULT_DELAY 10000
#define MAX_AP_LOG_BUFF_LEN 8192
/*Ramdump Ö¸ÁÒå*/
#define DUMPFILE_LINK_REQ (UINT32)1 //ͬ²½ÇëÇó
#define DUMPFILE_LINK_RSP (UINT32)2 //ͬ²½ÇëÇóÓ¦´ð£¬¸½´øramdumpÎļþÊýÄ¿
#define DUMPFILE_FILE_REQ (UINT32)3 //ÇëÇóÖ¸¶¨±àºÅÎļþÐÅÏ¢
#define DUMPFILE_FILE_RSP (UINT32)4 //Îļþ±àºÅÎļþÐÅÏ¢Ó¦´ð£¬¸½´ø´«ÊäÎļþÃû¼°´óС
#define DUMPFILE_READ_REQ (UINT32)5 //ÇëÇó¶Áȡָ¶¨±àºÅÎļþÄÚÈÝ
#define DUMPFILE_READ_RSP (UINT32)6 //ÎļþÄÚÈݶÁȡӦ´ð£¬¸½´øÎļþÄÚÈÝ
#define DUMPFILE_END_REQ (UINT32)7 //´«Êä½áÊø
#define DUMPFILE_END_RSP (UINT32)8 //´«Êä½áÊøÓ¦´ð
#define DUMPFILE_CMD_FAIL (UINT32)9 //Ö¸Áî´íÎó
#define DUMPFILE_NO_FAIL (UINT32)10 //Îļþ±àºÅ´íÎó
#define DUMPFILE_LENGTH_FAIL (UINT32)11 //ÎļþλÖôóС´íÎó
#define CMD_BUFFER_LEN (UINT32)16 //Ö¸Áî²Á·À¶¾
#define FILENAME_LEN (UINT32)32 //ÎļþÃû³¤¶È
#define FILENAME_MAX_LEN (UINT32)256 //ÎļþÃû×î´ó³¤¶È
//#define DATA_BLOCK_SIZE (0x40000) // Êý¾Ý»º³å´óС
#define DATA_BLOCK_SIZE (0x01000) // Êý¾Ý»º³å´óС
#define MIN(a, b) ((a)< (b) ? (a): (b))
static char g_ramdump_datablock_buffer[DATA_BLOCK_SIZE] = {0};
//static T_LOG_SDCARD_PARA g_ramdump_sdcard_para = { {0} };
static char* g_ramdump_path = NULL;
static int g_modem_fd = -1;
/*É豸·¾¶*/
static char* ramdump_dev="/dev/ramdump";
static char* usb_ramdump_dev="/dev/ttyGS0";
BOOL g_cp_trap_flag = TRUE;
BOOL g_cpcrash_flag = FALSE;
BOOL g_trap_flag = TRUE;
int usb_ramdump_dev_fd = -1;
pthread_t usb_ramdump_dev_thread = -1;
/**
* Íⲿ±äÁ¿ºÍº¯ÊýÒýÓÃ
*/
extern int ramdump_fd;
extern E_ZCAT_MODE g_log_dir;
extern unsigned int zTools_SendData(unsigned char *buf, unsigned int buf_len,unsigned char tgt_mdl_no, unsigned char tgt_submdl_no, unsigned char src_submdl_no);
extern int filelength(FILE *fp);
extern BOOL zCatAgt_Ap_ReadBuffer(T_AP_SRC_BUFFER_TYPE *src, T_AP_DEST_BUFFER_TYPE *dest);
extern int test_dir_exist(char* dir_path);
/**
* º¯ÊýʵÏÖ
*/
BOOL get_cp_crash_flag()
{
return g_cpcrash_flag;
}
#if 0
static char * zte_time()
{
time_t timep;
struct tm *p;
static char buf[22];
memset(buf,0,22);
time(&timep);
p =localtime(&timep);
snprintf(buf,21,"%4d/%02d/%02d %02d:%02d:%02d ",1900 + p->tm_year,1 + p->tm_mon,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
return buf;
}
#endif
static int writefile(char*path, char*buf, unsigned len)
{
FILE *fp;
int rtv;
if((fp=fopen(path,"w"))==NULL)
{
printf("open file %s error.\n",path);
return -1;
}
rtv = fwrite(buf,len,1, fp);
fclose(fp);
return rtv;
}
static int readfile(char *path, char* buf, unsigned len)
{
FILE *fp;
int length;
if((fp=fopen(path,"r"))==NULL)
{
printf("open file %s error.\n",path);
return -1;
}
length = filelength(fp);
length = length > len? len: length;
//ch=(char *)malloc(length+1);
fread(buf,length,1,fp);
fclose(fp);
*(buf+length)='\0';
return length;
}
BOOL get_trap_flag_from_dev()
{
int ramdumpFlag = 0;
char buf[2]={0};
readfile(USB_RAMDUMP_FLAG_FILE_NAME, buf, 1);
ramdumpFlag = atoi(buf);
printf("ramdumpFlag : %d \n", ramdumpFlag);
if(ramdumpFlag == 0){
printf("usb normal \n");
}else{
printf("usb ramdump \n");
}
if(ramdumpFlag == 1)
{
return TRUE;
}
return FALSE;
}
int send_ramdump_to_trap(unsigned char *buf, int read_len)
{
int write_len = -1;
while(usb_ramdump_dev_fd == -1)
{
sleep(1);
printf("hb ramdump test\n");
}
write_len = write(usb_ramdump_dev_fd, buf, read_len);
if (write_len != read_len)
{
printf("modem_log, send_rule error, write_len = %d, len = %d. \n", write_len, read_len);
return -1;
}
return 0;
}
static unsigned char gReadApplogBuffer[1024*130] = {0};
/**********************************************************************************
*º¯Êý˵Ã÷:´ÓramdumpÉ豸¶ÁÈ¡Êý¾Ý
***********************************************************************************/
void *get_ramdump_from_dev(void *arg)
//void *get_ramdump_from_dev(int fd)
{
int read_len = -1;
printf("get_ramdump_from_dev * p_fd %d \n", ramdump_fd);
while(1)
{
read_len = read(ramdump_fd, gReadApplogBuffer, sizeof(gReadApplogBuffer));
if(read_len>0)
{
if(g_log_dir == ZCAT_MODE_AP_USB)
{
if(g_cp_trap_flag)
{
writefile(USB_RAMDUMP_FLAG_FILE_NAME, "1", 1);
printf("get_ramdump_from_dev: writefile");
}
else
{
send_ramdump_to_trap(gReadApplogBuffer, read_len);
printf("get_ramdump_from_dev: send_ramdump_to_trap");
}
}
else if(g_log_dir == ZCAT_MODE_AP_NET)
{
g_cpcrash_flag = TRUE;
T_AP_DEST_BUFFER_TYPE dest = {0};
T_AP_SRC_BUFFER_TYPE src = {0};
src.buf = gReadApplogBuffer;
src.beginIndex=0;
src.bufSize = sizeof(gReadApplogBuffer);
while (zCatAgt_Ap_ReadBuffer(&src , &dest))
{
unsigned char *p = dest.buf;
unsigned short len = dest.len;
//if(g_log_dir == ZCAT_MODE_AP_NET)
{
//»¥³â???
zTools_SendData(p, len, MDL_ZCAT, 1, SUBMDL_ZCATAGT);
}
memset(&dest, 0, sizeof(T_AP_DEST_BUFFER_TYPE));
}
}
else
{
printf("get_ramdump_from_dev g_log_dir error \n");
}
}
else
{
sleep(1);
//printf("get_ramdump_from_dev: sleep1");
}
}
return NULL;
}
//³õʼ»¯ramdump logÉ豸
int init_ramdump_log_device()
{
int ret_ramdump;
int fd;
fd = open(ramdump_dev, O_RDWR);
printf("init_ramdump_log_device fd %d \n", fd);
if (fd < 0)
{
printf("open ramdump_dev error!!!\n");
return -1;
}
ramdump_fd = fd;
ret_ramdump = pthread_create(&get_ramdump_thread, NULL, get_ramdump_from_dev, NULL);
if(ret_ramdump!=0)
{
printf("pthread_create getramdump_thread error\n");
return -1;
}
return fd;
}
static int tty_write(int fd, const char* buf, int size)
{
int ret = 0;
ret = write(fd, buf, size);
if (ret != size) {
printf("%s failed, size=%d, ret=%d\n", __FUNCTION__, size, ret);
return -1;
}
return 0;
}
static int tty_read(int fd, char*buf, int size ,unsigned int delay_ms)
{
int ret = -1;
int read_count = 0;
fd_set fds;
struct timeval tv;
if (buf == NULL)
return -1;
tv.tv_sec = delay_ms/1000;
tv.tv_usec = (delay_ms%1000) *1000;
FD_ZERO(&fds);
FD_SET(fd, &fds);
ret = select(fd +1, &fds, NULL, NULL, &tv);
if (ret > 0) {
read_count = read(fd, buf, size);
if (read_count <= 0) {
printf("%s read %d failed for ret=%d\n" , __FUNCTION__, read_count, ret);
return -1;
}
return read_count;
} else if (ret == 0) {
printf("select time out %dms\n" , delay_ms);
} else {
printf("select failed %s\n" , strerror(errno));
}
return -1;
}
static int mdp_send(const char*buf, int size)
{
//mdp_print_array(,buf, size);
return tty_write(g_modem_fd, buf,size);
}
static int mdp_receive(char *buf, int size)
{
int count = 0;
int length = size;
char *pbuffer = buf;
while ( length > 0) {
count = tty_read(g_modem_fd, pbuffer,size, RAMDUMP_DEFAULT_DELAY);
if (count < 0) {
return -1;
}
pbuffer += count;
length -= count;
}
//mdp_print_array(, buf, size);
return size;
}
static int mdp_send_command(unsigned int cmd, unsigned int argc,...)
{
char buffer[CMD_BUFFER_LEN] = {0};
unsigned int i = 0;
unsigned int arg = 0;
UINT32 *pbuffer = (UINT32*)buffer;
*pbuffer = cmd;
va_list ap;
va_start(ap, argc);
for (i=0; i<argc; i++) {
arg = va_arg(ap, unsigned int);
*(++pbuffer) = arg;
}
va_end(ap);
return mdp_send(buffer, CMD_BUFFER_LEN);
}
static int mdp_receive_ack(unsigned int ack)
{
int ret = 0;
unsigned int resp;
//char buffer[64] = {0};
ret = mdp_receive((char *)&resp, sizeof(unsigned int));
if (ret > 0) {
if (ack == resp)
return 0;
}
return -1;
}
static int init_devices(char* dev_path)
{
int fd = -1;
fd = open(dev_path, O_RDWR);
if (fd < 0) {
printf("Can't open %s(%s)\n", dev_path, strerror(errno));
return -1;
}
return fd;
}
static int create_fold(char *fold)
{
char buffer[256]= {0};
snprintf(buffer, 256, "mkdir -p %s\n", fold);
int ret = system(buffer);
if (ret < 0)
return -1;
return 0;
}
static int create_file(char* fold, char * path)
{
int fd = -1;
DIR* pdir = NULL;
char file_name[FILENAME_MAX_LEN] = {0};
int ret = 0;
if ((fold==NULL) || (*fold=='\0'))
fold = g_ramdump_path;
if ( (path==NULL) || (*path=='\0')) {
return -1;
}
if ((pdir = opendir(fold)) == NULL) {
ret = create_fold(fold);
if (ret < 0) {
printf("%s create fold %d failed (%s)", fold, errno, strerror(errno));
return -1;
}
}
if (pdir != NULL)
closedir(pdir);
snprintf(file_name, FILENAME_MAX_LEN, "%s/%s", fold, path);
unlink(file_name);
printf("%s\n" , file_name);
fd = open(file_name, O_CREAT| O_RDWR, 0777);
if (fd < 0) {
printf("failed to create %s (%s)\n", path, strerror(errno));
}
return fd;
}
static int write_to_file(int fd, char *buffer, int size)
{
int ret = 0;
if ((fd < 0) || (buffer==NULL) || (size<=0))
return -1;
ret = write(fd, buffer, size);
if (ret < size) {
printf("write to file failed, ret=%d, size=%d\n", ret, size);
return -1;
}
return 0;
}
static int mdp_receive_ack_and_info(int cmd, void *receive_info, int receive_size)
{
int ret = -1;
char* buffer = NULL;
int rsp = -1;
buffer = malloc(receive_size + sizeof(rsp));
if(buffer == NULL)
goto exit;
ret = mdp_receive(buffer, receive_size + sizeof(rsp));
if (ret < sizeof(rsp) + receive_size) {
printf("failed to mdp_receive_ack_and_info\n");
goto exit;
}
memcpy(&rsp, buffer, sizeof(rsp));
if (rsp != cmd) {
printf("failed to receive cmd:%d\n", cmd);
goto exit;
}
memcpy(receive_info, buffer + sizeof(rsp), receive_size);
exit:
free(buffer);
ret = 0;
return ret;
}
//»ñÈ¡µÚindex¸öramdumpÎļþ²¢Ð´Èët¿¨
static int dump_file(int index, char *fold)
{
int ret = 0;
//char path[256] = {0};
//char cmd_buffer[CMD_BUFFER_LEN] = {0};
file_info_t file_info = {{0}, 0};
int fd = 0;
int file_size , read_count, file_offset;
ret = mdp_send_command(DUMPFILE_FILE_REQ, 1, index);
if (ret < 0) {
return -1;
}
ret = mdp_receive_ack_and_info(DUMPFILE_FILE_RSP, (void*)(&file_info), sizeof(file_info));
/*
if (ret < 0) {
return -1;
}*/
fd = create_file(fold, file_info.file_name);
if (fd < 0) {
printf("failed to create file %s\n", file_info.file_name);
return -1;
}
printf("filename=%s\t size=%d\n", file_info.file_name, file_info.file_size);
file_size = file_info.file_size;
file_offset = read_count = 0;
while (file_size > 0) {
read_count = MIN(file_size, DATA_BLOCK_SIZE);
if (mdp_send_command(DUMPFILE_READ_REQ, 3, index, file_offset, read_count) < 0) {
ret = -1;
goto exit;
}
if (mdp_receive_ack(DUMPFILE_READ_RSP) < 0) {
ret = -1;
goto exit;
}
if (mdp_receive(g_ramdump_datablock_buffer, read_count) < 0) {
printf("failed to read file data\n");
ret = -1;
goto exit;
}
if (write_to_file(fd, g_ramdump_datablock_buffer, read_count)< 0) {
printf("failed to write file data\n");
ret = -1;
goto exit;
}
file_offset += read_count;
file_size -= read_count;
}
ret = 0;
exit:
close(fd);
return ret;;
}
static int do_modem_ramdump( char* tty, char*path)
{
int ret = -1;
int file_number = 0;
int i = 0;
int read_count = 0;
char read_buf[5] = {0};
g_modem_fd = init_devices(tty);
if (g_modem_fd < 0) {
printf("failed to open %s\n", tty);
return -1;
}
read_count = read(g_modem_fd, read_buf, sizeof(read_buf));
if (0 >= read_count )
{
printf("read_count %d\n", read_count);
goto exit;
}
ret = mdp_send_command(DUMPFILE_LINK_REQ, 0);
if (ret < 0) {
printf("Send DUMPFILE_LINK_REQ failed\n");
ret = -1;
goto exit;
}
ret = mdp_receive_ack_and_info(DUMPFILE_LINK_RSP, &file_number, sizeof(file_number));
/*
if (ret < 0) {
printf("mdp_receive_ack_and_filenum failed\n");
ret = -1;
goto exit;
}
*/
printf("file_number = %d\n", file_number);
for (i=0; i<file_number; i++) {
printf("dump file index=%d ...\n", i);
ret = dump_file(i, path);
if (ret < 0) {
printf("dump file index=%d failed\n", i);
ret = -1;
goto exit;
}
printf("dump file index=%d success\n", i);
}
ret = mdp_send_command(DUMPFILE_END_REQ, 0);
if (ret < 0) {
printf("failed to send DUMPFILE_END_REQ\n");
ret = -1;
goto exit;
}
mdp_receive_ack(DUMPFILE_END_RSP);
ret = 0;
exit:
if (g_modem_fd > 0)
close(g_modem_fd);
return ret;
}
void broadcast_ramdump_result(int success)
{
char command[256];
sprintf(command, "am broadcast -a zte.com.cn.intent_modemramdump_finished --ez extra_success %s", (success == 0 ? "true" : "false"));
printf("%s\n" , command);
system(command);
}
#if 0
static void compress_and_rm_fold(char *pfold, char *time_str)
{
char buffer[512] = {0};
int ret = 0;
printf("%s %s %s\n", pfold, time_str);
snprintf(buffer, 512, "cd %s;tar -zcf %s.tgz %s/*\n", pfold, time_str, time_str);
printf("%s %s\n" , buffer);
ret = system(buffer);
if(ret != 0){
printf("compress failed, delete the unfinished compressed file\n");
snprintf(buffer, 512, "cd %s;rm -rvf %s.tgz \n", pfold, time_str);
}else {
printf("compress finished, delete the source fold\n");
snprintf(buffer, 512, "cd %s; rm -rvf %s\n", pfold, time_str);
}
printf("%s %s\n", buffer);
system(buffer);
}
#endif
static int get_time_str(char*buf, size_t size)
{
struct tm cur_tm;
time_t now = time(NULL);
if (NULL==buf || size<=0)
return -1;
localtime_r(&now, &cur_tm);
strftime(buf, size, "%Y_%m%d_%H%M%S", &cur_tm);
printf("%s\n", buf);
return 0;
}
static int get_ramdump_fold_name(char*ramdump_path, size_t size, char *time_buffer)
{
if (ramdump_path==NULL || size<=0 || time_buffer==NULL)
{
return -1;
}
snprintf(ramdump_path, size, "%s/%s", g_ramdump_path, time_buffer);
printf("ramdump_path: %s\n", ramdump_path);
return 0;
}
/***********************************************************************************
º¯Êý˵Ã÷£ºramdump²Ù×÷Ïß³Ì
Êä È룺
Êä ³ö£º
·µ »Ø Öµ£º
Æä Ëû£º
***********************************************************************************/
static void* ramdump_entry(void *arg)
{
int ret = -1;
char dev_tty[256] = {0};
char dump_path[256] = {0};
char time_str[64] = {0};
// property_set("ctl.stop", "ztemodemlog");
/*
if(get_time_str(time_str, 64) < 0){
printf("Can't get the time str\n");
return NULL;
}
*/
get_time_str(time_str, 64);
ret = get_ramdump_fold_name(dump_path, 256, time_str);
/*
if (ret < 0) {
printf("Can't get the ramdump fold path\n");
return NULL;
} */
memcpy(dev_tty, ramdump_dev, 256);
printf("try to get the ramdump data from %s\n", ramdump_dev);
ret = do_modem_ramdump(ramdump_dev,dump_path);
#if 0//for test
if (ret >= 0)
{
printf("get the ramdump data from %s success\n", dev_tty);
compress_and_rm_fold(dump_path, time_str);
}
else
{
printf("get the ramdump data from %s failed\n", dev_tty);
}
#endif
return NULL;
}
static void init_output_flash_mode()
{
if(test_dir_exist(DEFAULT_RAMDUMP_PATH) < 0)
{
printf("test_dir_exist failed:%s. \n", DEFAULT_RAMDUMP_PATH);
return;
}
g_ramdump_path = DEFAULT_RAMDUMP_PATH;
}
static int init_output_u_mode()
{
if(test_dir_exist(ZTE_LOG_PATH) < 0)//ÅжϸùĿ¼
{
printf("test_dir_exist failed:%s. \n", ZTE_LOG_PATH);
return -1;
}
if(test_dir_exist(RAMDUMP_LOG_PATH) < 0)//ÅжÏramdumpÈÕ־Ŀ¼ÊÇ·ñ´æÔÚ
{
printf("test_dir_exist failed:%s. \n", RAMDUMP_LOG_PATH);
return -1;
}
g_ramdump_path = RAMDUMP_LOG_PATH;
return 0;
}
int init_ramdump_output_dir(E_FLASH_MODE mode)
{
int ret = -1;
pthread_t ramdump_thread = -1;
if(mode == FLASH_MODE_NOMAL)
{
init_output_flash_mode();
}
else if(mode == FLASH_MODE_U)
{
init_output_u_mode();
}
else
{
return -1;
}
ret = pthread_create(&ramdump_thread, NULL, ramdump_entry, NULL);
return ret;
}
static int send_ramdump_rules_to_cp(char *buf, int read_len)
{
int write_len = write(ramdump_fd, buf, read_len);
if (write_len != read_len)
{
printf("modem_log, send_rule error, write_len = %d, len = %d. \n", write_len, read_len);
return -1;
}
return 0;
}
void *get_rule_from_ramdump_dev(void* args)
{
char *pbuf = NULL;
int read_len = 0;
pbuf = (char *)malloc(8*1024);
if(pbuf == NULL)
{
return NULL;
}
while(1)
{
read_len = read(usb_ramdump_dev_fd, pbuf, 8*1024);
if(read_len > 0)
{
//send_rules_to_ramdump(pbuf, read_len);//Ïòramdump·¢Ë͹æÔò
send_ramdump_rules_to_cp(pbuf, read_len);
}
else
{
sleep(2);
}
}
return NULL;
}
static void* init_usb_trap_device(void* args)
{
int ret_ramdump = -1;
int fd = -1;
while(TRUE)
{
//ret_ramdump = close(usb_ramdump_dev);
fd = open(usb_ramdump_dev, O_RDWR);
if (fd < 0)
{
sleep(1);
printf("usb_ramdump_dev open fail\n");
}
else
{
printf("usb_ramdump_dev open success\n");
break;
}
}
usb_ramdump_dev_fd = fd;
ret_ramdump=pthread_create(&usb_ramdump_dev_thread, NULL, get_rule_from_ramdump_dev, NULL);
if(ret_ramdump != 0)
{
printf("pthread_create cp_interact_thread error\n");
}
return NULL;
}
int init_ramdump_device()
{
int ret = -1;
pthread_t trap_dev_thread = -1;
ret=pthread_create(&trap_dev_thread, NULL, init_usb_trap_device, NULL);
if(ret != 0)
{
printf("pthread_create init_ramdump_device error\n");
return -1;
}
g_cp_trap_flag = FALSE;
return ret;
}
int ramdump_trap_rev_close(VOID)
{
int ret = -1;
ret = close(usb_ramdump_dev_fd);
if (ret < 0)
{
printf("open devtty GS0 error!!!\n");
return -1;
}
usb_ramdump_dev_fd = -1;
return ret;
}
#endif