chen
2025-05-15 67ca69985af9109a0603a1cde71f21b940c059ff
keil/include/components/internet/src/Socket.c
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,893 @@
/*******************************************************************************
 * File Name         : Socket.c
 * Description       :
 * Created on        : 2018å¹´5月17日
 * Author            : www.hido-studio.com
 *******************************************************************************/
/*******************************************************************************
 *                              Include Files                                  *
 *******************************************************************************/
#include "string.h"
#include "Socket.h"
#include "HIDO_Util.h"
#include "HIDO_Debug.h"
#include "HIDO_ArraryQueue.h"
/*******************************************************************************
 *                                  Macro                                      *
 *******************************************************************************/
/* SOICKET相关 */
#define SOCKET_SEND_QUEUE_BUF_SIZE                    (512)
#define SOCKET_RECV_QUEUE_BUF_SIZE                    (512)
#define SOCKET_SEND_QUEUE_MEMBER_CNT                  16
#define SOCKET_RECV_QUEUE_MEMBER_CNT                  16
/*******************************************************************************
 *                             Type Definition                                 *
 *******************************************************************************/
typedef struct
{
    E_SocketState m_eState;
    E_SocketType m_eType;
    HIDO_BOOL m_bHasRecvData;
    HIDO_INT32 m_i32ID;
    FN_SocketEventProc m_fnEventProc;
    HIDO_VOID *m_pArg;
    HIDO_CHAR m_acRemoteAddr[42];
    HIDO_UINT16 m_u16RemotePort;
    HIDO_VLQStruct m_stSendQueue;
    HIDO_VLQStruct m_stRecvQueue;
    HIDO_ArraryQueueStruct m_stRecvInfoQueue;
    HIDO_ArraryQueueStruct m_stTCPRecvQueue;
    HIDO_UINT8 l_au8SendQueueBuf[SOCKET_SEND_QUEUE_BUF_SIZE];
    HIDO_UINT8 l_au8RecvQueueBuf[SOCKET_RECV_QUEUE_BUF_SIZE];
    HIDO_BOOL m_bUseHeartbeat;
    HIDO_UINT32 m_u32HeartbeatFreq;
    HIDO_CHAR m_acHeartbeatData[128];
}ST_SocketData;
/*******************************************************************************
 *                             Local Variable                                  *
 *******************************************************************************/
static ST_SocketData l_astSocketData[SOCKET_NUM];
/*******************************************************************************
 *                        Local Function Declaration                           *
 *******************************************************************************/
/*******************************************************************************
 *                             Local Function                                  *
 *******************************************************************************/
/*******************************************************************************
 *                             Global Function                                 *
 *******************************************************************************/
