/* CPPDOC_BEGIN_EXCLUDE */ /*************************************************************************** OxYD Socket v0.1 File : OxYDSocketHelper.cpp Versions : - v0.1 (20/01/2003) : Initial release --------------------------------------------------------------------------- Copyright (C) 2003 Grégory WILMES -- Engage Security (http://www.engagesecurity.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ***************************************************************************/ /* CPPDOC_END_EXCLUDE */ #include "stdafx.h" #include "OxYDSocketHelper.h" /** * The constructor. Initializes all variables to their default value. */ COxYDSocketHelper::COxYDSocketHelper() { m_nPacketNumber = 0; } /** * The destructor. */ COxYDSocketHelper::~COxYDSocketHelper() { // Nothing do to ? } /** * Encode data and send it. * * @param szData const LPSTR : Data to send * @param nDataLength int : Data length * @param nMessage int : Message number * @param nPacketNumber int : Packet number * @return BOOL */ BOOL COxYDSocketHelper::Send(const LPSTR szData, int nDataLength, int nMessage, int nPacketNumber) { CString strPacket; Encode(szData, nDataLength, nMessage, nPacketNumber, strPacket); m_nPacketNumber++; // Send our packet (string format) return(SendRaw(strPacket)); } /** * Help to encode data to hexa string with extra parameters. * * @param szData const LPSTR : Data to encode * @param nDataLength int : Data length * @param nMessage int : Message number * @param nPacketNumber int : Packet number * @param strPacket CString& : Data encoded/converted to hexa string * @return BOOL */ BOOL COxYDSocketHelper::Encode(const LPSTR szData, int nDataLength, int nMessage, int nPacketNumber, CString &strPacket) { CString strTmp; if(nDataLength == -1) nDataLength = strlen(szData); if(nPacketNumber == -1) nPacketNumber = m_nPacketNumber; // Convert data to hexa string ConvDataToHex(szData, nDataLength, strTmp); // Packet format : [Packet number]N[Message]M[Data size]T[Data] strPacket.Format("%dN%dM%dT%s", nPacketNumber, nMessage, strlen((LPSTR)(LPCSTR)strTmp), strTmp); return TRUE; } /** * Receive hexa string and decode it. * * @param szData LPSTR : Data * @param nDataLength int : Data buffer length * @param nMessage int : Message number * @param nPacketNumber int : Packet number * @return BOOL */ BOOL COxYDSocketHelper::Receive(LPSTR szData, int &nDataLength, int &nMessage, int &nPacketNumber) { CString strTmp; if(ReceiveRaw(strTmp)) return(Decode(strTmp, szData, nDataLength, nMessage, nPacketNumber)); return FALSE; } /** * Help to decode hexa string with extra parameters to data. * * @param strTmp CString : Hexa string to decode * @param szData LPSTR : Data buffer * @param nDataLength int : Data buffer length * @param nMessage int : Message number * @param nPacketNumber int : Packet number * @return BOOL */ BOOL COxYDSocketHelper::Decode(CString strTmp, LPSTR szData, int &nDataLength, int &nMessage, int &nPacketNumber) { CString strPacketNumberTmp, strMessageTmp, strDataLengthTmp; int nPosPacketNumberTmp, nPosMessageTmp, nPosDataLengthTmp; int nPacketNumberTmp, nMessageTmp, nDataLengthTmp; ZeroMemory(szData, nDataLength); if(strlen(strTmp) > 0) { // Packet format : [Packet number]N[Message]M[Data size]T[Data] if( (nPosPacketNumberTmp = strTmp.Find('N')) >= 1 ) { strPacketNumberTmp = strTmp.Left(nPosPacketNumberTmp); nPacketNumberTmp = atoi((LPSTR)(LPCSTR)strPacketNumberTmp); if( (nPosMessageTmp = strTmp.Find('M', nPosPacketNumberTmp)) >= 1 ) { strMessageTmp = strTmp.Mid(nPosPacketNumberTmp + 1, nPosMessageTmp -nPosPacketNumberTmp -1); nMessageTmp = atoi((LPSTR)(LPCSTR)strMessageTmp); if( (nPosDataLengthTmp = strTmp.Find('T', nPosMessageTmp)) >= 1 ) { strDataLengthTmp = strTmp.Mid(nPosMessageTmp + 1, nPosDataLengthTmp -nPosMessageTmp -1); nDataLengthTmp = atoi((LPSTR)(LPCSTR)strDataLengthTmp); strTmp = strTmp.Mid(nPosDataLengthTmp + 1); if( nDataLengthTmp != (int)(strlen(strTmp)) ) { m_nLastError = ERROR__UNCOMPLETE_PACKET; return FALSE; } if(ConvHexToData(strTmp, szData, nDataLength) > 0) { nDataLength = nDataLengthTmp / 2; // Hexa... nMessage = nMessageTmp; nPacketNumber = nPacketNumberTmp; return TRUE; } } } } m_nLastError = ERROR__CORRUPTED_PACKET_HEADER; } else m_nLastError = ERROR__EMPTY_PACKET; return FALSE; } /** * Get last error string from error number. * * @param nLastError int : Error number (-1 = last error) * @return CString : Last error (string format) */ CString COxYDSocketHelper::FormatMessage(int nLastError) { CString strLastError; int nLastErrorTmp; nLastErrorTmp = nLastError; if(nLastError == -1) nLastError = m_nLastError; if(nLastError == ERROR__UNCOMPLETE_PACKET) strLastError = "Uncomplete packet"; else if(nLastError == ERROR__CORRUPTED_PACKET_HEADER) strLastError = "Corrupted packet header"; else if(nLastError == ERROR__EMPTY_PACKET) strLastError = "Empty packet (no header and no data)"; else if(nLastError == ERROR__NULL_POINTER) strLastError = "Null pointer"; else strLastError = COxYDSocket::FormatMessage(nLastErrorTmp); return strLastError; } /** * Convert data to hexa string. * * @param szData LPSTR : Data * @param nDataLength int : Data length * @param strHex CString& : Data converted to hexa string * @return int */ int COxYDSocketHelper::ConvDataToHex(LPSTR szData, int nDataLength, CString &strHex) { CString strTmp, strHexTmp; int nPos; if(szData != NULL) { strTmp.Empty(); for(nPos = 0; nPos < nDataLength; nPos++) { strHexTmp.Format("%02X", (unsigned char)szData[nPos]); strTmp += strHexTmp; } strHex = strTmp; return nPos; } m_nLastError = ERROR__NULL_POINTER; return -1; } /** * Convert hexa string to data. * * @param strHex CString : Hexa string * @param szData LPSTR : Hexa string converted to data * @param nDataLengthMax int : Data buffer length * @return int */ int COxYDSocketHelper::ConvHexToData(CString strHex, LPSTR szData, int nDataLengthMax) { CString strTmp, strTmp2; int nPos, nPosTmp = 0, nDataLength; unsigned char c; if(szData != NULL) { strTmp = strHex; nDataLength = strlen(strTmp); for(nPos = 0; nPos < nDataLength; nPos = nPos + 2) { if(nPosTmp == nDataLengthMax) break; strTmp2 = strTmp.Mid(nPos, 2); if( (strTmp2[1] >= 'a') && (strTmp2[1] <= 'f') ) c = (strTmp2[1] -'a') + 10; else if( (strTmp2[1] >= 'A') && (strTmp2[1] <= 'F') ) c = (strTmp2[1] -'A') + 10; else if( (strTmp2[1] >= '0') && (strTmp2[1] <= '9') ) c = strTmp2[1] -'0'; if( (strTmp2[0] >= 'a') && (strTmp2[0] <= 'f') ) c += ((strTmp2[0] -'a') + 10) << 4; else if( (strTmp2[0] >= 'A') && (strTmp2[0] <= 'F') ) c += ((strTmp2[0] -'A') + 10) << 4; else if( (strTmp2[0] >= '0') && (strTmp2[0] <= '9') ) c += (strTmp2[0] -'0') << 4; szData[nPosTmp++] = c; } szData[nPosTmp] = 0; return nPosTmp; } m_nLastError = ERROR__NULL_POINTER; return -1; }