Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2341926
  • 博文数量: 816
  • 博客积分: 10000
  • 博客等级: 上将
  • 技术积分: 5010
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-17 17:57
文章分类

全部博文(816)

文章存档

2011年(1)

2008年(815)

分类:

2008-12-17 18:03:43

如果要检查 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) |
给主人留下些什么吧!~~