STM32H743/FML/Internet/HTTPClient.c
@@ -1,8 +1,8 @@
/*******************************************************************************
 * File Name         : HTTP.c
 * Description       :
 * Created on        : 2020年7月1日
 * Author            : 杜键
 * Created on        : 2020��7��1��
 * Author            : �ż�
 *******************************************************************************/
/*******************************************************************************
@@ -66,7 +66,7 @@
static HIDO_UINT32 l_u32HTTPTryCnt = 0;
static HIDO_UINT32 l_u32HTTPPort = 80;
static HIDO_CHAR l_acHTTPPath[64];
static HIDO_CHAR l_acHTTPPath[128];  // Increased from 64 to 128 for longer file paths
static HIDO_CHAR l_acHTTPHost[64];
static HIDO_UINT32 l_u32HTTPPostLen = 0;
@@ -97,8 +97,8 @@
 * Input             :
 * Output            :
 * Return            :
 * Author            : 杜键
 * Modified Date:    : 2020年7月1日
 * Author            : �ż�
 * Modified Date:    : 2020��7��1��
 *******************************************************************************/
static HIDO_INT32 HTTPClient_Response(HIDO_UINT32 _u32RespCode, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len)
{
@@ -128,8 +128,8 @@
 * Input             :
 * Output            :
 * Return            :
 * Author            : 杜键
 * Modified Date:    : 2020年7月1日
 * Author            : �ż�
 * Modified Date:    : 2020��7��1��
 *******************************************************************************/
static HIDO_VOID HTTPClient_TimerCallback(HIDO_VOID *_pArg)
{
@@ -145,8 +145,8 @@
 * Input             :
 * Output            :
 * Return            :
 * Author            : 杜键
 * Modified Date:    : 2020年11月14日
 * Author            : �ż�
 * Modified Date:    : 2020��11��14��
 *******************************************************************************/
static void HTTPClient_SocketEventProc(HIDO_INT32 _i32SockID, E_SocketEvent _eEvent, HIDO_VOID *_pArg)
{
@@ -193,8 +193,16 @@
                HIDO_TimerCancel(l_u32HTTPClientTimerID);
                l_eHTTPClientState = HTTP_CLIENT_STATE_IDLE;
                // 对于GET_FILE方法,发送NULL表示下载完成
                if(HTTP_METHOD_GET_FILE == l_eHTTPMethod)
                {
                    HTTPClient_Response(l_u32HTTPRespCode, HIDO_NULL, 0);
                }
                else
                {
                HTTPClient_Response(l_u32HTTPRespCode, l_pu8HTTPRespBody, l_u32HTTPContentLength);
            }
            }
            else
            {
                HIDO_TimerCancel(l_u32HTTPClientTimerID);
@@ -228,7 +236,7 @@
                if (HTTP_RECV_STATE_HEAD == l_eHTTPRecvState)
                {
                    /* 收到"\r\n\r\n */
                    /* �յ�"\r\n\r\n */
                    l_pu8HTTPRespBody = (HIDO_UINT8 *)HIDO_UtilStrnstr(l_acHTTPRecvBuff, "\r\n\r\n", u32RecvLen);
                    if (l_pu8HTTPRespBody != HIDO_NULL)
                    {
@@ -266,65 +274,62 @@
                            break;
                        }
                        /* 获取文件分片信息 */
                        /* ��ȡ�ļ���Ƭ��Ϣ */
                        if(HTTP_METHOD_GET_FILE == l_eHTTPMethod)
                        {
                            HIDO_DataStruct stETag;
                            memset(&l_stHTTPGetFileResponse, 0, sizeof(l_stHTTPGetFileResponse));
                            // 检查是否有Content-Range头(206 Partial Content响应)
                            pcKeyName = HIDO_UtilStrnstr(l_acHTTPRecvBuff, "Content-Range: ", u32RecvLen);
                            if (pcKeyName != HIDO_NULL)
                            {
                                // 有Range,解析Range信息
                                if (HIDO_UtilParseFormat((HIDO_UINT8 *) pcKeyName,
                                        u32RecvLen - (pcKeyName - l_acHTTPRecvBuff), "Content-Range: bytes %d-%d/%d\r\n",
                                        &u32Range0, &u32Range1, &u32RangeAll) != 3)
                                {
                                    Socket_Close(l_i32HTTPClientSockID);
                                    break;
                                }
                            }
                            else
                            {
                                Socket_Close(l_i32HTTPClientSockID);
                                break;
                            }
                            l_stHTTPGetFileResponse.m_u32RangeBegin = u32Range0;
                            l_stHTTPGetFileResponse.m_u32RangeEnd = u32Range1;
                            l_stHTTPGetFileResponse.m_u32RangeTotal = u32RangeAll;
                            }
                            else
                            {
                                // 无Range头,使用Content-Length作为总大小(200 OK响应)
                                l_stHTTPGetFileResponse.m_u32RangeBegin = 0;
                                l_stHTTPGetFileResponse.m_u32RangeEnd = l_u32HTTPContentLength - 1;
                                l_stHTTPGetFileResponse.m_u32RangeTotal = l_u32HTTPContentLength;
                            }
                            // ETag是可选的
                            pcKeyName = HIDO_UtilStrnstr(l_acHTTPRecvBuff, "ETag: ", u32RecvLen);
                             if (pcKeyName != HIDO_NULL)
                             {
                                 if (HIDO_UtilParseFormat((HIDO_UINT8 *) pcKeyName,
                                         u32RecvLen - (pcKeyName - l_acHTTPRecvBuff), "ETag: %p\r\n", &stETag) != 1)
                                        u32RecvLen - (pcKeyName - l_acHTTPRecvBuff), "ETag: %p\r\n", &stETag) == 1)
                                 {
                                     Socket_Close(l_i32HTTPClientSockID);
                                     break;
                                 }
                             }
                             else
                             {
                                 Socket_Close(l_i32HTTPClientSockID);
                                 break;
                             }
                             if((stETag.m_u32Len + 1) < sizeof(l_stHTTPGetFileResponse.m_acETag))
                             {
                                 memcpy(l_stHTTPGetFileResponse.m_acETag, stETag.m_pData, stETag.m_u32Len);
                             }
                        }
                            }
                        }
                        l_u32HTTPRecvTotalLen = l_pu8HTTPRespBody - (HIDO_UINT8 *)l_acHTTPRecvBuff + l_u32HTTPContentLength;
                        l_eHTTPRecvState = HTTP_RECV_STATE_BODY;
                        if (l_u32HTTPRecvBuffLen >= l_u32HTTPRecvTotalLen)
                        {
                            // 对于GET_FILE方法,需要先传递body数据
                            if(HTTP_METHOD_GET_FILE == l_eHTTPMethod && l_u32HTTPContentLength > 0)
                            {
                                HTTPClient_Response(l_u32HTTPRespCode, l_pu8HTTPRespBody, l_u32HTTPContentLength);
                            }
                            Socket_Close(l_i32HTTPClientSockID);
                        }
                    }
