/******************************************************************************* * 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; }