diff -r c892c53c664e -r 9d2210c8eed2 connectivity/com.nokia.tcf/native/TCFNative/TCFCommSerial/RealSerialComm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectivity/com.nokia.tcf/native/TCFNative/TCFCommSerial/RealSerialComm.cpp Mon Apr 06 15:18:48 2009 -0500 @@ -0,0 +1,886 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +// RealSerialComm.cpp: implementation of the CRealSerialComm class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "RealSerialComm.h" +//#include "pn_const.h" +//#include "OSTConstants.h" +#include "Connection.h" + +#ifdef _DEBUG +static char sLogMsg[3000]; +#endif +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// +#ifdef _DEBUG +#define LogErrorText(err) { if (err > 0) GetErrorText(err); } +#define LogErrorText2(err) { if (err > 0) GetErrorText2(err); } +#else +#define LogErrorText(err) {} +#define LogErrorText2(err) {} +#endif + +#ifdef _DEBUG +#define DUMPCOMSTAT(x) DumpComStat(x) +#define DUMPCOMSTATP(x) DumpComStatP(x) +#else +#define DUMPCOMSTAT(x) +#define DUMPCOMSTATP(x) +#endif + +CRealSerialComm::CRealSerialComm() +{ +#ifdef _DEBUG + if (gDoLogging) + { + FILE* f = fopen("c:\\tcf\\rscommlog.txt", "at"); + fprintf(f, "CRealSerialComm::CRealSerialComm() (default constructor)\n"); + fclose(f); + } +#endif + m_hSerial = INVALID_HANDLE_VALUE; + m_serialPortName[0] = 0; + m_pBuffer = NULL; + m_ProcDebugLog = NULL; + +} +CRealSerialComm::CRealSerialComm(ConnectData* connectSettings, DWORD connectionId, CBaseProtocol* protocol) +{ +#ifdef _DEBUG + if (gDoLogging) + { + FILE* f = fopen("c:\\tcf\\rscommlog.txt", "at"); + fprintf(f, "connectSettings=%x connectionId=%d, protocol=%x\n", connectSettings, connectionId, protocol); + fclose(f); + } +#endif + m_hSerial = INVALID_HANDLE_VALUE; + m_serialPortName[0] = 0; + m_pBuffer = NULL; + + m_connId = connectionId; + m_Protocol = protocol; + + m_ConnectSettings = new ConnectData(); + memcpy(m_ConnectSettings, connectSettings, sizeof(ConnectData)); + +#if (defined(LOG_COMM) || defined(LOG_PROCCOMM)) && defined(_DEBUG) + if (gDoLogging) + { + m_CommDebugLog = new TCDebugLog("TCF_Comm", connectionId, 2000L); + m_ProcDebugLog = new TCDebugLog("TCF_CommP", connectionId, 2000L); + } +#endif +} +CRealSerialComm::~CRealSerialComm() +{ +#ifdef _DEBUG + if (gDoLogging) + { + FILE* f = fopen("c:\\tcf\\rscommlog.txt", "at"); + fprintf(f, "CRealSerialComm::~CRealSerialComm()\n"); + fclose(f); + } +#endif + if (m_hSerial != INVALID_HANDLE_VALUE) + ::CloseHandle(m_hSerial); + + if (m_pBuffer) + delete[] m_pBuffer; + +} + +long CRealSerialComm::OpenPort() +{ + COMMLOGOPEN(); + COMMLOGS("CRealSerialComm::OpenPort\n"); + + long err = TCAPI_ERR_NONE; + + char* comPort = m_ConnectSettings->realSerialSettings.comPort; + DWORD baudRate = m_ConnectSettings->realSerialSettings.baudRate; + DWORD dataBits = m_ConnectSettings->realSerialSettings.dataBits; + eParity parity = m_ConnectSettings->realSerialSettings.parity; + eStopBits stopBits = m_ConnectSettings->realSerialSettings.stopBits; + eFlowControl flow = m_ConnectSettings->realSerialSettings.flowControl; + + COMMLOGA2("CRealSerialComm::OpenPort comPort=%s baudRate=%d\n", comPort, baudRate); + COMMLOGA2("CRealSerialComm::OpenPort dataBits=%d parity=%d\n", dataBits, parity); + COMMLOGA2("CRealSerialComm::OpenPort stopBits=%d flow=%d\n", stopBits, flow); + + // fill in DCB + m_dcb.DCBlength = sizeof(DCB); + m_dcb.BaudRate = baudRate; + m_dcb.ByteSize = dataBits; + + // parity + switch(parity) + { + default: + case eParityNone: + m_dcb.fParity = FALSE; + m_dcb.Parity = NOPARITY; + break; + case eParityEven: + m_dcb.fParity = TRUE; + m_dcb.Parity = EVENPARITY; + break; + case eParityOdd: + m_dcb.fParity = TRUE; + m_dcb.Parity = ODDPARITY; + break; + } + + // stop bits + switch(stopBits) + { + default: + case eStopBits1: + m_dcb.StopBits = ONESTOPBIT; + break; + case eStopBits15: + m_dcb.StopBits = ONE5STOPBITS; + break; + case eStopBits2: + m_dcb.StopBits = TWOSTOPBITS; + break; + } + + // flow control + switch(flow) + { + default: + case eFlowControlNone: + m_dcb.fRtsControl = RTS_CONTROL_DISABLE; + m_dcb.fOutxCtsFlow = FALSE; + m_dcb.fInX = m_dcb.fOutX = FALSE; + break; + case eFlowControlHW: + m_dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + m_dcb.fOutxCtsFlow = TRUE; + m_dcb.fInX = m_dcb.fOutX = FALSE; + break; + case eFlowControlSW: + m_dcb.fRtsControl = RTS_CONTROL_DISABLE; + m_dcb.fOutxCtsFlow = FALSE; + m_dcb.fInX = m_dcb.fOutX = TRUE; + m_dcb.XonChar = '\021'; // Ctrl-Q; + m_dcb.XoffChar = '\023'; // Ctrl-S; + m_dcb.XonLim = 100; + m_dcb.XoffLim = 100; + break; + } + + // other things in DCB + m_dcb.fDtrControl = DTR_CONTROL_ENABLE; + m_dcb.fDsrSensitivity = FALSE; + m_dcb.fBinary = TRUE; + m_dcb.fNull = FALSE; + m_dcb.fAbortOnError = TRUE; // reads & writes will terminate with errors if one occurs + + // translate serial port + char p[20]; char* pp = p; + strncpy(p, comPort, 20); + int len = (int)strlen(p); + for (int i = 0; i < len; i++) + { + p[i] = toupper(p[i]); + } + if (strncmp(p, "COM", 3) == 0) + { + pp+=3; + } + int val = atoi((const char*)pp); + if (val == INT_MIN || val == INT_MAX) + { + err = TCAPI_ERR_INVALID_MEDIA_DATA; + } + else + { + // must translate for CreatFile + _snprintf(m_serialPortName, MAX_COMPORT_SIZE, "\\\\.\\COM%d", val); + } + + + if (err == TCAPI_ERR_NONE) + { + m_hSerial = CreateFile(m_serialPortName, + GENERIC_READ|GENERIC_WRITE, // dwDesiredAccess = read & write + 0, // dwSharedMode = 0 ==> device not shared + NULL, // lpSecurityAttributes = NULL ==> not inheritable + OPEN_EXISTING, // dwCreationDisposition ==> required for devices + 0, // dwFlagsAndAttributes ==> no special flags or attributes (not overlapped) + NULL ); // hTemplateFile = NULL ==> required for devices + + if (m_hSerial != INVALID_HANDLE_VALUE) + { + // TODO: this is really not needed as we're not doing overlapped IO + // and we're not creating an event nor waiting on that event + if (!SetCommMask(m_hSerial, EV_RXCHAR)) + { + ::CloseHandle(m_hSerial); + m_hSerial = INVALID_HANDLE_VALUE; + m_lastCommError = GetLastError(); + err = TCAPI_ERR_WHILE_CONFIGURING_MEDIA; + } + else + { + // no error from SetCommMask + if (!SetupComm(m_hSerial,MAX_MESSAGE_LENGTH,MAX_SERIAL_MESSAGE_BUFFER_LENGTH)) + { + CloseHandle(m_hSerial); + m_hSerial = INVALID_HANDLE_VALUE; + m_lastCommError = GetLastError(); + err = TCAPI_ERR_WHILE_CONFIGURING_MEDIA; + } + else + { + // no error from SetupComm + // Get rid of any junk that might be sitting there. + PurgeComm( m_hSerial, PURGE_TXABORT | PURGE_RXABORT | + PURGE_TXCLEAR | PURGE_RXCLEAR ); + + // Using these settings, the ReadFile command will return immediately + // rather than waiting for a timeout. + COMMTIMEOUTS lclCommTimeOuts; + + lclCommTimeOuts.ReadIntervalTimeout = MAXDWORD; // we don't care about time between chars + lclCommTimeOuts.ReadTotalTimeoutMultiplier = 100; + lclCommTimeOuts.ReadTotalTimeoutConstant = 0; + lclCommTimeOuts.WriteTotalTimeoutMultiplier = 100; + lclCommTimeOuts.WriteTotalTimeoutConstant = 0; + + if (!SetCommTimeouts( m_hSerial, &lclCommTimeOuts )) + { + CloseHandle(m_hSerial); + m_hSerial = INVALID_HANDLE_VALUE; + m_lastCommError = GetLastError(); + err = TCAPI_ERR_WHILE_CONFIGURING_MEDIA; + } + else + { + // no error from SetCommTimeouts + err = SetDCB(); + if (err != TCAPI_ERR_NONE) + { + CloseHandle(m_hSerial); + m_hSerial = INVALID_HANDLE_VALUE; + } + else + { + // no error from SetDCB + err = TCAPI_ERR_NONE; + m_numberBytes = 0; + m_lastCommError = 0; + m_isConnected = true; + m_pBuffer = new BYTE[MAX_SERIAL_MESSAGE_BUFFER_LENGTH]; + } + } + } + } + } + else + { + // error from CreateFile + // couldn't open serial port + m_lastCommError = GetLastError(); + err = TCAPI_ERR_WHILE_CONFIGURING_MEDIA; + } + } + + COMMLOGA2("CRealSerialComm::OpenPort err=%d osError=%d\n", err, m_lastCommError); + LogErrorText(m_lastCommError); +// if (m_lastCommError > 0) +// LogErrorText(m_lastCommError); + COMMLOGCLOSE(); + return err; +} + +long CRealSerialComm::SetDCB() +{ + // assumes serial port is open + long err = TCAPI_ERR_NONE; + if (m_hSerial == INVALID_HANDLE_VALUE) + return err; + + // setup DCB + DCB lcldcb; + lcldcb.DCBlength = sizeof(DCB); + + if (!GetCommState( m_hSerial, &lcldcb )) + { + m_lastCommError = GetLastError(); + err = TCAPI_ERR_WHILE_CONFIGURING_MEDIA; + } + +// LogDCB(pInfo); + // copy only the ones that Connect() set initially + lcldcb.BaudRate = m_dcb.BaudRate; + lcldcb.ByteSize = m_dcb.ByteSize; + lcldcb.Parity = m_dcb.Parity; + lcldcb.StopBits = m_dcb.StopBits; + lcldcb.fRtsControl = m_dcb.fRtsControl; + lcldcb.fOutxCtsFlow = m_dcb.fOutxCtsFlow; + lcldcb.fDtrControl = m_dcb.fDtrControl; + lcldcb.fDsrSensitivity = m_dcb.fDsrSensitivity; + lcldcb.fInX = m_dcb.fInX; + lcldcb.fOutX = m_dcb.fOutX; + lcldcb.XonChar = m_dcb.XonChar; + lcldcb.XoffChar = m_dcb.XoffChar; + lcldcb.XonLim = m_dcb.XonLim; + lcldcb.XoffLim = m_dcb.XoffLim; + lcldcb.fBinary = m_dcb.fBinary; + lcldcb.fParity = m_dcb.fParity; + lcldcb.fNull = m_dcb.fNull; + lcldcb.fAbortOnError = m_dcb.fAbortOnError; + + // DCB has been changed + // If setting the port went well then we are connected properly! + if (!SetCommState( m_hSerial, &lcldcb)) + { + m_lastCommError = GetLastError(); + err = TCAPI_ERR_WHILE_CONFIGURING_MEDIA; + } + + return err; +} + +long CRealSerialComm::ClosePort() +{ + COMMLOGOPEN(); + COMMLOGS("CRealSerialComm::ClosePort\n"); + + long err = TCAPI_ERR_NONE; + + if (!IsConnected()) + { + + err = TCAPI_ERR_MEDIA_NOT_OPEN; + } + else if (m_hSerial != INVALID_HANDLE_VALUE) + { + // disable event notification + SetCommMask( m_hSerial, 0 ); + + // drop DTR + EscapeCommFunction( m_hSerial, CLRDTR ); + + // purge any outstanding reads/writes and close device handle + PurgeComm( m_hSerial, + PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); + + CloseHandle( m_hSerial ); + m_hSerial = INVALID_HANDLE_VALUE; + + if (m_pBuffer) + { + delete[] m_pBuffer; + m_pBuffer = NULL; + } + m_isConnected = false; + } + + COMMLOGCLOSE(); + return err; +} + +void CRealSerialComm::DeleteMsg(DWORD inMsgLength) +{ + if (!IsConnected()) + return; + // inMsgLength includes header + // delete from beginning of buffer + if (inMsgLength == 0) + return; + if (m_numberBytes > 0 && m_numberBytes >= inMsgLength) + { + size_t moveLen = m_numberBytes - inMsgLength; + if (moveLen > 0) + memcpy(&m_pBuffer[0], &m_pBuffer[inMsgLength], moveLen); + m_numberBytes -= inMsgLength; + } +} + +long CRealSerialComm::SendDataToPort(DWORD inSize, const void *inData) +{ + + long err = TCAPI_ERR_NONE; + DWORD lclNumBytes=0; + COMMLOGOPEN(); + COMMLOGS("CRealSerialComm::SendDataToPort\n"); + COMMLOGCLOSE(); + if (!IsConnected()) + { + + COMMLOGOPEN(); + COMMLOGS("CRealSerialComm::SendDataToPort notConnected\n"); + COMMLOGCLOSE(); + return TCAPI_ERR_MEDIA_NOT_OPEN; + } + + if (WriteFile(m_hSerial, inData, inSize, &lclNumBytes, NULL)) + { + // we were successful, but did we send all data? (i.e., a timeout occurred) + // we are not doing overlapped I/O so if not all data went, then we timed out + // and there was some kind of error + if (lclNumBytes != inSize) + { + COMMLOGOPEN(); + COMMLOGA3("CRealSerialComm::SendDataToPort WriteFile not all bytes sent: lclNumBytes=%d inSize=%d err=%d\n", lclNumBytes, inSize, GetLastError()); + COMMLOGCLOSE(); + + COMSTAT lclComStat; + DWORD lclErrorFlags = 0; + if (!ClearCommError(m_hSerial, &lclErrorFlags, &lclComStat)) + { + // clear comm error returned error (this doesn't normally happen if the handle is valid and port is still open) + m_lastCommError = GetLastError(); + err = TCAPI_ERR_COMM_ERROR; + COMMLOGOPEN(); + COMMLOGA1("CRealSerialComm::SendDataToPort ClearCommError failed=%d\n", m_lastCommError); + COMMLOGCLOSE(); + } + else + { + // clear comm error returned OK + // check error flags + if (lclErrorFlags) + { + // there really was an error + m_lastCommError = lclErrorFlags; + err = TCAPI_ERR_COMM_ERROR; + COMMLOGOPEN(); + COMMLOGA1("CRealSerialComm::SendDataToPort ClearCommError succeeded lclErrorFlags=%d\n", m_lastCommError); + COMMLOGCLOSE(); + } + else + { + // No OS error returned, but WriteFile failed to write out all bytes + // therefore, since we are not doing overlapped I/O, this is an error. + err = TCAPI_ERR_COMM_ERROR; + COMMLOGOPEN(); + COMMLOGS("CRealSerialComm::SendDataToPort ClearCommError succeeded lclErrorFlags=0\n"); + COMMLOGCLOSE(); +// DUMPCOMSTAT(&lclComStat); + } + } + } + else + { + // we sent all the data we requested + err = TCAPI_ERR_NONE; +#ifdef _DEBUG + COMMLOGOPEN(); + COMMLOGS("CRealSerialComm::SendDataToPort WriteFile successful\n"); + BYTE* ptr = (BYTE*)inData; + long numBytes = (inSize > 20) ? 20 : inSize; + char msg[200]; + sprintf(msg, "CRealSerialComm::SendDataToPort = "); + for (int i = 0; i < numBytes; i++) + { + sprintf(msg, "%s %02.2x", msg, ptr[i]); + } + sprintf(msg, "%s\n", msg); + COMMLOGS(msg); + COMMLOGCLOSE(); +#endif + } + } + else + { + // write failed + m_lastCommError = GetLastError(); + err = TCAPI_ERR_COMM_ERROR; + COMMLOGOPEN(); + COMMLOGA1("CRealSerialComm::SendDataToPort WriteFile failed = %d\n", m_lastCommError); + COMMLOGCLOSE(); + } + + return err; +} +long CRealSerialComm::PollPort(DWORD &outSize) +{ + long err = TCAPI_ERR_NONE; + outSize = 0; + + COMSTAT lclComStat; + DWORD lclErrorFlags=0; + + if (!IsConnected()) + return TCAPI_ERR_MEDIA_NOT_OPEN; + +// Sleep(1); + if (!ClearCommError( m_hSerial, &lclErrorFlags, &lclComStat )) + { + m_lastCommError = GetLastError(); + err = TCAPI_ERR_COMM_ERROR; + + PROCLOGOPEN(); + PROCLOGA1("CRealSerialComm::PollPort ClearCommError failed=%d\n", m_lastCommError); +// if (m_lastCommError > 0) + LogErrorText2(m_lastCommError); + PROCLOGCLOSE(); + } + else + { + // ClearCommError succeeded + if (lclErrorFlags) + { + m_lastCommError = lclErrorFlags; + err = TCAPI_ERR_COMM_ERROR; + PROCLOGOPEN(); + PROCLOGA1("CRealSerialComm::PollPort ClearCommError succeeded but lclErrorFlags=%d\n", m_lastCommError); + PROCLOGCLOSE(); + } + else + { +// DUMPCOMSTATP(&lclComStat); +// PROCLOGOPEN(); +// PROCLOGA1("CRealSerialComm::PollPort ClearCommError succeeded cbInQue=%d\n", lclComStat.cbInQue); +// PROCLOGCLOSE(); + m_lastCommError = 0; + } + outSize = lclComStat.cbInQue; + } + + return err; +} +#ifdef _DEBUG +void CRealSerialComm::DumpComStat(COMSTAT* stat) +{ + COMMLOGOPEN(); + COMMLOGA3(" comstat fCtsHold =%d fDsrHold =%d fRlsdHold=%d\n", stat->fCtsHold, stat->fDsrHold, stat->fRlsdHold); + COMMLOGA3(" comstat fXoffHold=%d fXoffSent=%d fEof =%d\n", stat->fXoffHold, stat->fXoffSent, stat->fEof); + COMMLOGA3(" comstat fTxim =%d cbInQue =%d cbOutQue =%d\n", stat->fTxim, stat->cbInQue, stat->cbOutQue); + COMMLOGCLOSE(); +} +void CRealSerialComm::DumpComStatP(COMSTAT* stat) +{ + PROCLOGOPEN(); + PROCLOGA3(" comstat fCtsHold =%d fDsrHold =%d fRlsdHold=%d\n", stat->fCtsHold, stat->fDsrHold, stat->fRlsdHold); + PROCLOGA3(" comstat fXoffHold=%d fXoffSent=%d fEof =%d\n", stat->fXoffHold, stat->fXoffSent, stat->fEof); + PROCLOGA3(" comstat fTxim =%d cbInQue =%d cbOutQue =%d\n", stat->fTxim, stat->cbInQue, stat->cbOutQue); + PROCLOGCLOSE(); +} +#endif +long CRealSerialComm::ReadPort(DWORD inSize, void *outData, DWORD &outSize) +{ + long err = TCAPI_ERR_NONE; + outSize = 0; + + COMSTAT lclComStat; + DWORD lclErrorFlags=0; + DWORD lclLength; + if (!IsConnected()) + return TCAPI_ERR_MEDIA_NOT_OPEN; + + // clear out any errors in the channel and get the length of the buffer + if (!ClearCommError( m_hSerial, &lclErrorFlags, &lclComStat )) + { + // ClearCommError failed + m_lastCommError = GetLastError(); + err = TCAPI_ERR_COMM_ERROR; + PROCLOGOPEN(); + PROCLOGA1("CRealSerialComm::ReadPort ClearCommError failed=%d\n", m_lastCommError); + PROCLOGCLOSE(); + } + else + { + if (lclErrorFlags) + { + m_lastCommError = lclErrorFlags; + err = TCAPI_ERR_COMM_ERROR; + PROCLOGOPEN(); + PROCLOGA1("CRealSerialComm::ReadPort ClearCommError succeeded but lclErrorFlags=%d\n", m_lastCommError); + PROCLOGCLOSE(); + } + else + { + m_lastCommError = 0; + + lclLength = min( inSize, lclComStat.cbInQue ); + + if (lclLength > 0) + { + // Read lclLength number of bytes into outData. + if (!ReadFile(m_hSerial,outData,lclLength,&outSize,NULL)) + { + m_lastCommError = GetLastError(); + err = TCAPI_ERR_COMM_ERROR; + PROCLOGOPEN(); + PROCLOGA1("CRealSerialComm::ReadPort ReadFile failed = %d\n", m_lastCommError); + PROCLOGCLOSE(); + } + else + { + // ReadFile returned successful, check to see all our bytes came in + // If a timeout happened - we may not get all the data + if (lclLength != outSize) + { + lclErrorFlags = 0; + if (!ClearCommError( m_hSerial, &lclErrorFlags, &lclComStat )) + { + // ClearCommError failed + m_lastCommError = GetLastError(); + err = TCAPI_ERR_COMM_ERROR; + PROCLOGOPEN(); + PROCLOGA1("CRealSerialComm::ReadPort ClearCommError failed=%d\n", m_lastCommError); + PROCLOGCLOSE(); + } + else + { + // ClearCommError succeeded + if (lclErrorFlags) + { + // there really was an error + m_lastCommError = lclErrorFlags; + err = TCAPI_ERR_COMM_ERROR; + PROCLOGOPEN(); + PROCLOGA1("CRealSerialComm::ReadPort ReadFile succeeded-not all data read lclErrorFlags=%d\n", m_lastCommError); + PROCLOGCLOSE(); + } + else + { + // Since we are not doing overlapped I/O + // and our timeout values say to timeout, we should read all the bytes + // that the last Poll told us, if not this is an error + err = TCAPI_ERR_COMM_ERROR; + PROCLOGOPEN(); + PROCLOGS("CRealSerialComm::ReadPort ReadFile succeeded-not all data read lclErrorFlags=0\n"); + PROCLOGCLOSE(); + } + } + } + else + { + // all data read + m_lastCommError = 0; + PROCLOGOPEN(); + PROCLOGS("CRealSerialComm::ReadPort ReadFile successful\n"); + PROCLOGCLOSE(); + } + } + } + } + } + + return err; +} + +long CRealSerialComm::ProcessBuffer(CConnection* pConn, CRegistry* pRegistry, long& numberProcessed) +{ + PROCLOGOPEN(); + PROCLOGS("CRealSerialComm::ProcessBuffer\n"); + PROCLOGCLOSE(); + + long err = TCAPI_ERR_NONE; + long routingErr = TCAPI_ERR_NONE; + + if (!IsConnected()) + return TCAPI_ERR_MEDIA_NOT_OPEN; + + if (!m_Protocol) + return TCAPI_ERR_UNKNOWN_MEDIA_TYPE; + + DWORD protocolHeaderLength = m_Protocol->GetHeaderLength(); + + // fill buffer + if (m_numberBytes < MAX_SERIAL_MESSAGE_BUFFER_LENGTH) + { + DWORD outLen = 0; + err = PollPort(outLen); + if (err == TCAPI_ERR_NONE && outLen > 0) + { + if (outLen > (MAX_SERIAL_MESSAGE_BUFFER_LENGTH - m_numberBytes)) + outLen = MAX_SERIAL_MESSAGE_BUFFER_LENGTH - m_numberBytes; + BYTE *ptr = &m_pBuffer[m_numberBytes]; + err = ReadPort(outLen, ptr, outLen); + if (err == TCAPI_ERR_NONE && outLen > 0) + { + m_numberBytes += outLen; + } + } + } + // now process buffer but only for complete messages + if (err == TCAPI_ERR_NONE) + { + if (m_numberBytes >= protocolHeaderLength) + { + BYTE* ptr = m_pBuffer; + long bytesRemaining = m_numberBytes; + long usedLen = 0; + bool done = false; + + while (!done) + { + DWORD fullMessageLength = bytesRemaining; + DWORD rawLength = 0; + BYTE* fullMessage = ptr; + BYTE* rawMessage = ptr; + BYTE msgId = 0; + if (m_Protocol->DecodeMessage(fullMessage, fullMessageLength, msgId, rawMessage, rawLength)) + { + err = PreProcessMessage(msgId, fullMessageLength, fullMessage); + if (err != TCAPI_ERR_NONE) + { + // notify all clients right now + pConn->NotifyClientsCommError(err, false, 0); + err = TCAPI_ERR_NONE; + } +#ifdef _DEBUG + int reallen = fullMessageLength; + if (reallen > 50) reallen = 50; + char msg[6]; + msg[0] = '\0'; + + sLogMsg[0] = '\0'; + if (reallen > 0) + { + sLogMsg[0] = '\0'; + for (int i = 0; i < reallen; i++) + { + sprintf(msg, "%02.2x ", ptr[i]); + strcat(sLogMsg, msg); + } + } +#endif + PROCLOGOPEN(); + PROCLOGA5("CRealSerialComm::ProcessBuffer - RouteMesssage pRegistry = %x id=%x len=%d len=%d\n msg=%s\n", pRegistry, msgId, fullMessageLength, rawLength, sLogMsg); + PROCLOGCLOSE(); + + err = pRegistry->RouteMessage(msgId, fullMessage, fullMessageLength, rawMessage, rawLength); + if (err != TCAPI_ERR_NONE) routingErr = err; // saved for future + + numberProcessed++; + usedLen += fullMessageLength; + bytesRemaining -= fullMessageLength; + ptr += fullMessageLength; + if (bytesRemaining < protocolHeaderLength) + done = true; + } + else + { + done = true; + } + } + DeleteMsg(usedLen); + } + } +// PROCLOGOPEN(); +// PROCLOGA1("CRealSerialComm::ProcessBuffer err = %d\n", err); +// PROCLOGCLOSE(); + if (routingErr == TCAPI_ERR_NONE) + return err; + else + return routingErr; +} +bool CRealSerialComm::IsConnectionEqual(ConnectData* pConn) +{ + bool equal = false; + + // forms accepted: + // "comNN", "NN" + char* ptr1 = m_ConnectSettings->realSerialSettings.comPort; + char* ptr2 = pConn->realSerialSettings.comPort; + bool digit1found = false; + while(!digit1found && *ptr1 != NULL) + { + if (*ptr1 >= '0' && *ptr1 <= '9') + { + digit1found = true; + break; + } + ptr1++; + } + bool digit2found = false; + while(!digit2found && *ptr2 != NULL) + { + if (*ptr2 >= '0' && *ptr2 <= '9') + { + digit2found = true; + break; + } + ptr2++; + } + if (digit1found && digit2found) + { + if (strcmp(ptr1, ptr2) == 0) + equal = true; + } + return equal; +} + +#ifdef _DEBUG +DWORD CRealSerialComm::GetErrorText(DWORD inError) +{ + LPVOID lpMsgBuf; + + if (inError == 0) return inError; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + inError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + + COMMLOGA1(" -- GetErrorText=%s", lpMsgBuf); + // Free the buffer. + LocalFree( lpMsgBuf ); + + return inError; +} +DWORD CRealSerialComm::GetErrorText2(DWORD inError) +{ + LPVOID lpMsgBuf; + + if (inError == 0) return inError; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + inError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + + PROCLOGA1(" -- GetErrorText=%s", lpMsgBuf); + // Free the buffer. + LocalFree( lpMsgBuf ); + + return inError; +} + +void CRealSerialComm::DumpBuffer(BYTE* ptr, long length) +{ + char msg[256] = {0}; + if (length > 50) length = 50; + for (int i = 0; i < length; i++) + { + sprintf(msg, "%s%02.2X ", msg, ptr[i]); + } + sprintf(msg, "%s\n", msg); + PROCLOGS(msg); +} +#endif