@@ -333,6 +338,11 @@
                {
                    if (l_u32HTTPRecvBuffLen >= l_u32HTTPRecvTotalLen)
                    {
                        // 对于GET_FILE方法,需要先传递body数据
                        if(HTTP_METHOD_GET_FILE == l_eHTTPMethod && l_u32HTTPContentLength > 0)
                        {
                            HTTPClient_Response(l_u32HTTPRespCode, l_pu8HTTPRespBody, l_u32HTTPContentLength);
                        }
                        Socket_Close(l_i32HTTPClientSockID);
                    }
                }
@@ -350,12 +360,12 @@
/*******************************************************************************
 * Function Name     : HTTPClient_ParseUrl
 * Description       : 解析Url
 * Description       : ����Url
 * Input             :
 * Output            :
 * Return            :
 * Author            : 杜键
 * Modified Date:    : 2020年7月1日
 * Author            : �ż�
 * Modified Date:    : 2020��7��1��
 *******************************************************************************/
HIDO_INT32 HTTPClient_ParseUrl(HIDO_CHAR *_pcUrl, HIDO_CHAR *_pcHost, HIDO_UINT32 _u32HostSize,
        HIDO_CHAR *_pcPath, HIDO_UINT32 _u32PathSize, HIDO_UINT32 *_pu32Port)
@@ -419,8 +429,8 @@
 * Input             :
 * Output            :
 * Return            :
 * Author            : 杜键
 * Modified Date:    : 2021年5月3日
 * Author            : �ż�
 * Modified Date:    : 2021��5��3��
 *******************************************************************************/
