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