/*******************************************************************************
 * Function Name     : Socket_HaveRecvData
 * Description       : é€šçŸ¥Socket有数据需要接收
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_HaveRecvData(HIDO_INT32 _i32SockID)
{
    if(_i32SockID < SOCKET_NUM)
    {
        l_astSocketData[_i32SockID].m_bHasRecvData = HIDO_TRUE;
        return HIDO_OK;
    }
    return HIDO_ERR;
}
/*******************************************************************************
 * Function Name     : Socket_NoRecvData
 * Description       : é€šçŸ¥Socket没有数据需要接收
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_NoRecvData(HIDO_INT32 _i32SockID)
{
    if(_i32SockID < SOCKET_NUM)
    {
        l_astSocketData[_i32SockID].m_bHasRecvData = HIDO_FALSE;
        return HIDO_OK;
    }
    return HIDO_ERR;
}
/*******************************************************************************
 * Function Name     : Socket_HasRecvData
 * Description       : èŽ·å–Socket是否有数据需要接收
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_TRUE æœ‰æ•°æ®éœ€è¦æŽ¥æ”¶, HIDO_FALSE æ²¡æœ‰æ•°æ®éœ€è¦æŽ¥æ”¶
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_BOOL Socket_HasRecvData(HIDO_INT32 _i32SockID)
{
    if(_i32SockID < SOCKET_NUM)
    {
        return l_astSocketData[_i32SockID].m_bHasRecvData;
    }
    return HIDO_FALSE;
}
/*******************************************************************************
 * Function Name     : Socket_GetSocketRecvQueue
 * Description       : èŽ·å–Socket接收队列
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : Socket接收队列
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_VLQStruct *Socket_GetSocketRecvQueue(HIDO_INT32 _i32SockID)
{
    if(_i32SockID < SOCKET_NUM)
    {
        return &l_astSocketData[_i32SockID].m_stRecvQueue;
    }
    return HIDO_NULL;
}
/*******************************************************************************
 * Function Name     : Socket_GetSocketSendQueue
 * Description       : èŽ·å–Socket发送队列
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : Socket发送队列
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_VLQStruct *Socket_GetSocketSendQueue(HIDO_INT32 _i32SockID)
{
    if(_i32SockID < SOCKET_NUM)
    {
        return &l_astSocketData[_i32SockID].m_stSendQueue;
    }
    return HIDO_NULL;
}
/*******************************************************************************
 * Function Name     : Socket_GetType
 * Description       : èŽ·å–Socke类型
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : Socke类型
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
E_SocketType Socket_GetType(HIDO_INT32 _i32SockID)
{
    if(_i32SockID < SOCKET_NUM)
    {
        return l_astSocketData[_i32SockID].m_eType;
    }
    return SOCKET_TYPE_NONE;
}
/*******************************************************************************
 * Function Name     : Socket_GetSocketState
 * Description       : èŽ·å–Socke内部状态
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : Socke内部状态
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
E_SocketState Socket_GetSocketState(HIDO_INT32 _i32SockID)
{
    if(_i32SockID < SOCKET_NUM)
    {
        return l_astSocketData[_i32SockID].m_eState;
    }
    return SOCKET_STATE_IDLE;
}
/*******************************************************************************
 * Function Name     : Socket_SetSocketState
 * Description       : è®¾ç½®Socke内部状态
 * Input             : _i32Sock Socket描述符
 *                   : _eState Socke内部状态
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_SetSocketState(HIDO_INT32 _i32SockID, E_SocketState _eState)
{
    if(_i32SockID < SOCKET_NUM)
    {
        l_astSocketData[_i32SockID].m_eState = _eState;
        return HIDO_OK;
    }
    return HIDO_ERR;
}
/*******************************************************************************
 * Function Name     : Socket_GetRemoteAddr
 * Description       : èŽ·å–Socket远程地址
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : è¿œç¨‹åœ°å€
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_CHAR *Socket_GetRemoteAddr(HIDO_INT32 _i32SockID)
{
    if(_i32SockID < SOCKET_NUM)
    {
        return l_astSocketData[_i32SockID].m_acRemoteAddr;
    }
    return "";
}
/*******************************************************************************
 * Function Name     : Socket_GetRemotePort
 * Description       : èŽ·å–Socket远程端口
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : è¿œç¨‹ç«¯å£
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_UINT16 Socket_GetRemotePort(HIDO_INT32 _i32SockID)
{
    if(_i32SockID < SOCKET_NUM)
    {
        return l_astSocketData[_i32SockID].m_u16RemotePort;
    }
    return 0;
}
/*******************************************************************************
 * Function Name     : Socket_RecvAll
 * Description       : å…¨éƒ¨Socket需要接收数据的通知
 * Input             : None
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_RecvAll(void)
{
    HIDO_INT32 i32SockID = 0;
    ST_SocketData *pstSocketData = HIDO_NULL;
    for(i32SockID = 0; i32SockID < SOCKET_NUM; i32SockID++)
    {
        pstSocketData = &l_astSocketData[i32SockID];
        if(pstSocketData != HIDO_NULL && SOCKET_STATE_CONNECTED == pstSocketData->m_eState)
        {
            pstSocketData->m_bHasRecvData = HIDO_TRUE;
        }
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_ClosedAll
 * Description       : å…¨éƒ¨Socket被断开的通知
 * Input             : None
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_ClosedAll(void)
{
    HIDO_INT32 i32SockID = 0;
    ST_SocketData *pstSocketData = HIDO_NULL;
    for(i32SockID = 0; i32SockID < SOCKET_NUM; i32SockID++)
    {
        pstSocketData = &l_astSocketData[i32SockID];
        switch (pstSocketData->m_eState)
        {
            case SOCKET_STATE_CONNECT:
            case SOCKET_STATE_CLOSE_BEFORE_CONNECT:
            case SOCKET_STATE_CONNECTED:
            {
                pstSocketData->m_bHasRecvData = HIDO_FALSE;
                pstSocketData->m_eState = SOCKET_STATE_CLOSED;
                if (pstSocketData->m_fnEventProc != HIDO_NULL)
                {
                    pstSocketData->m_fnEventProc(i32SockID, SOCKET_EVENT_CLOSED, pstSocketData->m_pArg);
                }
                break;
            }
            default:
            {
                break;
            }
        }
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_OnConnectFailed
 * Description       : Socket连接失败时的内部通知
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_OnConnectFailed(HIDO_INT32 _i32SockID)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL)
    {
        return HIDO_ERR;
    }
    pstSocketData->m_eState = SOCKET_STATE_CONNECT_FAILED;
    if(pstSocketData->m_fnEventProc != HIDO_NULL)
    {
        pstSocketData->m_fnEventProc(_i32SockID, SOCKET_EVENT_CONNECT_FAILED, pstSocketData->m_pArg);
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_OnConnected
 * Description       : Socket连接成功时的内部通知
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_OnConnected(HIDO_INT32 _i32SockID)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL)
    {
        return HIDO_ERR;
    }
    pstSocketData->m_eState = SOCKET_STATE_CONNECTED;
    /* é‡ç½®é˜Ÿåˆ— */
