blob: 8a99c2951406c112c27e8ba61c05dbc1daf78ed3 [file] [log] [blame]
/*
*
* Copyright (C) 2023
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* FileName : log_savefs.c
* This program Capture module's trace log, and save log to local
* file system.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/mman.h>
#include "log_usb.h"
#include "log_savefs.h"
#include "./config/IPStart_rule.h"
#include "./config/modemrule_rule.h"
/**
* ºê¶¨Òå
*/
#define DELETE_OLD_FILE_NUMR (1)
#define READ_BUFFER_SIZE (2048)
#define SINGLE_LOG_SIZE (50*1024*1024)
#define UNIT_ONE_MB_SIZE (1024*1024)
/**
* Íⲿ±äÁ¿ÒýÓÃ
*/
extern int errno;
/**
* È«¾Ö±äÁ¿¶¨Òå
*/
char gReadBuffer[READ_BUFFER_SIZE];
static pthread_mutex_t s_state_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t s_state_cond = PTHREAD_COND_INITIALIZER;
T_LOG_RULE_TYPE gRuleOps[] =
{
{"modemrule.rule", modemrule_rule_buf, sizeof(modemrule_rule_buf)},
{"IPStart.rule", IPStart_rule_buf, sizeof(IPStart_rule_buf)}
};
char gHeartBeat_Data[] = {0x01,0xaa,0xaa,0xaa,0x01,0x55,0x73,0x01,
0x14,0x00,0x00,0x00,0x06,0x67,0xbb,0xbb,
0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
0x44,0x09,0x7e};
T_COMM_FS_PARAM gFsSaveParam;
/**
* @brief д³öÊý¾Ý
* @param[in] void
* @return ³É¹¦·µ»ØÐ´È볤¶È£¬Ê§°Ü·µ»Ø-1
* @note
* @see
*/
static int zLogAgt_WriteToTracePort(usbdev_t *udev, char *buf, int len)
{
int retval = -1, write_len = 0;
int left_len = len;
while (left_len > 0) {
retval = zLogAgt_Usb_Write(udev, buf+write_len, len);
if (retval == -1) {
if (errno == EINTR) {
continue;
}
printf("%s failed.\n", __func__);
return retval;
}
left_len -= retval;
write_len += retval;
}
return write_len;
}
/**
* @brief ·¢Ë͹æÔòÎļþ¸ø°å²à
* @param[in] void
* @return ³É¹¦·µ»Ø0£¬Ê§°Ü·µ»Ø-1
* @note
* @see
*/
static int zLogAgt_SendRuleFile(usbdev_t *udev)
{
int ret = -1;
int read_size = 0;
char *read_buf = NULL;
int log_fp = -1;
int index = 0;
int rule_size = (sizeof(gRuleOps) / sizeof(T_LOG_RULE_TYPE));
read_buf = (char *)malloc(ZLOG_RULE_MAX_SIZE);
if (read_buf == NULL)
return ret;
for (; index < rule_size; index++) {
log_fp = open(gRuleOps[index].name, O_RDONLY);
if (log_fp >= 0) {
while ((read_size = read(log_fp, read_buf, ZLOG_RULE_MAX_SIZE - 1)) > 0) {
ret = zLogAgt_WriteToTracePort(udev, read_buf, read_size);
if (ret < 0) {
printf("write trace port failed\n");
close(log_fp);
free(read_buf);
return ret;
}
memset(read_buf, 0, sizeof(read_buf));
}
}
else {
ret = zLogAgt_WriteToTracePort(udev, gRuleOps[index].buf, gRuleOps[index].len);
if (ret < 0) {
free(read_buf);
printf("write trace port failed\n");
return ret;
}
}
}
if (log_fp >= 0) {
close(log_fp);
log_fp = -1;
}
ret = 0;
free(read_buf);
return ret;
}
/**
* @brief ÐÄÌø°ü·¢ËÍÏß³ÌÈë¿Ú
* @param[in] void
* @return ³É¹¦·µ»ØZOSS_SUCCESS£¬Ê§°Ü·µ»ØZOSS_ERROR
* @note
* @see
*/
static void *zLogAgt_HeartBeatSend_Entry(void *param)
{
int write_len = 0;
int remain_len = 0;
usbdev_t *udev = (usbdev_t *)param;
if (param == NULL)
return NULL;
if (zLogAgt_SendRuleFile(udev))
return NULL;
while (1) {
remain_len = sizeof(gHeartBeat_Data);
while (remain_len > 0) {
write_len = 0;
int retval = zLogAgt_Usb_Write(udev, gHeartBeat_Data + write_len, remain_len);
if (retval <= 0) {
PRINTF_DBG_ERROR("retval:%d\n", retval);
/*ÐÄÌø°ü·¢ËÍʧ°Ü, Ö÷½ø³ÌÍ˳ö*/
pthread_mutex_lock(&s_state_mutex);
pthread_cond_broadcast (&s_state_cond);
pthread_mutex_unlock(&s_state_mutex);
return NULL;
}
remain_len -= retval;
write_len += retval;
}
if (write_len != sizeof(gHeartBeat_Data)) {
PRINTF_DBG_ERROR("write_len:%d \n", write_len);
}
sleep(2);
}
}
/**
* @brief ɾ³ýLog File
* @param[in]ÐèҪɾ³ýµÄÎļþ¸öÊý
* @return ³É¹¦·µ»Ø0
* @note
* @see
*/
static int zLogAgt_DelLogFile(int delcnt)
{
int ret = 0;
char shcmd[ZLOG_SHELL_CMD_SIZE];
if (delcnt < DELETE_OLD_FILE_NUMR)
delcnt = DELETE_OLD_FILE_NUMR;
sprintf(shcmd, "ls -rt | sort | head -%d| xargs rm -rf", delcnt);
ret = system(shcmd);
if (ret < 0)
printf("system error errno:%d(%s) \n", errno, strerror(errno));
return ret;
}
/**
* @brief ´´½¨Log File
* @param[in] void
* @return ³É¹¦·µ»ØZOSS_SUCCESS£¬Ê§°Ü·µ»ØZOSS_ERROR
* @note
* @see
*/
static int zLogAgt_CreatLogFile(int log_fp)
{
int new_fd = -1;
char filename[ZLOG_BUF_SIZE] = {0};
time_t t = time(NULL);
struct tm *tm = localtime(&t);
gFsSaveParam.tmaxLogNum = (gFsSaveParam.tMaxLogsize) / (SINGLE_LOG_SIZE);
if (gFsSaveParam.uFileNum >= gFsSaveParam.tmaxLogNum){
zLogAgt_DelLogFile(DELETE_OLD_FILE_NUMR);
gFsSaveParam.uFileNum -= DELETE_OLD_FILE_NUMR;
}
sprintf(filename, "%s/%02d_%02d%02d_%02d%02d%02d.log", gFsSaveParam.localFsPath,
1900+tm->tm_year, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
if (log_fp >= 0) {
close(log_fp);
}
new_fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (new_fd < 0) {
printf("open %s failed errno %d %s.\n", filename, errno, strerror(new_fd));
}
gFsSaveParam.uFileNum++;
gFsSaveParam.curfd = new_fd;
return new_fd;
}
/**
* @brief LOG ¶ÁÈ¡¼°±£´æÏß³Ì
* @param[in] void
* @return ³É¹¦·µ»ØZOSS_SUCCESS£¬Ê§°Ü·µ»ØZOSS_ERROR
* @note
* @see
*/
void *zlogAgt_StoreToFs_Entry(void *param)
{
int read_size = 0;
int dlog_fp = -1;
unsigned int total_len = 0;
usbdev_t *udev = (usbdev_t *)param;
pthread_t heartbeat_thread;
if (pthread_create(&heartbeat_thread, NULL, zLogAgt_HeartBeatSend_Entry, (void *)udev)) {
PRINTF_DBG_ERROR("create thread failed.\n");
}
while (1) {
if (read_size <= 0) {
read_size = zLogAgt_Usb_Read(udev, gReadBuffer, sizeof(gReadBuffer));
}
else {
if ((dlog_fp < 0)
|| ((total_len + read_size) >= SINGLE_LOG_SIZE)) {
total_len = 0;
dlog_fp = zLogAgt_CreatLogFile(dlog_fp);
if (dlog_fp < 0) {
break;
}
}
int w_ret = write(dlog_fp, gReadBuffer, read_size);
if (w_ret < 0) {
printf("%s failed.\n", __func__);
dlog_fp = zLogAgt_CreatLogFile(dlog_fp);
if (dlog_fp < 0) {
break;
}
continue;
}
read_size -= w_ret;
total_len += w_ret;
fsync (dlog_fp);
}
}
if (dlog_fp >= 0) {
close(dlog_fp);
dlog_fp = -1;
}
zLogAgt_Usb_Close(udev);
pthread_exit(NULL);
return NULL;
}
/**
* @brief ÐźÅÍ˳öº¯ÊýÈë¿Ú
* @param[in] msg
* @return void
* @note
* @see
*/
static void zLogAgt_Exit_Process(int msg)
{
printf("\n%s: %d\n", __func__, msg);
pthread_mutex_lock(&s_state_mutex);
pthread_cond_broadcast(&s_state_cond);
pthread_mutex_unlock(&s_state_mutex);
sleep(1);
/*Enable Ctrl+C to exit*/
signal(SIGINT, SIG_DFL);
}
/**
* @brief LOG±£´æÖ÷º¯ÊýÈë¿Ú
* @param[in] É豸Îļþ¾ä±ú
* @return
* @note
* @see
*/
int zLogAgt_Savefs_Main(int fd_devfile)
{
int ret = -1;
int opt = -1;
usbdev_t udev = {0};
pthread_t savefs_thread;
if (access(gFsSaveParam.localFsPath, 0)) {
mkdir(gFsSaveParam.localFsPath, 0777);
}
gFsSaveParam.tMaxLogsize *= UNIT_ONE_MB_SIZE;
if (gFsSaveParam.tMaxLogsize <= SINGLE_LOG_SIZE)
gFsSaveParam.tMaxLogsize = SINGLE_LOG_SIZE;
udev.ttyfd = fd_devfile;
ret = pthread_create(&savefs_thread, NULL, zlogAgt_StoreToFs_Entry, (void *)&udev);
if (!ret) {
signal(SIGINT, zLogAgt_Exit_Process); //ctrl+C
signal(SIGTERM, zLogAgt_Exit_Process); //kill
pthread_mutex_lock(&s_state_mutex);
pthread_cond_wait(&s_state_cond, &s_state_mutex);
pthread_mutex_unlock(&s_state_mutex);
}
else {
printf("%s create thread failed, ret:%d error:%s\n", __func__, ret, strerror(ret));
return -1;
}
ret = pthread_join(savefs_thread, NULL);
if (ret) {
printf("pthread_join error: %s\n", strerror(ret));
}
return 0;
}