/******************************************************************************* * File Name : FileDownload.c * Description : *******************************************************************************/ /******************************************************************************* * Include Files * *******************************************************************************/ #include "string.h" #include "HIDO_TypeDef.h" #include "HIDO_Timer.h" #include "FileDownload.h" #include "HIDO_Debug.h" #include "HIDO_Timer.h" #include "HIDO_Util.h" #include "HTTPClient.h" #include "APPConfig.h" #include "Internet.h" /******************************************************************************* * Macro * *******************************************************************************/ #define MAX_REQUEST_SIZE (30 * 1024) /******************************************************************************* * Type Definition * *******************************************************************************/ typedef enum { STATE_IDLE, STATE_HTTP_REQUEST_FILE_LEN, STATE_HTTP_REQUEST_DATA, STATE_WAIT_HTTP_RESPONSE, } E_FileDownloadState; /******************************************************************************* * Local Variable * *******************************************************************************/ static HIDO_CHAR l_acFileDownloadUrl[128]; static HIDO_UINT32 l_u32FileDownloadTimerID = 0; static E_FileDownloadState l_eFileDownloadState = STATE_IDLE; static HIDO_UINT32 l_u32FileDownloadRetryCnt = 0; static HIDO_UINT32 l_u32FileDownloadFileRecvLen = 0; static HIDO_UINT32 l_u32FileDownloadFileSize = 0; static T_FileDownloadCompleteCallback l_pFileDownloadCompleteCallback = HIDO_NULL; static T_FileDownloadDataCallback l_pFileDownloadDataCallback = HIDO_NULL; /******************************************************************************* * Local Function Declaration * *******************************************************************************/ static HIDO_VOID FileDownload_TimerCallBack(HIDO_VOID *_pArg); static HIDO_INT32 FileDownload_HTTPGetFileCallBack(HIDO_UINT32 _u32RespCode, ST_HTTPGetFileResponse *_pstResponse, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len, HIDO_VOID *_pArg); /******************************************************************************* * Local Function * *******************************************************************************/ /******************************************************************************* * Function Name : FileDownload_RequestFileLen * Description : * Input : * Output : * Return : *******************************************************************************/ static HIDO_INT32 FileDownload_RequestFileLen(HIDO_VOID) { ST_HTTPGetFileOpt stFileOpt; memset(&stFileOpt, 0, sizeof(stFileOpt)); stFileOpt.m_u32RangeBegin = 0; stFileOpt.m_u32RangeEnd = 0; if (HTTPClient_GetFile(l_acFileDownloadUrl, FileDownload_HTTPGetFileCallBack, &stFileOpt, HIDO_NULL) != HIDO_OK) { return HIDO_ERR; } return HIDO_OK; } /******************************************************************************* * Function Name : FileDownload_RequestFileData * Description : * Input : * Output : * Return : *******************************************************************************/ static HIDO_INT32 FileDownload_RequestFileData(HIDO_UINT32 _u32Offset) { ST_HTTPGetFileOpt stFileOpt; memset(&stFileOpt, 0, sizeof(stFileOpt)); stFileOpt.m_u32RangeBegin = _u32Offset; if ((l_u32FileDownloadFileSize - l_u32FileDownloadFileRecvLen) < MAX_REQUEST_SIZE) { stFileOpt.m_u32RangeEnd = _u32Offset + l_u32FileDownloadFileSize - l_u32FileDownloadFileRecvLen - 1; } else { stFileOpt.m_u32RangeEnd = _u32Offset + MAX_REQUEST_SIZE - 1; } if (HTTPClient_GetFile(l_acFileDownloadUrl, FileDownload_HTTPGetFileCallBack, &stFileOpt, HIDO_NULL) != HIDO_OK) { return HIDO_ERR; } return HIDO_OK; } /******************************************************************************* * Function Name : FileDownload_HTTPGetFileCallBack * Description : * Input : * Output : * Return : *******************************************************************************/ static HIDO_INT32 FileDownload_HTTPGetFileCallBack(HIDO_UINT32 _u32RespCode, ST_HTTPGetFileResponse *_pstResponse, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len, HIDO_VOID *_pArg) { if (200 == _u32RespCode) { HIDO_Debug("HTTPGetFileCallBack:200\r\n"); } else if (206 == _u32RespCode) { switch (l_eFileDownloadState) { case STATE_HTTP_REQUEST_FILE_LEN: { l_u32FileDownloadFileRecvLen = 0; l_u32FileDownloadFileSize = _pstResponse->m_u32RangeTotal; if (0 == l_u32FileDownloadFileSize) { HIDO_Debug("FileDownloadFileSize error\r\n"); } HIDO_Debug("FileDownloadFileSize %u\r\n", l_u32FileDownloadFileSize); l_eFileDownloadState = STATE_HTTP_REQUEST_DATA; FileDownload_RequestFileData(l_u32FileDownloadFileRecvLen); HIDO_TimerStart(l_u32FileDownloadTimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), FileDownload_TimerCallBack, HIDO_NULL); break; } case STATE_HTTP_REQUEST_DATA: { if (_pstResponse->m_u32RangeBegin != l_u32FileDownloadFileRecvLen) { break; } /* µ÷ÓÃÊý¾ÝдÈë»Øµ÷º¯Êý */ if (l_pFileDownloadDataCallback != HIDO_NULL) { l_pFileDownloadDataCallback(l_u32FileDownloadFileRecvLen, _pu8Data, _u32Len); } l_u32FileDownloadFileRecvLen += _u32Len; HIDO_Debug("FileDownloadFileDownload %u/%u\r\n", l_u32FileDownloadFileRecvLen, l_u32FileDownloadFileSize); /* Îļþ½ÓÊÕÍê³É */ if (l_u32FileDownloadFileRecvLen == l_u32FileDownloadFileSize) { l_eFileDownloadState = STATE_IDLE; HIDO_TimerCancel(l_u32FileDownloadTimerID); /* µ÷ÓÃÏÂÔØÍê³É»Øµ÷º¯Êý */ if (l_pFileDownloadCompleteCallback != HIDO_NULL) { l_pFileDownloadCompleteCallback(HIDO_OK, l_u32FileDownloadFileSize); } break; } FileDownload_RequestFileData(l_u32FileDownloadFileRecvLen); HIDO_TimerStart(l_u32FileDownloadTimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), FileDownload_TimerCallBack, HIDO_NULL); break; } default: { break; } } } else { // l_eFileDownloadState = STATE_IDLE; /* ÇëÇóʧ°Ü */ } return HIDO_OK; } /******************************************************************************* * Function Name : FileDownload_Failed * Description : * Input : * Output : * Return : *******************************************************************************/ static HIDO_INT32 FileDownload_Failed(void) { /* Éý¼¶²ÎÊýÓÐÎó£¬È¡ÏûÉý¼¶ */ HIDO_UINT16 tmp = 0xFFFF; HIDO_Debug("goto app application\r\n"); /* µ÷ÓÃÏÂÔØÊ§°Ü»Øµ÷º¯Êý */ if (l_pFileDownloadCompleteCallback != HIDO_NULL) { l_pFileDownloadCompleteCallback(HIDO_ERR, 0); } return HIDO_OK; } /******************************************************************************* * Function Name : FileDownload_TimerCallBack * Description : FileDownload¶¨Ê±Æ÷³¬Ê±»Øµ÷ * Input : ¶¨Ê±Æ÷²ÎÊý * Output : * Return : *******************************************************************************/ static HIDO_VOID FileDownload_TimerCallBack(HIDO_VOID *_pArg) { HIDO_Debug("l_eFileDownloadState = %u @%s\r\n", l_eFileDownloadState, __FUNCTION__); switch (l_eFileDownloadState) { case STATE_HTTP_REQUEST_FILE_LEN: { l_u32FileDownloadRetryCnt++; if (l_u32FileDownloadRetryCnt >= 3) { FileDownload_Failed(); } FileDownload_RequestFileLen(); HIDO_TimerStart(l_u32FileDownloadTimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), FileDownload_TimerCallBack, HIDO_NULL); break; } case STATE_HTTP_REQUEST_DATA: { l_u32FileDownloadRetryCnt++; if (l_u32FileDownloadRetryCnt >= 3) { FileDownload_Failed(); } FileDownload_RequestFileData(l_u32FileDownloadFileRecvLen); HIDO_TimerStart(l_u32FileDownloadTimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), FileDownload_TimerCallBack, HIDO_NULL); break; } default: { break; } } } /******************************************************************************* * Global Function * *******************************************************************************/ /******************************************************************************* * Function Name : FileDownload_SetUp * Description : FileDownloadÆô¶¯ * Input : _pcUrl FileDownloadÉý¼¶Îļþ·¾¶ * Output : None * Return : HIDO_OK ³É¹¦,HIDO_ERR ʧ°Ü *******************************************************************************/ HIDO_INT32 FileDownload_SetUp(HIDO_CHAR *_pcUrl, T_FileDownloadCompleteCallback _pCompleteCallback, T_FileDownloadDataCallback _pDataCallback) { if (HIDO_NULL == _pcUrl) { return HIDO_ERR; } if (l_eFileDownloadState != STATE_IDLE) { return HIDO_ERR; } /* ³õʼ»¯²ÎÊý */ l_u32FileDownloadRetryCnt = 0; l_u32FileDownloadFileSize = 0; l_u32FileDownloadFileRecvLen = 0; l_pFileDownloadCompleteCallback = _pCompleteCallback; l_pFileDownloadDataCallback = _pDataCallback; HIDO_UtilSnprintf(l_acFileDownloadUrl, sizeof(l_acFileDownloadUrl), _pcUrl); /* ÇëÇóÉý¼¶Îļþ³¤¶È */ if (FileDownload_RequestFileLen() != HIDO_OK) { return HIDO_ERR; } l_eFileDownloadState = STATE_HTTP_REQUEST_FILE_LEN; HIDO_TimerStart(l_u32FileDownloadTimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), FileDownload_TimerCallBack, HIDO_NULL); return HIDO_OK; } /******************************************************************************* * Function Name : FileDownload_Cancel * Description : * Input : * Output : * Return : *******************************************************************************/ HIDO_INT32 FileDownload_Cancel(HIDO_VOID) { HIDO_TimerCancel(l_u32FileDownloadTimerID); l_eFileDownloadState = STATE_IDLE; return HIDO_OK; } /******************************************************************************* * Function Name : FileDownload_Init * Description : * Input : * Output : * Return : *******************************************************************************/ HIDO_INT32 FileDownload_Init(void) { l_eFileDownloadState = STATE_IDLE; HIDO_TimerCreate(&l_u32FileDownloadTimerID); return HIDO_OK; }