blob: a5ec0f228dd1770db9587df9f898fabaed6cc4fb [file] [log] [blame]
/**
*
* @file log_agent_tool.c
* @brief
* This file is part of ZCAT.
* zcatÓ¦Óòãlog_agent´¦ÀíÊý¾ÝÔ´µÄ°ïÖúº¯Êý
*
* @details
* @author Tools Team.
* @email
* @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
* @warning
* @date 2019/02/02
* @version 1.2
* @pre
* @post
*
* @par
* Change History :
* ---------------------------------------------------------------------------
* date version author description
* ---------------------------------------------------------------------------
* 2017/07/17 1.0 hou.bing Create file
* 2019/01/24 1.1 jiang.fenglin 1.Ìí¼Óusblog¶ÁÐ´Ëø
* 2.Ìí¼ÓÏß³ÌÃû³Æ
* 2019/02/02 1.2 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
* 2019/07/08 1.3 jiang.fenglin Ôö¼ÓAPFS/CPFSģʽ
* ---------------------------------------------------------------------------
*
*
*/
/**
* Í·Îļþ°üº¬
*/
#include <string.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include "log_agent.h"
#define MAX_PACKET_LEN (0x10000)
#define MAX_ENCODE_PACKET_LEN (MAX_PACKET_LEN * 2)
#define COMM_MDLNO_ZCAT_FLAG 115
#define COMM_MDLNO_RAMDUMP_FLAG 119
#define MAX_AP_LOG_BUFF_LEN 2048
extern E_ZCAT_MODE g_log_dir;
extern E_ZCAT_STATE g_log_state;
extern int send_message_to_client(unsigned char* buf, int len);
extern int send_message_to_usblog(unsigned char* buf, int len);
extern int send_message_to_sdcard(unsigned char* buf, int len);
extern int init_sdcard_log_dir(E_FLASH_MODE mode);
extern int init_fs_log_dir();
extern int zCat_MountSd();
extern BOOL hdlc_encode(T_HDLC_BUFFER_TYPE *dest, const T_HDLC_BUFFER_TYPE *src);
extern BOOL hdlc_decode(T_HDLC_BUFFER_TYPE *dest, T_HDLC_BUFFER_TYPE *src);
int deal_with_encoded_data(unsigned char* buffer, int buf_len);
int hb_flag = 0;
int bFirst = 1;
/*É豸¾ä±ú*/
extern int ramdump_fd;
extern int kernellog_fd;
extern int applog_fd;
extern int cplog_fd;
/*Ï̻߳¥³âËø*/
static pthread_mutex_t mutex_AP;
static pthread_mutex_t mutex_SD;
static T_HDLC_BUFFER_TYPE g_recvBuf = {0};
static unsigned int gCommEncodeBuffer[MAX_ENCODE_PACKET_LEN / 4] = {0};
static unsigned int gCommDecodeBuffer[MAX_ENCODE_PACKET_LEN / 4] = {0};
static unsigned int gCommRecvBuffer[MAX_ENCODE_PACKET_LEN / 4] = {0};
BOOL bSDSet = FALSE;
void init_log_agent_tools()
{
g_recvBuf.buf = (unsigned char *)gCommRecvBuffer;
g_recvBuf.bufIndex = 0;
g_recvBuf.bufSize = 0;
pthread_mutex_init(&mutex_AP, NULL);
pthread_mutex_init(&mutex_SD, NULL);
}
int g_cp_log_count = 0;
int g_ap_log_count = 0;
/**
* @brief ´òӡʱ¼äµÄ°ïÖúº¯Êý
* @param[in] void
* @return void
* @note
* @see
*/
char* zte_time()
{
time_t timep;
struct tm *p;
static char buf[22];
memset(buf, 0, 22);
time(&timep);
p =localtime(&timep);
if(p != NULL)
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;
}
/**
* @brief ½«¹æÔòÎļþ¡¢ÐÄÌø°üµÄÏÂÐÐÊý¾Ý·¢Ë͵½cp
* @param[in] buf ´ý·¢Ë͵ÄÊý¾ÝÖ¸Õë
* @param[in] len ´ý·¢Ë͵ÄÊý¾Ý³¤¶È
* @return ʵ¼Ê·¢Ë͵ÄÊý¾Ý³¤¶È
* @note
* @see
*/
int send_log_to_cp(unsigned char *buf, int len)
{
int write_len = 0;
if(buf == NULL || cplog_fd == -1)
{
printf("[zcat] send_log_to_cp fail\n");
return 0;
}
write_len = write(cplog_fd, buf, len);
return write_len;
}
/**
* @brief ¸ù¾Ýzcat_mode£¬·¢ËÍlogµ½²»Í¬µÄÍâÉ裺usb¡¢Íø¿¨¡¢sd¿¨
* @param[in] buf ´ý·¢Ë͵ÄÊý¾ÝÖ¸Õë
* @param[in] len ´ý·¢Ë͵ÄÊý¾Ý³¤¶È
* @return void
* @note
* @see
*/
void send_log_out(unsigned char* buf, int len)
{
if(g_log_state != ZCAT_STATE_RUNNING)
{
printf("[zcat] send_log_out fail, state = %d.\n", g_log_state);
return;
}
if(g_log_dir == ZCAT_MODE_AP_NET)
{
send_message_to_client(buf, len);
}
else if(g_log_dir == ZCAT_MODE_AP_USB)
{
int i;
int cnt = len / MAX_AP_LOG_BUFF_LEN;
for(i = 0; i < cnt; i++)
{
g_cp_log_count++;
send_message_to_usblog(buf + i * MAX_AP_LOG_BUFF_LEN, MAX_AP_LOG_BUFF_LEN);
}
cnt = len % MAX_AP_LOG_BUFF_LEN;
if(cnt > 0)
{
g_cp_log_count++;
send_message_to_usblog(buf + i * MAX_AP_LOG_BUFF_LEN, cnt);
}
}
else if(g_log_dir == ZCAT_MODE_AP_TF)
{
if(bSDSet == FALSE )
{
if(zCat_MountSd())
return;
bSDSet = TRUE;
if(init_sdcard_log_dir(FLASH_MODE_NOMAL) < 0) //³õʼ»¯cpÊä³öÎļþ¼Ð¼°²ÎÊý
{
bSDSet = FALSE;
return;
}
hb_flag = 1;
return;
}
if(bSDSet == TRUE)
{
pthread_mutex_lock(&mutex_SD);
send_message_to_sdcard(buf, len);
pthread_mutex_unlock(&mutex_SD);
}
}
else if(g_log_dir == ZCAT_MODE_AP_FS)
{
if(bSDSet == FALSE )
{
bSDSet = TRUE;
if(init_fs_log_dir() < 0) //³õʼ»¯cpÊä³öÎļþ¼Ð¼°²ÎÊý
{
bSDSet = FALSE;
return;
}
hb_flag = 1;
return;
}
if(bSDSet == TRUE)
{
pthread_mutex_lock(&mutex_SD);
send_message_to_sdcard(buf, len);
pthread_mutex_unlock(&mutex_SD);
}
}
else
{
deal_with_encoded_data(buf, len);
}
}
/**
* @brief ½«ap²àprintf¡¢printk²úÉúµÄlogÊý¾Ý·¢ËͳöÈ¥
* @param[in] commHeader ´ý·¢Ë͵ÄÊý¾Ý
* @return void
* @note
* @see
*/
static void send_ap_log_out(T_COMM_TYPE *commHeader)
{
T_HDLC_BUFFER_TYPE srcBuf = {0};
//T_ZCAT_HEADER *zcatHeader = (T_ZCAT_HEADER *)(((unsigned char*)commHeader) + sizeof(T_COMM_TYPE));
T_HDLC_BUFFER_TYPE destBuf = {(unsigned char *)gCommEncodeBuffer, 0, MAX_ENCODE_PACKET_LEN};
//int cmd_code = zcatHeader->cmd_code;
//UINT16 times = 0;
//UINT16 ipLast = 0;
srcBuf.buf = (unsigned char *)(commHeader);
srcBuf.bufIndex = 0;
srcBuf.bufSize = sizeof(T_COMM_TYPE) + commHeader->buf_len;
destBuf.bufIndex = 0;
if(g_log_state != ZCAT_STATE_RUNNING)
{
free((void*)commHeader);
return;
}
pthread_mutex_lock(&mutex_AP); // ¼Ó»¥³âËø£¬·Àֹͬʱ²Ù×÷gCommEncodeBuffer
if (hdlc_encode(&destBuf, &srcBuf)) // ±àÂë
{
if(g_log_dir == ZCAT_MODE_CP_USB || g_log_dir == ZCAT_MODE_CP_TF || g_log_dir == ZCAT_MODE_CP_FS)
{
send_log_to_cp(destBuf.buf, destBuf.bufIndex);
}
else
{
send_log_out(destBuf.buf, destBuf.bufIndex);
}
}
pthread_mutex_unlock(&mutex_AP); // ½â³ý»¥³âËø
free((void*)commHeader);
}
/**
* @brief ·¢ËÍÊý¾Ýµ½"ͳһ»º´æ"ÖÐ
* @param[in] buf ·¢ËÍÊý¾Ý(±ØÐëÊÇÓÉComm_MallocÉêÇëµÄÄÚ´æ!!!)
* @param[in] buf_len ·¢ËÍÊý¾ÝµÄ³¤¶È
* @param[in] tgt_mdl_no Ä¿±êÄ£¿éºÅ£¬ÊÖ»ú»òPCµÈ
* @param[in] tgt_submdl_no Ä¿±ê×ÓÄ£¿éºÅ
* @param[in] src_submdl_no Ô´×ÓÄ£¿éºÅ
* @return ³É¹¦·µ»ØZOSS_SUCCESS, ·ñÔò·µ»ØZOSS_ERROR
* @note
* @see
*/
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)
{
T_COMM_TYPE *commHeader = NULL;
/* Èë²ÎÅÐ¶Ï */
if (buf == NULL || buf_len == 0 || tgt_mdl_no == 0 || tgt_submdl_no == 0 || src_submdl_no == 0)
{
return -1;
}
commHeader = (T_COMM_TYPE *)(buf - sizeof(T_COMM_TYPE));
commHeader->msg_type = 1;
commHeader->pad = 0xAA;
commHeader->reserved = 0xAAAA;
commHeader->tgt_mdl_no = tgt_mdl_no; // Ä¿±êÄ£¿é
commHeader->tgt_submdl_no = tgt_submdl_no; // Ä¿±ê×ÓÄ£¿é
commHeader->src_mdl_no = MDL_PHONE; // Ô´Ä£¿é
commHeader->src_submdl_no = src_submdl_no; // Ô´×ÓÄ£¿é
commHeader->buf_len = buf_len; // Êý¾ÝÇø³¤¶È
send_ap_log_out(commHeader);
return 0;
}
/**
* @brief ZCATÏûϢͷ³õʼ»¯
* @param[out] zcatHeader ÏûϢͷָÕë
* @param[in] cmd_code ÏûÏ¢Âë
* @param[in] len ÏûÏ¢³¤¶È
* @return N/A
* @note
* @see
*/
VOID zCatAgt_HeaderInit(T_ZCAT_HEADER *zcatHeader, unsigned char cmd_code, unsigned int len)
{
struct timeval tmpTimeVal = {0};
zcatHeader->cmd_code = cmd_code;
zcatHeader->reserved = 0xBBBB;
zcatHeader->timeStamp[1] = 0;
zcatHeader->length = len;
zcatHeader->timeStamp[0] = 0;//corem»ñȡʱ¼ä
gettimeofday(&tmpTimeVal, NULL);
zcatHeader->timeStamp[1] = tmpTimeVal.tv_sec;
}
/**
* @brief ·¢ËÍZCATÏûÏ¢µ½"ÍâÉè"
* @param[in] cmd_code ÏûÏ¢Âë
* @param[in] buf ÏûÏ¢Êý¾ÝÖ¸Õë
* @param[in] len ÏûÏ¢Êý¾Ý³¤¶È
* @return ³É¹¦·µ»ØZOSS_SUCCESS, ·ñÔò·µ»ØZOSS_ERROR
* @note
* @see
*/
unsigned int zCatAgt_SendMsg(unsigned char cmd_code, unsigned char *buf, unsigned int len)
{
T_ZCAT_HEADER *zcatHeader = (T_ZCAT_HEADER *)(buf - sizeof(T_ZCAT_HEADER));
zCatAgt_HeaderInit(zcatHeader, cmd_code, len);
return zTools_SendData((unsigned char *)zcatHeader, sizeof(T_ZCAT_HEADER) + len, MDL_ZCAT, 1, SUBMDL_ZCATAGT);
}
/**
* @brief »ñȡģ¿éºÍµÈ¼¶
* @param[in] buf ÏûÏ¢Êý¾ÝÖ¸Õë
* @param[in] bufLen ÏûÏ¢Êý¾Ý³¤¶È
* @param[in] priority ÏûÏ¢µÈ¼¶
* @param[in] mod Ä£¿é±àºÅ
* @return void
* @note
* @see
*/
VOID zCatAgt_Ap_GetModAndPri(unsigned char **buf, unsigned short *bufLen, unsigned char *pPriority, unsigned char *pMod)
{
unsigned char *p = *buf;
unsigned short len = *bufLen;
if (len > 3 && p[0] == '<' && p[1] >= '0' && p[1] <= '7' && p[2] == '>')
{
*pPriority = p[1] - '0';
p += 3;
len -= 3;
if (len > 3 && p[0] == '<' && p[1] > '0' && p[1] <= '9')
{
if (p[2] == '>')
{
*pMod = p[1] - '0';
p += 3;
len -= 3;
}
else if (len > 4 && p[2] >= '0' && p[2] <= '9')
{
if (p[3] == '>')
{
*pMod = (p[1] - '0') * 10 + (p[2] - '0');
p += 4;
len -= 4;
}
else if (len > 5 && p[3] >= '0' && p[3] <= '9' && p[4] == '>')
{
*pMod = (p[1] - '0') * 100 + (p[2] - '0') * 10 + (p[3] - '0');
p += 5;
len -= 5;
}
}
}
}
*buf = p;
*bufLen = len;
}
/**
* @brief ·¢ËÍAP LOGµ½"ͳһ»º´æ"ÖÐ
* @param[in] cmd_code ÏûÏ¢Âë
* @param[in] priority ÏûÏ¢µÈ¼¶
* @param[in] mod Ä£¿é±àºÅ
* @param[in] buf ÏûÏ¢Êý¾ÝÖ¸Õë
* @param[in] len ÏûÏ¢Êý¾Ý³¤¶È
* @return ³É¹¦·µ»ØZOSS_SUCCESS, ·ñÔò·µ»ØZOSS_ERROR
* @note
* @see
*/
unsigned int zCatAgt_Ap_SendMsg(unsigned char cmd_code, unsigned char priority, unsigned char mod, unsigned char *buf, unsigned int len)
{
T_ZCAT_APLOG_HEADER *apHeader = NULL;
unsigned char *newBuffer = malloc(sizeof(T_ZCAT_APLOG_HEADER) + sizeof(T_ZCAT_HEADER) + sizeof(T_COMM_TYPE) + len);
if(newBuffer == NULL)
{
printf("[zcat] malloc buffer failed!\n");
return -1;
}
apHeader = (T_ZCAT_APLOG_HEADER *)(newBuffer + sizeof(T_ZCAT_HEADER) + sizeof(T_COMM_TYPE));
#if 0
if (apHeader == NULL)
{
printf("[zcat] apHeader is null.\n");
return -1;
}
else
#endif
{
apHeader->priority = priority;
apHeader->mod = mod;
apHeader->len = len;
memcpy(apHeader + 1, buf, len);
return zCatAgt_SendMsg(cmd_code, (unsigned char *)apHeader, sizeof(T_ZCAT_APLOG_HEADER) + len);
}
}
/**
* @brief ·ÖÎöAP LOG£¬°´»»ÐÐÖØÐ·ָî
* @param[in] src Ô´
* @param[in] dst Ä¿µÄ
* @return Èç¹û³É¹¦·µ»ØTRUE, ·ñÔò·µ»ØFALSE
* @note
* @see
*/
BOOL zCatAgt_Ap_ReadBuffer(T_AP_SRC_BUFFER_TYPE *src, T_AP_DEST_BUFFER_TYPE *dest)
{
if (src != NULL && src->buf != NULL && src->bufSize > src->beginIndex && dest != NULL )
{
unsigned char *src_buf = src->buf + src->beginIndex;
unsigned int src_length = src->bufSize - src->beginIndex;
unsigned int buf_length = src_length > AP_LOG_MAX_LENGTH ? AP_LOG_MAX_LENGTH : src_length;
unsigned int i = 0;
for (; i < buf_length; i++)
{
if (src_buf[i] == '\n')
{
i++;
dest->newLine = 1;
break;
}
}
dest->buf = src->buf + src->beginIndex;
dest->len = i;
src->beginIndex += i;
return TRUE;
}
return FALSE;
}
void timer(int sig)
{
hb_flag = 0;
return;
}
/**
* @brief ´¦Àíδ±àÂëµÄÊý¾Ý£¬¸ù¾ÝÀàÐÍ·Ö±ð½øÐÐÏàÓ¦´¦Àí
* @param[in] buffer »º´æÖ¸Õë
* @param[in] buf_len »º´æ³¤¶È
* @return ³É¹¦·µ»Ø0£»Ê§°Ü·µ»Ø-1
* @note
* @see
*/
void deal_with_rawdata(unsigned char* buf, unsigned short buf_len)
{
T_COMM_TYPE commHeader = {0};
if(buf_len > sizeof(T_COMM_TYPE))
{
memcpy(&commHeader, buf, sizeof(T_COMM_TYPE));
if(commHeader.src_mdl_no == COMM_MDLNO_ZCAT_FLAG) //aplogÏûÏ¢£¬È¥³ýcomÍ·zcatÍ·diagÍ·
{
T_ZCAT_HEADER *zcatHeader = (T_ZCAT_HEADER*)(buf+sizeof(T_COMM_TYPE));
if(zcatHeader->cmd_code >= ZCAT_CMDCODE_MAX)
{
printf("[zcat] zcatHeader->cmd_code:%d > ZCAT_CMDCODE_MAX\n", zcatHeader->cmd_code);
return;
}
else if(zcatHeader->cmd_code == ZCAT_DIAG_REPORT)
{
hb_flag = 1;
if(bFirst)
{
signal(SIGALRM, timer);
bFirst = 0;
}
alarm(5);
T_ZCAT_DIAG_HEADER *zdiagHeader = (T_ZCAT_DIAG_HEADER*)(buf + sizeof(T_COMM_TYPE)+sizeof(T_ZCAT_HEADER));
if (zdiagHeader->diag_id == DIAG_FILTER_CONFIG)
{
T_ZCAT_DIAG_CONFIG_REQ *diag_config = (T_ZCAT_DIAG_CONFIG_REQ *)(zdiagHeader + 1);
int headerLen = sizeof(T_COMM_TYPE)+sizeof(T_ZCAT_HEADER)+sizeof(T_ZCAT_DIAG_HEADER);
if(diag_config->type == ZCAT_AP_APP_TYPE)
{
ioctl(applog_fd, 5, buf + headerLen);
}
else if(diag_config->type == ZCAT_AP_KERNEL_TYPE)
{
ioctl(kernellog_fd, 5, buf + headerLen);
}
}
}
}
}
}
/**
* @brief ´¦Àí±àÂëºóµÄÊý¾Ý£¬¸ù¾ÝÀàÐÍ·Ö±ð½øÐÐÏàÓ¦´¦Àí
* @param[in] buffer »º´æÖ¸Õë
* @param[in] buf_len »º´æ³¤¶È
* @return ³É¹¦·µ»Ø0£»Ê§°Ü·µ»Ø-1
* @note
* @see
*/
int deal_with_encoded_data(unsigned char* buffer, int buf_len)
{
static T_HDLC_BUFFER_TYPE dest = {(unsigned char *)gCommDecodeBuffer, 0, MAX_ENCODE_PACKET_LEN};
T_HDLC_BUFFER_TYPE *src = &g_recvBuf;
unsigned int remainLen = 0;
BOOL ret_decode = FALSE;
if(buffer == NULL)
{
printf("[zcat] deal_with_encoded_data input error!\n");
return -1;
}
src->bufIndex=0;
// ½«ÐÂÏûÏ¢Êý¾Ý¿½È뻺³åÇø
if (src->bufSize + buf_len <= MAX_ENCODE_PACKET_LEN)
{
memcpy(src->buf + src->bufSize, buffer, buf_len);
src->bufSize += buf_len;
}
else if (buf_len <= MAX_ENCODE_PACKET_LEN)
{
memcpy(src->buf, buffer, buf_len);
src->bufSize = buf_len;
}
else
{
src->bufSize = 0;
}
remainLen = src->bufSize - src->bufIndex;
while (remainLen > 0)
{
ret_decode = hdlc_decode(&dest, src);
if(!ret_decode)
{
if (dest.bufIndex != 0 || src->bufSize - src->bufIndex == remainLen)
{
break;
}
}
else
{
deal_with_rawdata(dest.buf, dest.bufIndex);
dest.bufIndex = 0;
}
remainLen = src->bufSize - src->bufIndex;
}//end while
if (dest.bufSize <= dest.bufIndex)
{
dest.bufIndex = 0;
}
if (src->bufSize > src->bufIndex)
{
src->bufSize -= src->bufIndex;
memmove(src->buf, src->buf + src->bufIndex, src->bufSize);
}
else
{
src->bufSize = 0;
}
src->bufIndex = 0;
return 0;
}