HIDO_INT32 HTTPClient_GetPostFileData(HIDO_UINT32 _u32Offset, HIDO_VOID *_pBuff, HIDO_UINT32 _u32BuffSize, HIDO_UINT32 *_pu32Len)
{
@@ -442,8 +452,8 @@
 * Input             :
 * Output            :
 * Return            :
 * Author            : 杜键
 * Modified Date:    : 2020年7月1日
 * Author            : �ż�
 * Modified Date:    : 2020��7��1��
 *******************************************************************************/
HIDO_INT32 HTTPClient_Post(HIDO_CHAR *_pcUrl, HIDO_CHAR *_pcBody, HIDO_UINT32 _u32BodyLen, FN_HTTPResponseCallback _fnResponseCallback, HIDO_VOID *_pArg)
{
@@ -457,7 +467,7 @@
        return HIDO_ERR;
    }
    /* 解析Url */
    /* ����Url */
    if(HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort) != HIDO_OK)
    {
        return HIDO_ERR;
@@ -497,8 +507,8 @@
 * Input             :
 * Output            :
 * Return            :
 * Author            : 杜键
 * Modified Date:    : 2020年7月1日
 * Author            : �ż�
 * Modified Date:    : 2020��7��1��
 *******************************************************************************/
HIDO_INT32 HTTPClient_Get(HIDO_CHAR *_pcUrl, FN_HTTPResponseCallback _fnResponseCallback, HIDO_VOID *_pArg)
{
@@ -512,7 +522,7 @@
        return HIDO_ERR;
    }
    /* 解析Url */
    /* ����Url */
    if(HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort) != HIDO_OK)
    {
        return HIDO_ERR;
@@ -545,18 +555,20 @@
/*******************************************************************************
 * Function Name     : HTTPClient_GetFile
 * Description       : HTTP 下载文件
 * Input             : _pcUrl 文件连接
 *                   : _fnGetFileCallback 文件下载事件回调
 *                   : _pstOpt 下载参数
 *                   : _pArg 用户参数,回调使用
 * Description       : HTTP �����ļ�
 * Input             : _pcUrl �ļ�����
 *                   : _fnGetFileCallback �ļ������¼��ص�
 *                   : _pstOpt ���ز���
 *                   �� _pArg �û�����,�ص�ʹ��
 * Output            : None
 * Return            : HIDO_OK 成功,HIDO_ERR 失败
 * Author            : 杜键
 * Modified Date:    : 2020年7月1日
 * Return            : HIDO_OK �ɹ�,HIDO_ERR ʧ��
 * Author            : �ż�
 * Modified Date:    : 2020��7��1��
 *******************************************************************************/
HIDO_INT32 HTTPClient_GetFile(HIDO_CHAR *_pcUrl, FN_HTTPGetFileCallback _fnGetFileCallback, ST_HTTPGetFileOpt *_pstOpt, HIDO_VOID *_pArg)
{
    HIDO_INT32 ret;
    if(l_eHTTPClientState != HTTP_CLIENT_STATE_IDLE)
    {
        return HIDO_ERR;
@@ -572,8 +584,9 @@
        return HIDO_ERR;
    }
    /* 解析Url */
    if(HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort) != HIDO_OK)
    /* ����Url */
    ret = HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort);
    if(ret != HIDO_OK)
    {
        return HIDO_ERR;
    }