#if 0
    HIDO_VLQInit(&pstSocketData->m_stSendQueue, pstSocketData->l_au8SendQueueBuf,
            SOCKET_SEND_QUEUE_BUF_SIZE, SOCKET_SEND_QUEUE_MEMBER_CNT);
    if(SOCKET_TYPE_TCP == pstSocketData->m_eType)
    {
        HIDO_ArraryQueueInit(&pstSocketData->m_stTCPRecvQueue, pstSocketData->l_au8RecvQueueBuf,
                SOCKET_RECV_QUEUE_BUF_SIZE, sizeof(HIDO_UINT8));
    }
    else
    {
        HIDO_VLQInit(&pstSocketData->m_stRecvQueue, pstSocketData->l_au8RecvQueueBuf,
                SOCKET_RECV_QUEUE_BUF_SIZE, SOCKET_RECV_QUEUE_MEMBER_CNT);
    }
#endif
    /* é€šçŸ¥ä¸Šå±‚ */
    if(pstSocketData->m_fnEventProc != HIDO_NULL)
    {
        pstSocketData->m_fnEventProc(_i32SockID, SOCKET_EVENT_CONNECTED, pstSocketData->m_pArg);
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_OnClosed
 * Description       : Socket被关闭时的内部通知
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_OnClosed(HIDO_INT32 _i32SockID)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL)
    {
        return HIDO_ERR;
    }
    if(SOCKET_STATE_CLOSE_BEFORE_CONNECT == pstSocketData->m_eState)
    {
       return HIDO_ERR;
    }
    pstSocketData->m_eState = SOCKET_STATE_CLOSED;
    if(pstSocketData->m_fnEventProc != HIDO_NULL)
    {
        pstSocketData->m_fnEventProc(_i32SockID, SOCKET_EVENT_CLOSED, pstSocketData->m_pArg);
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_RecvData
 * Description       : Socket收到数据时的内部处理
 * Input             : _i32Sock Socket描述符
 *                   : _pu8Data æ”¶åˆ°çš„æ•°æ®
 *                   : _u32Len æ”¶åˆ°çš„æ•°æ®é•¿åº¦
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_RecvData(HIDO_INT32 _i32SockID, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    HIDO_UINT32 i = 0;
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL)
    {
        return HIDO_ERR;
    }
    if(SOCKET_TYPE_TCP == pstSocketData->m_eType)
    {
        for(i = 0; i < _u32Len; i++)
        {
           if(HIDO_ArraryQueueIn(&(pstSocketData->m_stTCPRecvQueue), &_pu8Data[i]) != HIDO_OK)
           {
               return HIDO_ERR;
           }
        }
    }
    else
    {
       HIDO_VLQMemberStruct *pstMember = HIDO_NULL;
        pstMember = HIDO_VLQGetEnqueueMember(&l_astSocketData[_i32SockID].m_stRecvQueue, _u32Len);
        if (pstMember != HIDO_NULL)
        {
            memcpy(pstMember->m_pDataAddr, _pu8Data, _u32Len);
            HIDO_VLQEnqueue(&l_astSocketData[_i32SockID].m_stRecvQueue, pstMember);
        }
        else
        {
            HIDO_Debug("Socket[%u] Recv Buffer Full\r\n", _i32SockID);
        }
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_OnRecv
 * Description       : Socket收到数据时的内部通知
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_OnRecv(HIDO_INT32 _i32SockID)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL)
    {
        return HIDO_ERR;
    }
    if(pstSocketData->m_fnEventProc != HIDO_NULL)
    {
        pstSocketData->m_fnEventProc(_i32SockID, SOCKET_EVENT_RECV_DATA, pstSocketData->m_pArg);
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_Create
 * Description       : Socket创建
 * Input             : _eSocketType Socket类型
 *                   : _fnEventProc Socket事件处理函数
 *                   : _pArg å‚æ•°
 * Output            : _pi32SockID Socket描述符
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_Create(HIDO_INT32 *_pi32SockID, E_SocketType _eSocketType, FN_SocketEventProc _fnEventProc, HIDO_VOID *_pArg)
{
    HIDO_INT32 i32SockID = 0;
    ST_SocketData *pstSocketData = HIDO_NULL;
    for(i32SockID = 0; i32SockID < SOCKET_NUM; i32SockID++)
    {
        pstSocketData = &l_astSocketData[i32SockID];
        if(pstSocketData != HIDO_NULL && (SOCKET_STATE_IDLE == pstSocketData->m_eState))
        {
            HIDO_UtilBzero(pstSocketData, sizeof(ST_SocketData));
            pstSocketData->m_i32ID = i32SockID;
            pstSocketData->m_eType = _eSocketType;
            pstSocketData->m_eState = SOCKET_STATE_CREATED;
            pstSocketData->m_fnEventProc = _fnEventProc;
            pstSocketData->m_pArg = _pArg;
            HIDO_VLQInit(&pstSocketData->m_stSendQueue, pstSocketData->l_au8SendQueueBuf,
                    SOCKET_SEND_QUEUE_BUF_SIZE, SOCKET_SEND_QUEUE_MEMBER_CNT);
            if(SOCKET_TYPE_TCP == _eSocketType)
            {
               HIDO_ArraryQueueInit(&pstSocketData->m_stTCPRecvQueue, pstSocketData->l_au8RecvQueueBuf,
                     SOCKET_RECV_QUEUE_BUF_SIZE, sizeof(HIDO_UINT8));
            }
            else
            {
                HIDO_VLQInit(&pstSocketData->m_stRecvQueue, pstSocketData->l_au8RecvQueueBuf,
                      SOCKET_RECV_QUEUE_BUF_SIZE, SOCKET_RECV_QUEUE_MEMBER_CNT);
            }
            *_pi32SockID = i32SockID;
            return HIDO_OK;
        }
    }
    return HIDO_ERR;
}
/*******************************************************************************
 * Function Name     : Socket_Connect
 * Description       : Socket连接
 * Input             : _i32Sock Socket描述符
 *                   : _pcRemoteAddr ç›®æ ‡åœ°å€
 *                   : _u16RemotePort ç›®æ ‡ç«¯å£
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_Connect(HIDO_INT32 _i32SockID, HIDO_CHAR *_pcRemoteAddr, HIDO_UINT16 _u16RemotePort)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL)
    {
        return HIDO_ERR;
    }
    HIDO_UtilSnprintf(pstSocketData->m_acRemoteAddr, sizeof(pstSocketData->m_acRemoteAddr), "%s", _pcRemoteAddr);
    pstSocketData->m_u16RemotePort = _u16RemotePort;
    pstSocketData->m_eState = SOCKET_STATE_CONNECT;
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_Close
 * Description       : å…³é—­ä¸€ä¸ªSocket
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_Close(HIDO_INT32 _i32SockID)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL)
    {
        return HIDO_ERR;
    }
    if(pstSocketData->m_eState != SOCKET_STATE_IDLE && pstSocketData->m_eState != SOCKET_STATE_CLOSED)
    {
        pstSocketData->m_eState = SOCKET_STATE_CLOSE;
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_Destroy
 * Description       : é”€æ¯ä¸€ä¸ªSocket
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_Destroy(HIDO_INT32 _i32SockID)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL)
    {
        return HIDO_ERR;
    }
    pstSocketData->m_eState = SOCKET_STATE_IDLE;
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_IsSendQueueEmpty
 * Description       : åˆ¤æ–­å‘送队列是否为空
 * Input             : _i32Sock Socket描述符
 * Output            : None
 * Return            : HIDO_TRUE å‘送队列为空, HIDO_FALSE å‘送队列不为空
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_BOOL Socket_IsSendQueueEmpty(HIDO_INT32 _i32SockID)
{
    HIDO_VLQMemberStruct *pstMember = HIDO_NULL;
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL)
    {
        return HIDO_FALSE;
    }
    pstMember = HIDO_VLQGetDequeueMember(&pstSocketData->m_stSendQueue);
    if(HIDO_NULL == pstMember)
    {
        return HIDO_TRUE;
    }
    return HIDO_FALSE;
}
/*******************************************************************************
 * Function Name     : Socket_Send
 * Description       : Socket发送数据
 * Input             : _i32Sock Socket描述符
 *                   : _pu8Data å‘送的数据
 *                   : _u32DataLen å‘送的数据长度
 * Output            : None
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_Send(HIDO_INT32 _i32SockID, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32DataLen)
{
    HIDO_VLQMemberStruct *pstMember = HIDO_NULL;
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL || _u32DataLen == 0)
    {
        return HIDO_ERR;
    }
    pstMember = HIDO_VLQGetEnqueueMember(&pstSocketData->m_stSendQueue, _u32DataLen); /* èŽ·å–å…¥é˜Ÿç©ºé—´ */
    if(HIDO_NULL == pstMember)
    {
        HIDO_Debug("socket[%d] send buf full\r\n", _i32SockID);
        return HIDO_ERR;
    }
    memcpy(pstMember->m_pDataAddr, _pu8Data, _u32DataLen);
    HIDO_VLQEnqueue(&pstSocketData->m_stSendQueue, pstMember); /* å…¥é˜Ÿ */
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_IsClosed
 * Description       : æ£€æŸ¥Socket是否已断开
 * Input             : _i32Sock Socket描述符
 * Output            : _pbResult æ–­å¼€çŠ¶æ€ HIDO_TRUE å·²æ–­å¼€  HIDO_FALSE æœªæ–­å¼€
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_IsClosed(HIDO_INT32 _i32SockID, HIDO_BOOL *_pbResult)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || HIDO_NULL == _pbResult)
    {
        return HIDO_ERR;
    }
    if(SOCKET_STATE_CLOSED == pstSocketData->m_eState || SOCKET_STATE_IDLE == pstSocketData->m_eState
          || SOCKET_STATE_CONNECT_FAILED == pstSocketData->m_eState || SOCKET_STATE_CREATED == pstSocketData->m_eState)
    {
       *_pbResult = HIDO_TRUE;
    }
    else
    {
       *_pbResult = HIDO_FALSE;
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_IsConnected
 * Description       : æ£€æŸ¥Socket是否已连接
 * Input             : _i32Sock Socket描述符
 * Output            : _pbResult è¿žæŽ¥çŠ¶æ€ HIDO_TRUE å·²è¿žæŽ¥  HIDO_FALSE æœªè¿žæŽ¥
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_IsConnected(HIDO_INT32 _i32SockID, HIDO_BOOL *_pbResult)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || HIDO_NULL == _pbResult)
    {
        return HIDO_ERR;
    }
    if(SOCKET_STATE_CONNECTED == pstSocketData->m_eState)
    {
        *_pbResult = HIDO_TRUE;
    }
    else
    {
        *_pbResult = HIDO_FALSE;
    }
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_UseHeartbeat
 *******************************************************************************/
HIDO_BOOL Socket_UseHeartbeat(HIDO_INT32 _i32SockID)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM)
    {
        return HIDO_FALSE;
    }
    return pstSocketData->m_bUseHeartbeat;
}
/*******************************************************************************
 * Function Name     : Socket_SetHeartbeatData
 *******************************************************************************/
