#include "huslib.h" #include "huslibex.h" HVspHandler::HVspHandler() { m_pRecvBuffer = new HStreamBuffer(HH_VSP_MAX_COMMAND_PACKET_SIZE); m_nBodyOffset = -1; m_nBodySize = -1; m_nRemainBodySize = -1; m_pSendBuffer = new HStreamBuffer(HH_VSP_MAX_COMMAND_PACKET_SIZE); } HVspHandler::~HVspHandler() { delete m_pRecvBuffer; delete m_pSendBuffer; } int HVspHandler::SendCommand(const HString & strCommand) { if (m_pSendBuffer->RemainSize() < strCommand.GetLength() + 5) return -1; size_t nLength = sprintf(m_pSendBuffer->Tail(), "VSP %d %s", strCommand.GetLength(), strCommand.psz()); m_pSendBuffer->MoveTail(nLength); return SendBufferCommand(); } int HVspHandler::SendBinary(const char * pData, size_t nSize) { if (m_pSendBuffer->StoredSize() == 0) { int nSentSize = SendToTransport(pData, nSize); if (nSentSize < 0) return -1; if (nSentSize != nSize) m_pSendBuffer->Store(pData + nSentSize, nSize - nSentSize); return nSentSize; } m_pSendBuffer->Store(pData, nSize); return SendBufferCommand(); } int HVspHandler::SendBufferCommand() { //if (m_pSendBuffer->StoredSize() == 0) // return SOCKET_ERROR; int nSentSize = SendToTransport(m_pSendBuffer->Head(), m_pSendBuffer->StoredSize()); if (nSentSize <= 0) return nSentSize; m_pSendBuffer->Pop(nSentSize); return nSentSize; } void HVspHandler::OnReceivedStatusFromTransport(int nStatus) { if (nStatus == HTransport::T_BEGIN_TRANSPORT) { OnInitialize(true); } else if (nStatus == HTransport::T_FAILED_BEGIN) { OnInitialize(false); } else if (nStatus == HTransport::T_END_TRANSPORT) { OnTerminate(); } } int HVspHandler::OnReceivedFromTransport(const char * pData, int nSize) { if (m_pRecvBuffer->Store(pData, nSize) == false) { HLOGF(HLOG_ERROR, "[ERROR], VspHdler, Failed to insert data, buffer = %d, stored = %d, recv size = %d\n", m_pRecvBuffer->Size(), m_pRecvBuffer->StoredSize(), nSize); return -1; // close connection } if (m_nRemainBodySize > 0) { int nResult = ProcPacketBodyReceive(); if (nResult < 0) return -1; // close connection else if (nResult == 0) return 0; } for (;;) { if (m_pRecvBuffer->StoredSize() < 6) return 0; // verify protocol name if (m_pRecvBuffer->MemCmp("VSP ", 4) != 0) { HLOGF(HLOG_WARNING, "[WARN], VspHdler, Invalid VSP protocol, buffer = %d, stored = %d, recv size = %d\n", m_pRecvBuffer->Size(), m_pRecvBuffer->StoredSize(), nSize); HLOGD(HLOG_WARNING, m_pRecvBuffer->Head(), m_pRecvBuffer->StoredSize(), false); return -1; // close connection } // extract body size m_nBodyOffset = m_pRecvBuffer->Find(' ', 4); if (m_nBodyOffset < 0) return 0; // receive remain packet if (m_nBodyOffset > 13) // 9 + 4 { HLOGF(HLOG_WARNING, "[WARN], VspHdler, Invalid VSP body size, buffer = %d, stored = %d, recv size = %d\n", m_pRecvBuffer->Size(), m_pRecvBuffer->StoredSize(), nSize); HLOGD(HLOG_WARNING, m_pRecvBuffer->Head(), m_pRecvBuffer->StoredSize(), false); return -1; // close connection } HString strBodySize(m_pRecvBuffer->Head() + 4, m_nBodyOffset - 4); m_nBodySize = strBodySize; m_nBodyOffset++; //if (m_nBodySize + nPos > HH_VSP_MAX_COMMAND_PACKET_SIZE) //{ //... extra size packet //} int nResult = ProcPacketBodyReceive(); if (nResult < 0) return -1; else if (nResult == 0) return 0; } return -1; // close connection } int HVspHandler::ProcPacketBodyReceive() { int nResult = 0; m_nRemainBodySize = m_nBodySize - (m_pRecvBuffer->StoredSize() - m_nBodyOffset); if (m_nRemainBodySize <= 0) { nResult = OnReceivedCommand(m_pRecvBuffer->Head() + m_nBodyOffset, m_nBodySize); if (nResult < 0) return -1; if (m_nRemainBodySize < 0) nResult = 1; else nResult = 0; m_pRecvBuffer->PopAndRewind(m_nBodyOffset + m_nBodySize); m_nBodyOffset = -1; m_nBodySize = -1; m_nRemainBodySize = -1; } return nResult; } int HVspHandler::OnSendRetryToTransport() { return SendBufferCommand(); } bool HVspHandler::OnPrepareReceive() { if (m_pRecvBuffer->RemainSize() < g_nSocketReceiveBlockSize) return false; return true; }