/*******************************************************************************
|
* File Name : Log.c
|
* Description :
|
* Created on : 2018Äê8ÔÂ2ÈÕ
|
* Author : ¶Å¼ü
|
*******************************************************************************/
|
|
/*******************************************************************************
|
* Include Files *
|
*******************************************************************************/
|
#include "stdarg.h"
|
#include "string.h"
|
#include "stm32f4xx_hal.h"
|
#include "Log.h"
|
#include "DBG.h"
|
#include "RTC.h"
|
#include "HIDO_Lock.h"
|
#include "HIDO_FIFO.h"
|
#include "HIDO_Timer.h"
|
#include "AppConfig.h"
|
#include "HIDO_Util.h"
|
#include "HIDO_Debug.h"
|
#include "HIDO_Log.h"
|
#include "SPIFlash.h"
|
#include "HTTPClient.h"
|
#include "global_param.h"
|
|
/*******************************************************************************
|
* Macro *
|
*******************************************************************************/
|
#define LOG_FILE "log.text"
|
|
/*******************************************************************************
|
* Type Definition *
|
*******************************************************************************/
|
typedef struct
|
{
|
HIDO_UINT32 m_u32Index;
|
HIDO_UINT32 m_u32LastIndex;
|
HIDO_UINT32 m_u32Cnt;
|
}ST_LogForEachInfo;
|
|
typedef struct
|
{
|
HIDO_LogLevelEnum m_eLogLevel;
|
HIDO_BOOL m_bLogPrint;
|
}ST_LogParam;
|
|
typedef enum
|
{
|
LOG_UPLOAD_STATE_IDLE,
|
LOG_UPLOAD_STATE_WRITE_FILE,
|
LOG_UPLOAD_STATE_POST,
|
LOG_UPLOAD_STATE_DEL,
|
} E_LogUploadState;
|
|
typedef enum
|
{
|
WRITE_STATE_IDLE,
|
WRITE_STATE_HEAD,
|
WRITE_STATE_BODY,
|
WRITE_STATE_TAIL,
|
} E_WriteState;
|
|
/*******************************************************************************
|
* Local Variable *
|
*******************************************************************************/
|
static HIDO_UINT8 l_u8LogBuf[64];
|
static HIDO_FIFOStruct l_stLogFIFO;
|
static ST_LogParam l_stLogParam = { .m_eLogLevel = HIDO_LOG_LEVEL_DEBUG };
|
const static HIDO_CHAR l_acLevelName[HIDO_LOG_LEVEL_MAX] = { 'E' , 'W' , 'I' , 'D' };
|
static E_LogUploadState l_eLogUploadState;
|
static E_WriteState l_eWriteState;
|
static HIDO_CHAR l_acLogUploadUrl[128];
|
static HIDO_CHAR l_acLogUploadFileName[32];
|
static HIDO_UINT32 l_u32LogFIFOIndex = 0;
|
static HIDO_UINT32 l_u32HTTPPort = 80;
|
static HIDO_CHAR l_acHTTPHost[64];
|
static HIDO_CHAR l_acHTTPPath[64];
|
|
/*******************************************************************************
|
* Local Function Declaration *
|
*******************************************************************************/
|
void IWDG_Refresh(void);
|
static HIDO_INT32 Log_FileStateCallback(HIDO_INT32 _i32Result, HIDO_VOID *_pArg);
|
|
/*******************************************************************************
|
* Local Function *
|
*******************************************************************************/
|
/*******************************************************************************
|
* Function Name : Log_Read
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 Log_Read(HIDO_FIFOStruct *_pstFIFO, HIDO_UINT32 _u32Addr, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len)
|
{
|
return SPIFlash_Read(SPI_FLASH_ID_0, _pu8Data, _u32Addr, _u32Len);
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_Write
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 Log_Write(HIDO_FIFOStruct *_pstFIFO, HIDO_UINT32 _u32Addr, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len)
|
{
|
return SPIFlash_Write(SPI_FLASH_ID_0, _u32Addr, _pu8Data, _u32Len);
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_Erase
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 Log_Erase(HIDO_FIFOStruct *_pstFIFO, HIDO_UINT32 _u32Addr)
|
{
|
return SPIFlash_Erase(SPI_FLASH_ID_0, _u32Addr, _pstFIFO->m_u32SectorSize, SPI_FLASH_SECTOR_ERASE_MODE_4K);
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_ForEach
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 Log_ForEach(HIDO_FIFOStruct *_pstFIFO, HIDO_UINT32 _u32Index, HIDO_VOID *_pArg)
|
{
|
HIDO_FIFOHeaderStruct stDataHeader;
|
HIDO_UINT32 u32Len = 0;
|
ST_LogForEachInfo *pstInfo = (ST_LogForEachInfo *)_pArg;
|
|
if(pstInfo->m_u32Index >= pstInfo->m_u32Cnt)
|
{
|
return HIDO_ERR;
|
}
|
|
if (HIDO_FIFOReadMember(_pstFIFO, _u32Index, &stDataHeader, l_u8LogBuf, &u32Len) != HIDO_OK)
|
{
|
return HIDO_ERR;
|
}
|
|
l_u8LogBuf[u32Len] = '\0';
|
|
if(pstInfo->m_u32LastIndex != pstInfo->m_u32Index)
|
{
|
pstInfo->m_u32LastIndex = pstInfo->m_u32Index;
|
HIDO_Debug("%08u ", pstInfo->m_u32Index);
|
}
|
|
HIDO_Debug("%s", (HIDO_CHAR *)l_u8LogBuf);
|
|
if(FIFO_DATA_TYPE_END == stDataHeader.m_u8Type)
|
{
|
pstInfo->m_u32Index++;
|
}
|
|
//IWDG_Refresh();
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_ForEach
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 Log_HTTPFileResponseCallback(HIDO_UINT32 _u32RespCode, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len, HIDO_VOID *_pArg)
|
{
|
switch(l_eLogUploadState)
|
{
|
case LOG_UPLOAD_STATE_POST:
|
{
|
l_eLogUploadState = LOG_UPLOAD_STATE_IDLE;
|
#if 0
|
l_eLogUploadState = LOG_UPLOAD_STATE_DEL;
|
ModuleFile_DelFile(LOG_FILE, Log_FileStateCallback, HIDO_NULL);
|
#endif
|
break;
|
}
|
default:
|
{
|
break;
|
}
|
}
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_FileStateCallback
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 Log_FileStateCallback(HIDO_INT32 _i32Result, HIDO_VOID *_pArg)
|
{
|
switch(l_eLogUploadState)
|
{
|
case LOG_UPLOAD_STATE_WRITE_FILE:
|
{
|
l_eLogUploadState = LOG_UPLOAD_STATE_POST;
|
//HTTP_PostFile(l_acLogUploadUrl, LOG_FILE, Log_HTTPFileResponseCallback, HIDO_NULL);
|
break;
|
}
|
case LOG_UPLOAD_STATE_DEL:
|
{
|
l_eLogUploadState = LOG_UPLOAD_STATE_IDLE;
|
break;
|
}
|
default:
|
{
|
break;
|
}
|
}
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_FileWriteDataCallback
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 Log_FileWriteDataCallback(HIDO_UINT32 _u32Offset, HIDO_VOID *_pBuff, HIDO_UINT32 _u32BuffSize,
|
HIDO_UINT32 *_pu32Len, HIDO_VOID *_pArg)
|
{
|
HIDO_FIFOHeaderStruct stDataHeader;
|
HIDO_UINT32 u32Len = 0;
|
|
if(WRITE_STATE_IDLE == l_eWriteState)
|
{
|
*_pu32Len = 0;
|
}
|
else if(WRITE_STATE_HEAD == l_eWriteState)
|
{
|
*_pu32Len = HIDO_UtilSnprintf((HIDO_CHAR *)_pBuff, _u32BuffSize,
|
"POST /%s HTTP/1.1\r\n"
|
"Host: %s:%u\r\n"
|
"Connection: close\r\n"
|
"Content-Length: 1024000\r\n"
|
"Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryz7YF0uYP5EL1SvfH\r\n"
|
"User-Agent: Mozilla/5.0\r\n"
|
"Accept: */*\r\n"
|
"Accept-Encoding: gzip, deflate\r\n"
|
"\r\n"
|
"------WebKitFormBoundaryz7YF0uYP5EL1SvfH\r\n"
|
"Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n"
|
"Content-Type: text/plain\r\n"
|
"\r\n",
|
l_acHTTPPath, l_acHTTPHost, l_u32HTTPPort, l_acLogUploadFileName
|
);
|
l_eWriteState = WRITE_STATE_BODY;
|
}
|
else if(WRITE_STATE_BODY == l_eWriteState)
|
{
|
if(0xFFFFFFFF == l_u32LogFIFOIndex)
|
{
|
if(l_stLogFIFO.m_u32HeadIndex == l_stLogFIFO.m_u32TailIndex)
|
{
|
goto tail;
|
}
|
|
l_u32LogFIFOIndex = l_stLogFIFO.m_u32HeadIndex;
|
}
|
else
|
{
|
if(l_u32LogFIFOIndex != l_stLogFIFO.m_u32TailIndex)
|
{
|
l_u32LogFIFOIndex = (l_u32LogFIFOIndex + 1) % l_stLogFIFO.m_u32TotalCount;
|
}
|
else
|
{
|
goto tail;
|
}
|
}
|
|
if (HIDO_FIFOReadMember(&l_stLogFIFO, l_u32LogFIFOIndex, &stDataHeader, l_u8LogBuf, &u32Len) != HIDO_OK)
|
{
|
goto tail;
|
}
|
|
if(u32Len > _u32BuffSize)
|
{
|
return HIDO_ERR;
|
}
|
|
memcpy(_pBuff, l_u8LogBuf, u32Len);
|
*_pu32Len = u32Len;
|
}
|
else if(WRITE_STATE_TAIL == l_eWriteState)
|
{
|
tail:
|
l_eWriteState = WRITE_STATE_TAIL;
|
*_pu32Len = HIDO_UtilSnprintf((HIDO_CHAR *)_pBuff, _u32BuffSize,
|
"\r\n"
|
"------WebKitFormBoundaryz7YF0uYP5EL1SvfH\r\n"
|
"Content-Disposition: form-data; name=\"file\"; filename=\"\"\r\n"
|
"Content-Type: application/octet-stream\r\n"
|
"\r\n"
|
"\r\n"
|
"------WebKitFormBoundaryz7YF0uYP5EL1SvfH--\r\n"
|
"\r\n");
|
l_eWriteState = WRITE_STATE_IDLE;
|
}
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Global Function *
|
*******************************************************************************/
|
|
/*******************************************************************************
|
* Function Name : Log
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 HIDO_Log(HIDO_LogLevelEnum _eLevel, const HIDO_CHAR *_pcFmt, ...)
|
{
|
HIDO_INT32 i32Result = HIDO_OK;
|
va_list ap;
|
HIDO_UINT32 u32Len = 0;
|
HIDO_CHAR acOutputBuf[384];
|
ST_RTCDateTime stRTCDateTime;
|
|
//return HIDO_OK;
|
|
/* ÉÏ´«ÈÕ־ʱ²»ÄܼǼÈÕÖ¾ */
|
if(l_eLogUploadState != LOG_UPLOAD_STATE_IDLE)
|
{
|
return HIDO_OK;
|
}
|
|
/* ÈÕÖ¾¼¶±ð±È½Ï */
|
if(l_stLogParam.m_eLogLevel < _eLevel)
|
{
|
return HIDO_OK;
|
}
|
|
/* Êä³öÈÕÖ¾¸ñʽ */
|
// RTC_GetDateTime(&stRTCDateTime);
|
u32Len = HIDO_UtilSnprintf(acOutputBuf, sizeof(acOutputBuf), "%04u-%02u-%02u %02u:%02u:%02u.%03u %c ",
|
stRTCDateTime.m_u16Year, stRTCDateTime.m_u8Month, stRTCDateTime.m_u8Day, stRTCDateTime.m_u8Hour,
|
stRTCDateTime.m_u8Min, stRTCDateTime.m_u8Sec, HAL_GetTick() % 1000, l_acLevelName[_eLevel]);
|
|
va_start(ap, _pcFmt);
|
u32Len += vsnprintf(acOutputBuf + u32Len, sizeof(acOutputBuf) - u32Len, _pcFmt, ap);
|
va_end(ap);
|
|
if(u32Len > (sizeof(acOutputBuf) - 1))
|
{
|
u32Len = sizeof(acOutputBuf) - 1;
|
}
|
|
if(HIDO_TRUE == l_stLogParam.m_bLogPrint)
|
{
|
HIDO_DebugString(acOutputBuf, u32Len);
|
}
|
|
i32Result = HIDO_FIFOWrite(&l_stLogFIFO, (HIDO_UINT8 *)acOutputBuf, u32Len);
|
|
return i32Result;
|
}
|
|
/*******************************************************************************
|
* Function Name : Log
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 HIDO_LogWrite(HIDO_LogLevelEnum _eLevel, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len)
|
{
|
HIDO_INT32 i32Result = HIDO_OK;
|
HIDO_UINT32 u32Len = 0;
|
HIDO_CHAR acOutputBuf[384];
|
ST_RTCDateTime stRTCDateTime;
|
|
/* ÉÏ´«ÈÕ־ʱ²»ÄܼǼÈÕÖ¾ */
|
if(l_eLogUploadState != LOG_UPLOAD_STATE_IDLE)
|
{
|
return HIDO_OK;
|
}
|
|
/* ÈÕÖ¾¼¶±ð±È½Ï */
|
if(l_stLogParam.m_eLogLevel < _eLevel)
|
{
|
return HIDO_OK;
|
}
|
|
/* Êä³öÈÕÖ¾¸ñʽ */
|
// RTC_GetDateTime(&stRTCDateTime);
|
u32Len = HIDO_UtilSnprintf(acOutputBuf, sizeof(acOutputBuf), "%04u-%02u-%02u %02u:%02u:%02u.%03u %c ",
|
stRTCDateTime.m_u16Year, stRTCDateTime.m_u8Month, stRTCDateTime.m_u8Day, stRTCDateTime.m_u8Hour,
|
stRTCDateTime.m_u8Min, stRTCDateTime.m_u8Sec, HAL_GetTick() % 1000, l_acLevelName[_eLevel]);
|
|
i32Result = HIDO_FIFOWrite(&l_stLogFIFO, (HIDO_UINT8 *)acOutputBuf, u32Len);
|
|
if(HIDO_OK == i32Result)
|
{
|
i32Result = HIDO_FIFOWrite(&l_stLogFIFO, _pu8Data, _u32Len);
|
}
|
|
return i32Result;
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_Print
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 Log_Print(HIDO_BOOL _bAsc, HIDO_UINT32 _u32Cnt)
|
{
|
HIDO_INT32 i32Result = HIDO_OK;
|
ST_LogForEachInfo stInfo;
|
|
stInfo.m_u32LastIndex = 0xFFFFFFFF;
|
stInfo.m_u32Index = 0;
|
stInfo.m_u32Cnt = _u32Cnt;
|
|
i32Result = HIDO_FIFOReadForEach(&l_stLogFIFO, Log_ForEach, _bAsc, &stInfo);
|
|
return i32Result;
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_SetPrint
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 Log_SetPrint(HIDO_BOOL _bPrint)
|
{
|
if(l_stLogParam.m_bLogPrint != _bPrint)
|
{
|
l_stLogParam.m_bLogPrint = _bPrint;
|
}
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_Clean
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 Log_Clean(void)
|
{
|
return HIDO_FIFOClean(&l_stLogFIFO);
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_Upload
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 Log_Upload(HIDO_CHAR *_pcUrl)
|
{
|
ST_RTCDateTime stRTCDateTime;
|
|
if(HIDO_NULL == _pcUrl)
|
{
|
return HIDO_ERR;
|
}
|
|
if(l_eLogUploadState != LOG_UPLOAD_STATE_IDLE)
|
{
|
return HIDO_ERR;
|
}
|
|
l_u32LogFIFOIndex = 0xFFFFFFFF;
|
|
HIDO_UtilSnprintf(l_acLogUploadUrl, sizeof(l_acLogUploadUrl), _pcUrl);
|
|
// RTC_GetDateTime(&stRTCDateTime);
|
HIDO_UtilSnprintf(l_acLogUploadFileName, sizeof(l_acLogUploadFileName), "%04u-%02u-%02u_%02u-%02u-%02u_%04X.log",
|
stRTCDateTime.m_u16Year, stRTCDateTime.m_u8Month, stRTCDateTime.m_u8Day, stRTCDateTime.m_u8Hour,
|
stRTCDateTime.m_u8Min, stRTCDateTime.m_u8Sec, g_com_map[DEV_ID]);
|
|
/* ½âÎöUrl */
|
if(HTTPClient_ParseUrl(l_acLogUploadUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort) != HIDO_OK)
|
{
|
return HIDO_ERR;
|
}
|
|
l_eWriteState = WRITE_STATE_HEAD;
|
l_eLogUploadState = LOG_UPLOAD_STATE_POST;
|
HTTPClient_PostFile(l_acLogUploadUrl, Log_FileWriteDataCallback, Log_HTTPFileResponseCallback, HIDO_NULL);
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : Log_Init
|
* Description : ÈÕ־ģ¿é³õʼ»¯
|
* Input :
|
* Output :
|
* Return :
|
* Author : ¶Å¼ü
|
* Modified Date: : 2018Äê8ÔÂ2ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 Log_Init(void)
|
{
|
HIDO_FIFOInitStruct stInit;
|
|
stInit.m_fnRead = Log_Read;
|
stInit.m_fnWrite = Log_Write;
|
stInit.m_fnErase = Log_Erase;
|
stInit.m_u32SectorSize = APP_CONFIG_GENERAL_FIFO_SECTOR_SIZE;
|
stInit.m_u32MemberSize = APP_CONFIG_GENERAL_FIFO_MEMBER_SIZE;
|
stInit.m_u32TotalSize = APP_CONFIG_SPIFLASH_LOG_SIZE;
|
stInit.m_u32StartAddr = APP_CONFIG_SPIFLASH_LOG_ADDR;
|
if(HIDO_FIFOInit(&l_stLogFIFO, &stInit) != HIDO_OK)
|
{
|
HIDO_Debug("LogFIFO formate error, eraseing\r\n");
|
SPIFlash_Erase(SPI_FLASH_ID_0, APP_CONFIG_SPIFLASH_LOG_ADDR, APP_CONFIG_SPIFLASH_LOG_SIZE, SPI_FLASH_SECTOR_ERASE_MODE_64K);
|
|
HIDO_Debug("LogFIFO reinit\r\n");
|
memset(&l_stLogFIFO, 0, sizeof(l_stLogFIFO));
|
if(HIDO_FIFOInit(&l_stLogFIFO, &stInit) != HIDO_OK)
|
{
|
HIDO_Debug("LogFIFO reinit error\r\n");
|
}
|
|
return HIDO_ERR;
|
}
|
|
return HIDO_OK;
|
}
|