HIDO_INT32 Socket_HeartbeatConfig(HIDO_INT32 _i32SockID, HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len, HIDO_UINT32 _u32HeartbeatFreq)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM)
    {
        return HIDO_ERR;
    }
    pstSocketData->m_bUseHeartbeat = HIDO_TRUE;
    pstSocketData->m_u32HeartbeatFreq = _u32HeartbeatFreq;
    HIDO_UtilByteArrayToHexString(_pu8Data, _u32Len, pstSocketData->m_acHeartbeatData, sizeof(pstSocketData->m_acHeartbeatData), HIDO_FALSE);
    return HIDO_OK;
}
/*******************************************************************************
 * Function Name     : Socket_GetHeartbeatFreq
 *******************************************************************************/
HIDO_UINT32 Socket_GetHeartbeatFreq(HIDO_INT32 _i32SockID)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM)
    {
        return 300;
    }
    return pstSocketData->m_u32HeartbeatFreq;
}
/*******************************************************************************
 * Function Name     : Socket_GetHeartbeatFreq
 *******************************************************************************/
HIDO_CHAR *Socket_GetHeartbeatData(HIDO_INT32 _i32SockID)
{
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM)
    {
        return 300;
    }
    return pstSocketData->m_acHeartbeatData;
}
/*******************************************************************************
 * Function Name     : Socket_Recv
 * Description       : ä»ŽSocket接收队列中读取数据
 * Input             : _i32Sock Socket描述符
 *                   : _u32RecvBuffSize è¯»å–数据的缓存地址
 * Output            : _pu8RecvBuff è¯»å–数据的缓存
 *                   : _pu32RecvLen æ•°æ®é•¿åº¦
 * Return            : HIDO_OK æˆåŠŸ, HIDO_ERR å¤±è´¥
 * Author            : www.hido-studio.com
 * Modified Date:    : 2018å¹´5月17日
 *******************************************************************************/
