|
|
// SacCommunicator.cpp: implementation of the CSacCommunicator class.
//
//////////////////////////////////////////////////////////////////////
#include "inclfile.h"
#include "..\SacCommunicator\SacCommunicator.h"
//#include "Debug.cpp"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
LPTSTR CSacCommunicator::s_vctrCommPorts[]= {_T("COM1"), _T("COM2"), NULL}; SacString CSacCommunicator::s_strDummyReponse;
BOOL CSacCommunicator::XReadFile( HANDLE hFile, // handle to file
LPVOID lpBuffer, // data buffer
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead, // number of bytes read
LPOVERLAPPED lpOverlapped, // overlapped buffer
time_t tmTimeout // time-out
) { time_t tmInitReadTime, tmCurrTime; time(&tmInitReadTime); // stamp
BOOL bLastRead;
while (!(bLastRead= ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped)) || !*lpNumberOfBytesRead) { time(&tmCurrTime); // stamp
if (tmCurrTime-tmInitReadTime>tmTimeout) break; }
return bLastRead; }
CSacCommunicator::CSacCommunicator(int nCommPort, DCB dcb) { _Construct(nCommPort, dcb); }
CSacCommunicator::~CSacCommunicator() { _Clean(); }
void CSacCommunicator::_Construct(int nCommPort, DCB dcb) { m_nCommPort= nCommPort; m_dcb= dcb;
m_hCommPort= INVALID_HANDLE_VALUE; }
void CSacCommunicator::_Clean() { if (IsConnected()) Disconnect(); }
BOOL CSacCommunicator::Connect() { m_hCommPort= CreateFile(s_vctrCommPorts[m_nCommPort], GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // open handle
if (m_hCommPort!=INVALID_HANDLE_VALUE) { if (!SetCommMask(m_hCommPort, EV_RXCHAR)) // masking all events but the char. read event
return FALSE; // init call has to succeed
COMMTIMEOUTS tmouts; ZeroMemory(&tmouts,sizeof(COMMTIMEOUTS)); tmouts.ReadIntervalTimeout= MAXDWORD; // no blocking
if (!SetCommTimeouts(m_hCommPort, &tmouts)) // non-blocking read
return FALSE; // has to succeed as well
}
return m_hCommPort!=INVALID_HANDLE_VALUE; // check if succeeded
}
BOOL CSacCommunicator::Disconnect() { CloseHandle(m_hCommPort); // close the handle
m_hCommPort= INVALID_HANDLE_VALUE; return m_hCommPort==INVALID_HANDLE_VALUE; // has to succeed
}
BOOL CSacCommunicator::IsConnected() { return m_hCommPort!=INVALID_HANDLE_VALUE; }
BOOL CSacCommunicator::PokeSac() // currently disabled
{ return FALSE; }
BOOL CSacCommunicator::SacCommand(SAC_STR szRequest, SacString& strResponse, BOOL bPoke, time_t tmTimeout) { time_t tmInitTime, tmCurrTime; time(&tmInitTime);
strResponse= ""; // init response
if (bPoke) // if asked:
/* if (!PokeSac()) // poke sac
return FALSE; // make sure to get response*/
0; // disabled
DWORD nBytesWritten, nBytesRead; SAC_CHAR szReturned[BUF_LEN]; // whatever is written by sac
for (int i= 0; i<SAC_STRLEN(szRequest); i++) // baby-feeding sac
{ if (!WriteFile( m_hCommPort, szRequest+i, sizeof(SAC_CHAR), &nBytesWritten, NULL)) // feed sac
return FALSE; // io must succeed
time(&tmCurrTime); tmTimeout-= tmCurrTime-tmInitTime; if (!XReadFile( m_hCommPort, szReturned, sizeof(SAC_CHAR), &nBytesRead, NULL, tmTimeout)||!nBytesRead) // feed sac
return FALSE; // io must succeed && must receive echo back
}
time(&tmCurrTime); tmTimeout-= tmCurrTime-tmInitTime; if (!XReadFile( m_hCommPort, szReturned, sizeof(SAC_CHAR), &nBytesRead, NULL, tmTimeout)||!nBytesRead) // feed sac
return FALSE; // io must succeed && must receive echo back
// DWORD dwEvtMask;
DWORD dwErrors; // port errors
COMSTAT stat; // io status
time(&tmInitTime);
do {
//dwEvtMask= 0;
//while (!(dwEvtMask & EV_RXCHAR)
// if (!WaitCommEvent(m_hCommPort, &dwEvtMask, NULL))
// return FALSE;
ClearCommError(m_hCommPort, &dwErrors, &stat); // peek into buffer
if (!ReadFile(m_hCommPort, szReturned, stat.cbInQue, &nBytesRead, NULL)) // receive echo-back
return FALSE; // io must succeed
if (!nBytesRead) continue; // save some worthless instructions then
szReturned[nBytesRead]= '\0'; // fix it
strResponse.append(szReturned); // add to response
time(&tmCurrTime); } while ((strResponse.rfind(SAC_TEXT("SAC>"))==SacString::npos)&&(tmCurrTime-tmInitTime<tmTimeout));
int nPosSacPrompt= strResponse.rfind(SAC_TEXT("SAC>")); if (!nPosSacPrompt) return FALSE; // no prompt back
strResponse.erase(nPosSacPrompt, SAC_STRLEN(SAC_TEXT("SAC>")));
return TRUE; // at last sac echoed back!!!
}
BOOL CSacCommunicator::PagingOff(SacString& strResponse) { if (!SacCommand(SAC_STR("p\r"), strResponse, FALSE)) // toggle paging
return FALSE;
if (strResponse.find(SAC_STR("OFF"))!=SacString::npos) // check state
return TRUE;
// if we r here then supposedly it's on, need to toggle once more
if (!SacCommand(SAC_STR("p\r"), strResponse, FALSE)) // toggle paging
return FALSE;
if (strResponse.find(SAC_STR("OFF"))!=SacString::npos) // re-check
return TRUE;
return FALSE; // desperate
}
|