如果要检查 Modem 的状态, 还需要开一个线程监视串口的状态(也许WinNT内核的Window的Bug,不能正确产生某些Modem的事件)
先要定义一个串口设置的 DCB:
DCB _dcb;
memset(&_dcb, 0, sizeof(DCB)); //Clear DCB
_dcb.DCBlength = sizeof(DCB); //DWORD: sizeof(DCB)
_dcb.BaudRate = CBR_115200; //DWORD: current baud rate
_dcb.Parity = NOPARITY; //BYTE : 0-4=no,odd,even,mark,space
_dcb.ByteSize = 8; //BYTE : number of bits/byte, 4-8
_dcb.StopBits = ONESTOPBIT; //BYTE : 0,1,2 = 1, 1.5, 2
_dcb.fBinary = true; //DWORD: binary mode, no EOF check
_dcb.fParity = false; //DWORD: enable parity checking
_dcb.fOutxCtsFlow = false; //DWORD: CTS output flow control
_dcb.fOutxDsrFlow = false; //DWORD: DSR output flow control
_dcb.fDtrControl = DTR_CONTROL_ENABLE; //DWORD: DTR flow control type
_dcb.fDsrSensitivity = false; //DWORD: DSR sensitivity
_dcb.fTXContinueOnXoff = false; //DWORD: XOFF continues Tx
_dcb.fOutX = false; //DWORD: XON/XOFF out flow control
_dcb.fInX = false; //DWORD: XON/XOFF in flow control
_dcb.fErrorChar = false; //DWORD: enable error replacement
_dcb.fNull = false; //DWORD: enable null stripping
_dcb.fRtsControl = RTS_CONTROL_ENABLE; //DWORD: RTS flow control
_dcb.fAbortOnError = false; //WORD : abort reads/writes on error
_dcb.XonLim = 2048; //0xffff; //WORD : transmit XON threshold
_dcb.XoffLim = 512; //0xffff; //WORD : transmit XOFF threshold
_dcb.XonChar = 0x11; //char : Tx and Rx XON character
_dcb.XoffChar = 0x13; //char : Tx and Rx XOFF character
_dcb.ErrorChar = 0; //char : error replacement character
_dcb.EofChar = 0; //char : end of input character
_dcb.EvtChar = 0; //char : received event character
--------------------next---------------------
OVERLAPPED _ReadOS;
OVERLAPPED _WriteOS;
memset(&_ReadOS, 0, sizeof(OVERLAPPED));
memset(&_WriteOS, 0, sizeof(OVERLAPPED));
_Handle=CreateFile(_PortName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);
if(_Handle==INVALID_HANDLE_VALUE)
{
//不能打开端口
return;
}
if(!SetCommMask(_Handle, EV_RXFLAG))
{
//不能设置端口事件MASK
return;
}
if(!SetCommState(_Handle, &dcb))
{
//不能设置端口参数
return
}
memset(&_ReadOS, 0, sizeof(OVERLAPPED));
_ReadOS.hEvent = CreateEvent(NULL,true,false,NULL);
_hKillRead = CreateEvent(NULL,true,false,NULL);
_hKillTimer = CreateEvent(NULL,true,false,NULL);
memset(&_WriteOS, 0, sizeof(OVERLAPPED));
_WriteOS.hEvent = CreateEvent(NULL, true, false, NULL);
_hSyncWrite = CreateEvent(NULL, true, false, NULL);
_hKillWrite = CreateEvent(NULL, true, false, NULL);
_ReadThreadId=_beginthread(_ReadThread, 4096, this));
_WriteThreadId=_beginthread(_WriteThread, 4096, this);
--------------------next---------------------
COMSTAT ComStat;
const RecvBufSize = 2048;
char RecvBuf[RecvBufSize];
DWORD dwErrorFlag, dwBytes, BytesToRead, BytesRemain;
OVERLAPPED os;
DWORD dwEvtMask, dwModemStatus;
os.hEvent = CreateEvent(NULL, true, false, NULL);
if(os.hEvent)
{
if(SetCommMask(Comm->Handle, EV_RXCHAR|EV_TXEMPTY|EV_CTS|EV_DSR|EV_RLSD|EV_RXFLAG|EV_RX80FULL|EV_ERR))
{
HANDLE StatusWaits[2] = {Comm->_hKillRead, os.hEvent};
while(Comm->_RunReadThread)
{
dwEvtMask = 0;
if(!WaitCommEvent(Comm->Handle, &dwEvtMask, &os))
{
if(GetLastError() == ERROR_IO_PENDING)
{
if(WaitForMultipleObjects(2, StatusWaits, false, INFINITE) == WAIT_OBJECT_0)
break;
}
}
if(!Comm->_RunReadThread)
break;
if(dwEvtMask & EV_RXCHAR)
{
ClearCommError(Comm->Handle, &dwErrorFlag, &ComStat);
BytesRemain = ComStat.cbInQue;
while(BytesRemain>0)
{
BytesToRead = BytesRemain if(ReadFile(Comm->Handle, RecvBuf, BytesToRead, &dwBytes, &Comm->_ReadOS))
{
Comm->_InQueue->In(RecvBuf, dwBytes);
BytesRemain-=dwBytes;
}
}
}
if(dwEvtMask & (EV_CTS|EV_DSR|EV_RLSD))
{
if(GetCommModemStatus(Comm->Handle, &dwModemStatus))
{
Comm->_ModemStatus = dwModemStatus;
}
if(dwEvtMask & EV_CTS)
{
if((!Comm->FromHandle) && (Comm->_dcb.fOutxCtsFlow) && (Comm->_ModemStatus & MS_CTS_ON))
dwEvtMask |= EV_TXEMPTY;
}
if(dwEvtMask & EV_RLSD)
{
Comm->_dwDetectingRing = 0;
}
}
if(dwEvtMask & EV_TXEMPTY)
{
if((Comm->_ModemStatus & MS_CTS_ON) || (!Comm->_dcb.fOutxCtsFlow) || (Comm->FromHandle))
{
if(Comm->_InQueue->Count)
dwEvtMask &=~ EV_TXEMPTY;
SetEvent(Comm->_hSyncWrite);
}
}
if(dwEvtMask & EV_ERR)
{
ClearCommError(Comm->Handle, &dwErrorFlag, &ComStat);
}
Comm->CommNotify(dwEvtMask);
}
}
CloseHandle(os.hEvent);
}
--------------------next---------------------
const SendBufSize = 256;
char SendBuf[SendBufSize];
DWORD BytesSent=0, BytesToSend=0;
COMSTAT ComStat;
DWORD dwErrorFlag, dwBytesWr;
int iSingled;
HANDLE MainWaits[2] = {Comm->_hKillWrite, Comm->_hSyncWrite};
HANDLE OvlWriteWaits[2] = {Comm->_hKillWrite, Comm->_WriteOS.hEvent};
while(Comm->_RunWriteThread)
{
iSingled = WaitForMultipleObjects(2, MainWaits, false, INFINITE);
if((!Comm->_RunWriteThread) || (iSingled==WAIT_OBJECT_0))
break;
ResetEvent(Comm->_hSyncWrite);
if(BytesSent {
if(WriteFile(Comm->Handle, SendBuf+BytesSent, BytesToSend-BytesSent, &dwBytesWr, &Comm->_WriteOS))
{
BytesSent+=dwBytesWr;
}
else if(GetLastError()==ERROR_IO_PENDING)
{
iSingled = WaitForMultipleObjects(2, OvlWriteWaits, false, INFINITE);
if((!Comm->_RunWriteThread) || (iSingled==WAIT_OBJECT_0))
break;
if(GetOverlappedResult(Comm->Handle, &Comm->_WriteOS, &dwBytesWr, false))
BytesSent+=dwBytesWr;
}
}
else if(Comm->_OutQueue->Count)
{
BytesSent = 0;
BytesToSend = Comm->_OutQueue->Out(SendBuf, SendBufSize);
SetEvent(Comm->_hSyncWrite);
}
}
--------------------next---------------------
阅读(1186) | 评论(0) | 转发(0) |