HIDO_INT32 Socket_Recv(HIDO_INT32 _i32SockID, HIDO_UINT8 *_pu8RecvBuff, HIDO_UINT32 _u32RecvBuffSize, HIDO_UINT32 *_pu32RecvLen)
{
    HIDO_INT32 i32Result = HIDO_ERR;
    HIDO_VLQMemberStruct *pstMember = HIDO_NULL;
    ST_SocketData *pstSocketData = &l_astSocketData[_i32SockID];
    if(_i32SockID < 0 || _i32SockID >= SOCKET_NUM || pstSocketData == HIDO_NULL || _pu32RecvLen == HIDO_NULL)
    {
        return HIDO_ERR;
    }
    if(SOCKET_TYPE_TCP == pstSocketData->m_eType)
    {
       HIDO_UINT32 i = 0;
       HIDO_UINT32 u32RecvLen = 0;
       for(i = 0; i < _u32RecvBuffSize; i++)
       {
          if(HIDO_ArraryQueueOut(&pstSocketData->m_stTCPRecvQueue, &_pu8RecvBuff[i]) != HIDO_OK)
          {
             *_pu32RecvLen = u32RecvLen;
             return HIDO_OK;
          }
          u32RecvLen++;
       }
       *_pu32RecvLen = u32RecvLen;
       i32Result = HIDO_OK;
    }
    else
    {
        pstMember = HIDO_VLQGetDequeueMember(&pstSocketData->m_stRecvQueue);
        if(pstMember != HIDO_NULL)
        {
            if(_u32RecvBuffSize > pstMember->m_u32DataLen)
            {
                memcpy(_pu8RecvBuff, pstMember->m_pDataAddr, pstMember->m_u32DataLen);
                *_pu32RecvLen = pstMember->m_u32DataLen;
                i32Result = HIDO_OK;
            }
            HIDO_VLQDequeue(&pstSocketData->m_stRecvQueue, pstMember);
        }
    }
    return i32Result;
}