@@ -581,14 +594,23 @@
    /* URL */
    HIDO_UtilSnprintf(l_acHTTPUrl, sizeof(l_acHTTPUrl), _pcUrl);
    // 构建基础HTTP请求头
    l_u32HTTPSendBuffLen = HIDO_UtilSnprintf(l_acHTTPSendBuff, sizeof(l_acHTTPSendBuff),
            "GET /%s HTTP/1.1\r\n"
            "Host: %s\r\n"
            "User-Agent: QUECTEL_MODULE\r\n"
            "Connection: Keep-Alive\r\n"
            "Accept: */*\r\n"
            "Accept: */*\r\n",
            l_acHTTPPath, l_acHTTPHost);
    // 只有当RangeEnd > RangeBegin且不为0时才添加Range头
    if(_pstOpt->m_u32RangeEnd > 0 && _pstOpt->m_u32RangeEnd != 0xFFFFFFFF)
    {
        l_u32HTTPSendBuffLen += HIDO_UtilSnprintf(l_acHTTPSendBuff + l_u32HTTPSendBuffLen,
            sizeof(l_acHTTPSendBuff) - l_u32HTTPSendBuffLen,
            "Range: bytes=%u-%u\r\n",
            l_acHTTPPath, l_acHTTPHost, _pstOpt->m_u32RangeBegin, _pstOpt->m_u32RangeEnd);
            _pstOpt->m_u32RangeBegin, _pstOpt->m_u32RangeEnd);
    }
    if(strlen(_pstOpt->m_acIfRange) != 0)
    {
@@ -617,15 +639,15 @@
/*******************************************************************************
 * Function Name     : HTTPClient_PostFile
 * Description       : HTTP 上传文件
 * Input             : _pcUrl              HTTP路径
 *                   : _pcFileName         文件名称
 *                   : _fnResponseCallback HTTP响应回调函数
 *                   : _pArg               参数
 * Description       : HTTP �ϴ��ļ�
 * Input             : _pcUrl              HTTP·��
 *                   : _pcFileName         �ļ�����
 *                   : _fnResponseCallback HTTP��Ӧ�ص�����
 *                   : _pArg               ����
 * Output            : Mone
 * Return            : HIDO_OK 成功,HIDO_ERR 失败
 * Author            : 杜键
 * Modified Date:    : 2021年5月3日
 * Return            : HIDO_OK �ɹ�,HIDO_ERR ʧ��
 * Author            : �ż�
 * Modified Date:    : 2021��5��3��
 *******************************************************************************/
HIDO_INT32 HTTPClient_PostFile(HIDO_CHAR *_pcUrl, FN_HTTPPostDataCallback _fnPostDataCallback, FN_HTTPResponseCallback _fnResponseCallback,
        HIDO_VOID *_pArg)
@@ -655,7 +677,7 @@
        return HIDO_ERR;
    }
    /* 解析Url */
    /* ����Url */
    if(HTTPClient_ParseUrl(_pcUrl, l_acHTTPHost, sizeof(l_acHTTPHost), l_acHTTPPath, sizeof(l_acHTTPPath), &l_u32HTTPPort) != HIDO_OK)
    {
        return HIDO_ERR;
@@ -675,12 +697,12 @@
/*******************************************************************************
 * Function Name     : HTTPClient_Poll
 * Description       : HTTP客户端轮询处理
 * Description       : HTTP�ͻ�����ѯ����
 * Input             : None
 * Output            : None
 * Return            : HIDO_OK 成功,HIDO_ERR 失败
 * Author            : 杜键
 * Modified Date:    : 2020年7月1日
 * Return            : HIDO_OK �ɹ�,HIDO_ERR ʧ��
 * Author            : �ż�
 * Modified Date:    : 2020��7��1��
 *******************************************************************************/
HIDO_INT32 HTTPClient_Poll(HIDO_VOID)
{
@@ -708,12 +730,12 @@
/*******************************************************************************
 * Function Name     : HTTPClient_Init
 * Description       : HTTP客户端初始化
 * Description       : HTTP�ͻ��˳�ʼ��
 * Input             : None
 * Output            : None
 * Return            : HIDO_OK 成功,HIDO_ERR 失败
 * Author            : 杜键
 * Modified Date:    : 2020年7月1日
 * Return            : HIDO_OK �ɹ�,HIDO_ERR ʧ��
 * Author            : �ż�
 * Modified Date:    : 2020��7��1��
 *******************************************************************************/
HIDO_INT32 HTTPClient_Init(HIDO_VOID)
{
@@ -731,3 +753,23 @@
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : HTTPClient_GetState
 * Description       : 获取HTTPClient当前状态(用于调试)
 * Return            : 0=IDLE, 1=CONNECTING, 2=CONNECTED
 *******************************************************************************/
HIDO_INT32 HTTPClient_GetState(HIDO_VOID)
{
    return (HIDO_INT32)l_eHTTPClientState;
}
/*******************************************************************************
 * Function Name     : HTTPClient_Reset
 * Description       : 强制重置HTTPClient状态到IDLE(用于错误恢复)
 *******************************************************************************/
HIDO_VOID HTTPClient_Reset(HIDO_VOID)
{
    l_eHTTPClientState = HTTP_CLIENT_STATE_IDLE;
    HIDO_TimerCancel(l_u32HTTPClientTimerID);
}