196 lines
5.2 KiB
C++
196 lines
5.2 KiB
C++
|
// 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
|
||
|
}
|
||
|
|
||
|
|