/******************************************************************************* * File Name : Socket.c * Description : * Created on : 2018Äê5ÔÂ22ÈÕ * Author : ¶Å¼ü *******************************************************************************/ /******************************************************************************* * Include Files * *******************************************************************************/ #include "Socket.h" #include "string.h" #include "stdlib.h" #include "EC600SDriver.h" #include "EC600SFSM.h" #include "HIDO_FSM.h" #include "HIDO_Timer.h" #include "HIDO_Util.h" #include "HIDO_VLQueue.h" #include "HIDO_ArraryQueue.h" #include "HIDO_ATLite.h" #include "HIDO_Debug.h" #include "Module.h" #include "ATConfig.h" /******************************************************************************* * Macro * *******************************************************************************/ /******************************************************************************* * Type Definition * *******************************************************************************/ /******************************************************************************* * Local Variable * *******************************************************************************/ HIDO_FSM_STATE_FULL_DECLARE(EC600SIPReady, EC600SSocketConnect) /* SOCKETÁ¬½Ó״̬ */ HIDO_FSM_STATE_FULL_DECLARE(EC600SIPReady, EC600SSocketClose) /* SOCKET¹Ø±Õ״̬ */ HIDO_FSM_STATE_FULL_DECLARE(EC600SIPReady, EC600SSocketRecvData) /* SOCKET½ÓÊÕÊý¾Ý״̬ */ HIDO_FSM_STATE_FULL_DECLARE(EC600SIPReady, EC600SSocketSendData) /* SOCKET·¢ËÍÊý¾Ý״̬ */ HIDO_FSM_STATE_FULL_DECLARE(EC600SIPReady, EC600SSocketSendAck) static HIDO_BOOL l_abSocketUnAck[SOCKET_NUM]; static HIDO_UINT32 l_au32SocketUnAckTick[SOCKET_NUM]; static HIDO_UINT32 l_au32SocketSendTick[SOCKET_NUM]; /******************************************************************************* * Local Function Declaration * *******************************************************************************/ /******************************************************************************* * Local Function * *******************************************************************************/ /******************************************************************************* * Global Function * *******************************************************************************/ /******************************************************************************* * State Name : EC600SSocketConnect * Parent State : EC600S * Description : * Author : ¶Å¼ü * Modified Date: : 2018-05-01 *******************************************************************************/ extern u8 TCPfail_flag; extern u32 TCPfailetimer; HIDO_FSM_STATE_IMPLEMENT(EC600SSocketConnect, HIDO_FSM_STATE(EC600SIPReady), HIDO_NULL) { static HIDO_INT32 l_i32SocketID = 0; static HIDO_UINT32 l_u32FailedCnt = 0; HIDO_ATLiteDeviceStruct *pstATDevice = (HIDO_ATLiteDeviceStruct *) _pstFSM->m_pPrivateData; HIDO_UINT32 u32FSMTimerID = ((ST_EC600SDriverData *)pstATDevice->m_pUserData)->m_u32FSMTimerID; switch (_u32Event) { case HIDO_EVENT_ENTRY: { l_i32SocketID = (HIDO_INT32) _pArg; HIDO_ATLiteCmdSend(pstATDevice, AT_GENERAL_TIMEOUT_TIME, "AT+QIOPEN=1,%d,\"%s\",\"%s\",%u,0,0\r\n", l_i32SocketID, Socket_GetType(l_i32SocketID) == SOCKET_TYPE_TCP ? "TCP" : "UDP", Socket_GetRemoteAddr(l_i32SocketID), Socket_GetRemotePort(l_i32SocketID)); HIDO_FSMStartTimer(u32FSMTimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(180), _pstFSM, EC600S_EVENT_DELAY); break; } case HIDO_EVENT_EXIT: { HIDO_ATLiteCmdSendOver(pstATDevice); HIDO_TimerCancel(u32FSMTimerID); break; } case HIDO_AT_EVENT_OK: { break; } case HIDO_AT_EVENT_ERROR: { Socket_OnConnectFailed(l_i32SocketID); l_u32FailedCnt++; if(l_u32FailedCnt >= 3) { l_u32FailedCnt = 0; HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600S), HIDO_NULL); } else { HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); } break; } case EC600S_EVENT_OPEN: { HIDO_DataStruct *pstData = (HIDO_DataStruct *) _pArg; HIDO_UINT32 u32ConnectID = 0; HIDO_UINT32 u32Err = 0; if (HIDO_UtilParseFormat((HIDO_UINT8 *) pstData->m_pData, pstData->m_u32Len, "+QIOPEN: %d,%d\r\n", &u32ConnectID, &u32Err) != 2) { break; } if (l_i32SocketID == u32ConnectID) { if (0 == u32Err) { l_u32FailedCnt = 0; Socket_OnConnected(l_i32SocketID); HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); } else { Socket_OnConnectFailed(l_i32SocketID); l_u32FailedCnt++; if (l_u32FailedCnt >= 3) { l_u32FailedCnt = 3; TCPfail_flag = 1; Socket_Destroy(l_i32SocketID); TCPfailetimer = HIDO_TimerGetTick(); // HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600S), HIDO_NULL); HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); } else { HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); } } } break; } case EC600S_EVENT_DELAY: { HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); break; } default: { return HIDO_EVENT_NO_PROC; } } return HIDO_EVENT_OK; } /******************************************************************************* * State Name : EC600SSocketClose * Parent State : EC600S * Description : * Author : ¶Å¼ü * Modified Date: : 2018-05-01 *******************************************************************************/ HIDO_FSM_STATE_IMPLEMENT(EC600SSocketClose, HIDO_FSM_STATE(EC600SIPReady), HIDO_NULL) { HIDO_ATLiteDeviceStruct *pstATDevice = (HIDO_ATLiteDeviceStruct *) _pstFSM->m_pPrivateData; static HIDO_INT32 l_i32SocketID = 0; switch (_u32Event) { case HIDO_EVENT_ENTRY: { l_i32SocketID = (HIDO_INT32) _pArg; HIDO_ATLiteCmdSend(pstATDevice, HIDO_TIMER_TICK_S(15), "AT+QICLOSE=%d,10\r\n", l_i32SocketID); break; } case HIDO_EVENT_EXIT: { HIDO_ATLiteCmdSendOver(pstATDevice); break; } case HIDO_AT_EVENT_ERROR: case HIDO_AT_EVENT_OK: { Socket_OnClosed(l_i32SocketID); HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); break; } default: { return HIDO_EVENT_NO_PROC; } } return HIDO_EVENT_OK; } /******************************************************************************* * State Name : EC600SSocketRecvData * Parent State : Ready * Description : * Author : ¶Å¼ü * Modified Date: : 2018-05-01 *******************************************************************************/ HIDO_FSM_STATE_IMPLEMENT(EC600SSocketRecvData, HIDO_FSM_STATE(EC600SIPReady), HIDO_NULL) { static HIDO_INT32 l_i32SocketID = 0; HIDO_ATLiteDeviceStruct *_pstATDevice = (HIDO_ATLiteDeviceStruct *) _pstFSM->m_pPrivateData; switch (_u32Event) { case HIDO_EVENT_ENTRY: { l_i32SocketID = (HIDO_INT32) _pArg; HIDO_ATLiteCmdSend(_pstATDevice, 5000, "AT+QIRD=%d,1024\r\n", l_i32SocketID); break; } case HIDO_EVENT_EXIT: { HIDO_ATLiteCmdSendOver(_pstATDevice); break; } case HIDO_AT_EVENT_ERROR: { Socket_NoRecvData(l_i32SocketID); Socket_OnClosed(l_i32SocketID); HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); break; } case HIDO_AT_EVENT_OK: { HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); break; } case EC600S_EVENT_READ: { HIDO_UINT32 u32ReadLen = 0; HIDO_DataStruct *pstData = (HIDO_DataStruct *) _pArg; HIDO_UINT8 *pu8IPData = HIDO_NULL; if (HIDO_UtilParseFormat((HIDO_UINT8 *) pstData->m_pData, pstData->m_u32Len, "+QIRD: %d\r\n", &u32ReadLen) != 1) { Socket_NoRecvData(l_i32SocketID); break; } if (0 == u32ReadLen) { Socket_NoRecvData(l_i32SocketID); break; } if (HIDO_UtilParseFormat((HIDO_UINT8 *) pstData->m_pData, pstData->m_u32Len, "+QIRD: %*\r\n%e", &pu8IPData) != 2) { Socket_NoRecvData(l_i32SocketID); break; } Socket_RecvData(l_i32SocketID, pu8IPData, u32ReadLen); //HIDO_Debug("Socket[%u] Recv %u {", l_i32SocketID, u32ReadLen); //HIDO_DebugHex(pu8IPData, u32ReadLen); //HIDO_Debug("}\r\n"); Socket_OnRecv(l_i32SocketID); break; } default: { return HIDO_EVENT_NO_PROC; } } return HIDO_EVENT_OK; } /******************************************************************************* * State Name : EC600SSocketSendData * Parent State : Ready * Description : * Author : ¶Å¼ü * Modified Date: : 2018-05-01 *******************************************************************************/ HIDO_FSM_STATE_IMPLEMENT(EC600SSocketSendData, HIDO_FSM_STATE(EC600SIPReady), HIDO_NULL) { static HIDO_INT32 l_i32SocketID = 0; static HIDO_VLQMemberStruct *l_pstMember = HIDO_NULL; HIDO_ATLiteDeviceStruct *pstATDevice = (HIDO_ATLiteDeviceStruct *) _pstFSM->m_pPrivateData; HIDO_VLQStruct *pstSendQueue = HIDO_NULL; switch (_u32Event) { case HIDO_EVENT_ENTRY: { l_i32SocketID = (HIDO_INT32) _pArg; pstSendQueue = Socket_GetSocketSendQueue(l_i32SocketID); if(HIDO_NULL == pstSendQueue) { break; } l_pstMember = HIDO_VLQGetDequeueMember(pstSendQueue); if(HIDO_NULL == l_pstMember) { break; } HIDO_ATLiteCmdSend(pstATDevice, AT_GENERAL_TIMEOUT_TIME, "AT+QISEND=%d,%u\r\n", l_i32SocketID, l_pstMember->m_u32DataLen); break; } case HIDO_EVENT_EXIT: { l_pstMember = HIDO_NULL; HIDO_ATLiteCmdSendOver(pstATDevice); break; } case HIDO_AT_EVENT_OK: { //HIDO_Debug("OK\r\n"); break; } case HIDO_AT_EVENT_ERROR: { Socket_OnClosed(l_i32SocketID); HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); break; } case EC600S_EVENT_ACK: { if(HIDO_ATLiteGetDebugFlag() == HIDO_TRUE) { HIDO_DebugHex((HIDO_UINT8 *)l_pstMember->m_pDataAddr, l_pstMember->m_u32DataLen); } HIDO_ATLiteDataSend(pstATDevice, 20000, (HIDO_UINT8 *)l_pstMember->m_pDataAddr, l_pstMember->m_u32DataLen); break; } case EC600S_EVENT_SEND_OK: { pstSendQueue = Socket_GetSocketSendQueue(l_i32SocketID); if (HIDO_NULL == pstSendQueue) { break; } HIDO_VLQDequeue(pstSendQueue, l_pstMember); l_abSocketUnAck[l_i32SocketID] = HIDO_TRUE; l_au32SocketUnAckTick[l_i32SocketID] = HIDO_TimerGetTick(); l_au32SocketSendTick[l_i32SocketID] = l_au32SocketUnAckTick[l_i32SocketID]; HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); break; } case EC600S_EVENT_SEND_FAIL: { Socket_OnClosed(l_i32SocketID); HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); break; } default: { return HIDO_EVENT_NO_PROC; } } return HIDO_EVENT_OK; } /******************************************************************************* * State Name : EC600SSocketSendData * Parent State : Ready * Description : * Author : ¶Å¼ü * Modified Date: : 2018-05-01 *******************************************************************************/ HIDO_FSM_STATE_IMPLEMENT(EC600SSocketSendAck, HIDO_FSM_STATE(EC600SIPReady), HIDO_NULL) { static HIDO_INT32 l_i32SocketID = 0; static HIDO_BOOL l_bIsAck = HIDO_FALSE; HIDO_ATLiteDeviceStruct *pstATDevice = (HIDO_ATLiteDeviceStruct *) _pstFSM->m_pPrivateData; HIDO_UINT32 u32FSMTimerID = ((ST_EC600SDriverData *)pstATDevice->m_pUserData)->m_u32FSMTimerID; switch (_u32Event) { case HIDO_EVENT_ENTRY: { l_i32SocketID = (HIDO_INT32) _pArg; l_bIsAck = HIDO_FALSE; l_au32SocketUnAckTick[l_i32SocketID] = HIDO_TimerGetTick(); HIDO_ATLiteCmdSend(pstATDevice, AT_GENERAL_TIMEOUT_TIME, "AT+QISEND=%d,0\r\n", l_i32SocketID); break; } case HIDO_EVENT_EXIT: { HIDO_ATLiteCmdSendOver(pstATDevice); HIDO_TimerCancel(u32FSMTimerID); break; } case HIDO_AT_EVENT_OK: { if(HIDO_TRUE == l_bIsAck) { l_abSocketUnAck[l_i32SocketID] = HIDO_FALSE; HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); } else { if((HIDO_TimerGetTick() - l_au32SocketSendTick[l_i32SocketID]) >= HIDO_TIMER_TICK_S(90)) { Socket_OnClosed(l_i32SocketID); l_abSocketUnAck[l_i32SocketID] = HIDO_FALSE; } HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); } break; } case HIDO_AT_EVENT_ERROR: { l_abSocketUnAck[l_i32SocketID] = HIDO_FALSE; Socket_OnClosed(l_i32SocketID); HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); break; } case EC600S_EVENT_SEND: { HIDO_UINT32 u32Total = 0; HIDO_UINT32 u32Ack = 0; HIDO_UINT32 u32UnAck = 0; HIDO_DataStruct *pstData = (HIDO_DataStruct *) _pArg; if (HIDO_UtilParseFormat((HIDO_UINT8 *) pstData->m_pData, pstData->m_u32Len, "+QISEND: %d,%d,%d\r\n", &u32Total, &u32Ack, &u32UnAck) != 3) { Socket_OnClosed(l_i32SocketID); HIDO_FSMStateChange(_pstFSM, HIDO_FSM_STATE(EC600SIPPoll), HIDO_NULL); break; } if(0 == u32UnAck) { l_bIsAck = HIDO_TRUE; } else { l_bIsAck = HIDO_FALSE; } break; } case EC600S_EVENT_DELAY: { HIDO_ATLiteCmdSend(pstATDevice, AT_GENERAL_TIMEOUT_TIME, "AT+QISEND=%d,0\r\n", l_i32SocketID); break; } default: { return HIDO_EVENT_NO_PROC; } } return HIDO_EVENT_OK; } HIDO_INT32 EC600SSocket_Poll(HIDO_ATLiteDeviceStruct *_pstATDevice) { static HIDO_INT32 i32LastSocketIndex = 0; HIDO_INT32 i = 0; HIDO_INT32 i32SocketIndex = 0; HIDO_VLQStruct *pstSendQueue = HIDO_NULL; HIDO_UINT32 u32CurTick = HIDO_TimerGetTick(); /* ÏÈ´¦ÀíÁ¬½Ó¡¢¶Ï¿ª¡¢Êý¾Ý½ÓÊÕ */ for(i32SocketIndex = 0; i32SocketIndex < SOCKET_NUM; i32SocketIndex++) { if(SOCKET_STATE_CONNECT == Socket_GetSocketState(i32SocketIndex)) { Socket_SetSocketState(i32SocketIndex, SOCKET_STATE_CLOSE_BEFORE_CONNECT); HIDO_FSMStateChange(_pstATDevice->m_pstFSM, HIDO_FSM_STATE(EC600SSocketClose), (HIDO_VOID *)(HIDO_UINT32)i32SocketIndex); return HIDO_OK; } else if(SOCKET_STATE_CLOSE_BEFORE_CONNECT == Socket_GetSocketState(i32SocketIndex)) { HIDO_FSMStateChange(_pstATDevice->m_pstFSM, HIDO_FSM_STATE(EC600SSocketConnect), (HIDO_VOID *)(HIDO_UINT32)i32SocketIndex); return HIDO_OK; } else if (SOCKET_STATE_CLOSE == Socket_GetSocketState(i32SocketIndex)) { HIDO_FSMStateChange(_pstATDevice->m_pstFSM, HIDO_FSM_STATE(EC600SSocketClose), (HIDO_VOID *) (HIDO_UINT32) i32SocketIndex); return HIDO_OK; } if(HIDO_TRUE == Socket_HasRecvData(i32SocketIndex)) { HIDO_FSMStateChange(_pstATDevice->m_pstFSM, HIDO_FSM_STATE(EC600SSocketRecvData), (HIDO_VOID *)(HIDO_UINT32)i32SocketIndex); return HIDO_OK; } #if 0 /* Ôݲ»Ê¹Ó÷¢ËÍÈ·Èϼì²é,Ó°Ïì·¢ËÍËÙÂÊ */ if (HIDO_TRUE == l_abSocketUnAck[i32SocketIndex]) { if ((u32CurTick - l_au32SocketUnAckTick[i32SocketIndex]) >= 10) { HIDO_FSMStateChange(_pstATDevice->m_pstFSM, HIDO_FSM_STATE(EC600SSocketSendAck), (HIDO_VOID *)(HIDO_UINT32)i32SocketIndex); return HIDO_OK; } else { return HIDO_ERR; } } #endif } /* ²ÉÓþùºâµÄ·½Ê½´¦ÀíÊý¾Ý·¢ËÍ */ i32SocketIndex = (i32LastSocketIndex + 1) % SOCKET_NUM; for(i = 0; i < SOCKET_NUM; i++) { if(SOCKET_STATE_CONNECTED == Socket_GetSocketState(i32SocketIndex)) { pstSendQueue = Socket_GetSocketSendQueue(i32SocketIndex); if(pstSendQueue != HIDO_NULL) { if(HIDO_VLQGetDequeueMember(pstSendQueue) != HIDO_NULL) { i32LastSocketIndex = i32SocketIndex; HIDO_FSMStateChange(_pstATDevice->m_pstFSM, HIDO_FSM_STATE(EC600SSocketSendData), (HIDO_VOID *)(HIDO_UINT32)i32SocketIndex); return HIDO_OK; } } } i32SocketIndex = (i32SocketIndex + 1) % SOCKET_NUM; } return HIDO_ERR; }