www.pudn.com > gps-time.rar > ComPort.cpp


// ComPort.cpp: implementation of the CComPort class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "RegionComm.h" 
#include "ComPort.h" 
#include "Communication.h" 
#include "RegionSocket.h" 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
extern bool bgpsOK; 
extern long igps; 
extern CString sgps; 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CComPort::CComPort(CCommunication *pComm) 
{ 
    m_bPortOpen=FALSE; 
	m_ComPort=0; 
	m_ComBitRate=9600;     
	m_pOwner = pComm; 
	TimeOutCount=15; 
	IsConnected=FALSE; 
	nTimeCount=-1; 
} 
 
CComPort::~CComPort() 
{ 
	SetCommMask( m_hcom, 0 ) ; 
    if (m_hcom != INVALID_HANDLE_VALUE) 
		::CloseHandle(m_hcom); 
    ::CloseHandle(m_hProcessEvent); 
    CloseHandle(m_osRead.hEvent ); 
    CloseHandle(m_osWrite.hEvent ); 
    CloseHandle(m_osWait.hEvent); 
	//Close(); 
} 
//打开串口 
BOOL CComPort::Open() 
{	 
   //   COMMTIMEOUTS  CommTimeOuts ; 
   CString portstr;    
   DCB        dcb ; 
    
    memset(&m_osRead, 0, sizeof(OVERLAPPED)); 
	if( NULL==(m_osRead.hEvent = CreateEvent( NULL,    // no security 
                                TRUE,    // explicit reset req 
                                FALSE,   // initial event reset 
                                NULL ) )) // no name 
	       return(FALSE); 
   memset(&m_osWrite, 0, sizeof(OVERLAPPED)); 
   if( NULL==(m_osWrite.hEvent = CreateEvent( NULL,    // no security 
                                 TRUE,    // explicit reset req 
                                 FALSE,   // initial event reset 
                                 NULL )))   //no name 
			return(FALSE); 
    
   memset(&m_osWait, 0, sizeof(OVERLAPPED)); 
   if(NULL==(m_osWait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) 
	        return(FALSE); 
   if(NULL==(m_hProcessEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL))) 
	        return(FALSE); 
 
   if(m_ComPort==0) 
	   return(FALSE); 
   if(m_bPortOpen) 
   { 
	   m_bPortOpen=FALSE; 
	   CloseHandle(m_hcom); 
   } 
   portstr.Format("\\\\.\\Com%d",m_ComPort);  
 
   if ((m_hcom=CreateFile( portstr, GENERIC_READ|GENERIC_WRITE, 
                  0,                    // exclusive access 
                  NULL,                 // no security attrs 
                  OPEN_EXISTING, 
                  FILE_ATTRIBUTE_NORMAL | 
                  FILE_FLAG_OVERLAPPED, // overlapped I/O    
                  NULL )) == (HANDLE) -1 ) 
   {	  
      return ( FALSE ) ; 
   } 
 
  // setup device buffers 
  SetupComm( m_hcom, 4096, 4096 ) ; 
   
   dcb.DCBlength = sizeof( DCB ) ; 
   GetCommState( m_hcom, &dcb ); 
	    
   dcb.BaudRate =m_ComBitRate; 
   dcb.ByteSize =8 ; 
   dcb.Parity = NOPARITY ; 
   dcb.StopBits = ONESTOPBIT ; 
 
   // setup hardware flow control 
   dcb.fOutxDsrFlow =FALSE ; 
   dcb.fDtrControl = DTR_CONTROL_ENABLE ; 
 
   dcb.fOutxCtsFlow = FALSE ; 
   dcb.fRtsControl = RTS_CONTROL_ENABLE ; 
   // setup software flow control 
   // other various settings 
   dcb.fBinary = TRUE ; 
  // dcb.fParity = FALSE ; 
   if(!SetCommState(m_hcom, &dcb ) ) 
   {	    
	   return(FALSE); 
   } 
   //SetCommMask(m_hComm, EV_RXCHAR); 
   m_bPortOpen=TRUE; 
   if(!SetCommMask( m_hcom, EV_RXCHAR )) 
	   return(FALSE); 
   else 
       return(TRUE);   
} 
//关闭串口 
void CComPort::Close() 
{ 
   if(!m_bPortOpen) 
	   return; 
   if (m_hcom != INVALID_HANDLE_VALUE) 
		::CloseHandle(m_hcom); 
   m_bPortOpen=FALSE; 
    
} 
//读串口 
int CComPort::ReadComm(BYTE* MyBuff, int rCount) 
{ 
   BOOL       fReadStat ; 
   COMSTAT    ComStat ; 
   DWORD      dwErrorFlags; 
   DWORD      dwLength; 
   DWORD      dwError; 
 
    
   // only try to read number of bytes in queue 
   ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ; 
   dwLength = min( (DWORD)rCount, ComStat.cbInQue ) ; 
   if (dwLength > 0) 
   { 
      fReadStat = ReadFile( m_hcom, MyBuff, 
		                    dwLength, &dwLength, &m_osRead ) ; 
      if (!fReadStat) 
      { 
          dwError = GetLastError(); 
		  if (GetLastError() == ERROR_IO_PENDING) 
         {             
            // We have to wait for read to complete. 
             // This function will timeout according to the 
            // CommTimeOuts.ReadTotalTimeoutConstant variable 
            // Every time it times out, check for port errors 
            while(!GetOverlappedResult( m_hcom , 
               &m_osRead, &dwLength, TRUE )) 
            { 
               dwError = GetLastError(); 
               if(dwError == ERROR_IO_INCOMPLETE) 
                  // normal result if not finished 
                  continue; 
               else 
               { 
                  // an error occurred, try to recover 
                  ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;        
               } 
            } 
 
	      } 
         else 
         { 
            // some other error occurred 
            dwLength = 0 ; 
            ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;        
         } 
      } 
   } 
   return ( dwLength ) ; 
} 
//写串口 
BOOL CComPort::WriteComm(BYTE * MyBuff, int wCount) 
{ 
	 BOOL        fWriteStat ; 
   DWORD       dwBytesWritten ;    
   DWORD       dwErrorFlags; 
   DWORD   	   dwError; 
   DWORD       dwBytesSent=0; 
   COMSTAT     ComStat; 
 
   fWriteStat = WriteFile( m_hcom, MyBuff, wCount, 
                           &dwBytesWritten, &m_osWrite ) ; 
   if (!fWriteStat) 
   { 
      if(GetLastError() == ERROR_IO_PENDING) 
      { 
         while(!GetOverlappedResult( m_hcom, 
            &m_osWrite, &dwBytesWritten, TRUE )) 
         { 
            dwError = GetLastError(); 
            if(dwError == ERROR_IO_INCOMPLETE) 
            { 
               // normal result if not finished 
               dwBytesSent += dwBytesWritten; 
               continue; 
            } 
            else 
            {              
               ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;               
               break; 
            } 
         } 
         dwBytesSent += dwBytesWritten; 
      } 
      else 
      { 
         // some other error occurred 
         ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;          
         return ( FALSE ); 
      } 
   } 
   return ( TRUE ) ; 
 
} 
//从串口读数据 
void CComPort::ReadComData() 
{ 
//     BYTE TmpBuffReadData[m_MaxTableLen]; 
	 int  datLength; 
 
	 if(!m_bPortOpen) 
		 return; 
	 datLength=ReadComm(TmpBuffReadData,m_MaxTableLen);  
	 while(datLength>0) 
	 {   		  
		 MyComBuff.SaveBuff(TmpBuffReadData,datLength); 
		 datLength=ReadComm(TmpBuffReadData,m_MaxTableLen);  
	} 
    ::SetEvent(m_hProcessEvent); 
	 return; 
} 
//外部线程只需要调用GetTable()即可完成通信端口表格的处理 
//GetTable()把不需要转发的通信协议表格自己自动处理 
//需要转发的表格通过pRegionSocket指针转发出去 
//具体的通信协议语义的处理由该过程负责 
BOOL CComPort::ProcessTable() 
{ 
//	 BYTE  rBuff[m_MaxTableLen]; 
//	 int  rCount; 
	 COleDateTime tgps; 
     while (MyComBuff.GetTab(&tgps)) 
	 { 
		 igps=0; 
 
		 COleDateTimeSpan tspan; 
		 COleDateTime  pTime;	 
		 pTime = COleDateTime::GetCurrentTime(); 
		 tspan=pTime-tgps; 
		 //误差10分钟才对时 
//		TRACE("%d-%d-%d %d:%d:%d \n ",tgps.GetYear(),tgps.GetMonth(),tgps.GetDay(),tgps.GetHour(),tgps.GetMinute(),tgps.GetSecond()); 
		 double dl; 
		 dl=tspan.GetTotalSeconds(); 
		 if(dl!= 0 && dl>-600 && dl<600)  
		 { 
			SYSTEMTIME st;  
			st.wYear = tgps.GetYear(); 
			st.wMonth = tgps.GetMonth(); 
			st.wDay = tgps.GetDay(); 
			st.wHour = tgps.GetHour(); 
			st.wMinute = tgps.GetMinute(); 
			st.wSecond = tgps.GetSecond(); 
			st.wMilliseconds = 0; 
			st.wDayOfWeek = 0; 
			SetLocalTime(&st); 
			sgps.Format("对时前%s 对时后%s",pTime.Format("%H:%M:%S"),tgps.Format("%H:%M:%S")); 
		 } 
	 } 
	 return(TRUE); 
} 
//把未打包的表格打包后发送 
BOOL CComPort::SendTable(BYTE *tabBuff, int tabCount) 
{ 
	//lv test 060808 
	long ltime,ltime2; 
	ltime=GetTickCount(); 
 
//     BYTE TmpBuff[m_MaxTableLen]; 
	 int i,packLength; 
 
	 if(!m_bPortOpen) 
		 return(FALSE); 
	 if(tabCount>m_MaxTableLen)//253) 
		 return(FALSE); 
	 for(i=0;i0) 
     { 
		 WriteComm(TmpBuff,packLength);		 
		  
		 //lv test 060808 
		 ltime2=GetTickCount(); 
		 ltime=ltime2-ltime; 
		 if(ltime>10) 
			 TRACE("CComPort::SendTable time %dms",ltime); 
 
		 return(TRUE); 
	 } 
	 else 
	 { 
		 TRACE("CComPort::SendTable FALSE"); 
		 return(FALSE); 
	 } 
} 
 
//给某个设备转发未打包的数据表格。处理:首先查找本端口是否包含该设备,然后打包,再发送 
BOOL CComPort::TransmitTable( BYTE tDeviceNo, BYTE *sBuff, int sCount) 
{     
	sBuff[5]=0; 
	sBuff[6]=tDeviceNo; 
	if(m_pOwner->m_pServerSocket->m_bAskConnect) 
		m_pOwner->m_pServerSocket->SendTable(sBuff,sCount);  
 
 	return TRUE; 
} 
//发送应答请求连接 
void CComPort::SendAck(BYTE sDeviceType,BYTE sDeviceNo) 
{ 
     BYTE sBuff[7]; 
     sBuff[0]=0; 
	 sBuff[1]=7; 
	 sBuff[2]=RegionNo; 
	 sBuff[3]=MainLinkCode; 
	 sBuff[4]=AckCnt; 
	 sBuff[5]=sDeviceType; 
	 sBuff[6]=sDeviceNo; 
	 SendTable(sBuff,7); 
} 
//发送查询请求连接 
void CComPort::SendAckQry(BYTE sDeviceType,BYTE sDeviceNo) 
{ 
     BYTE sBuff[7]; 
     sBuff[0]=0; 
	 sBuff[1]=7; 
	 sBuff[2]=RegionNo; 
	 sBuff[3]=MainLinkCode; 
	 sBuff[4]=AckQry; 
	 sBuff[5]=sDeviceType; 
	 sBuff[6]=sDeviceNo; 
	 SendTable(sBuff,7); 
} 
//应答请求连接处理 
void CComPort::AskCntProc(BYTE sDeviceType, BYTE sDeviceNo) 
{ 
	SendAck(sDeviceType,sDeviceNo); 
 
	if(!IsConnected) 
	{ 
		BYTE  b=1; 
		NotifyStatus(TRUE);//向中心发送 
		DWORD  lParam= (LPARAM)MAKELONG( 
			    MAKEWORD(m_ComPort,sDeviceNo), 
				MAKEWORD(b,0)); 
		nTimeCount=0; 
		AfxGetMainWnd()->PostMessage(WM_COMMAND, IDM_LINKDEVUPDATE,lParam);			 
        IsConnected=TRUE;		 
	}	 
} 
//应答查询连接 
void CComPort::QryCmdProc(BYTE sDeviceType, BYTE sDeviceNo) 
{ 
	if(!IsConnected) 
		return;	 
	 nTimeCount=0;	 
	 SendAckQry(sDeviceType,sDeviceNo); 
	 
} 
 
 
//waits for an event to occur for a specified communications device 
void CComPort::WaitCommEvent() 
{ 
	ASSERT(m_osWait.hEvent != NULL); 
	ASSERT(m_hcom != INVALID_HANDLE_VALUE); 
 
	if (m_bPortOpen) 	 
	{ 
		BOOL bRet = ::WaitCommEvent(m_hcom, &m_dwEventMask, &m_osWait);		 
		if(!bRet) 
		{ 
			long ErrNo=::GetLastError();  
		} 
	} 
} 
 
//向中心发送设备状态信息 
void CComPort::NotifyStatus(BOOL iConnected) 
{ 
	if(m_pOwner->m_pServerSocket==NULL) 
		 return; 
	 if(!m_pOwner->m_pServerSocket->m_IsConnected ) 
		 return;	 
	m_pOwner->m_pServerSocket->NotifyLineStatusTab(0,m_DeviceNo,iConnected); 
} 
//设置参数 
void CComPort::SetPamera(BYTE Port, long BitRate,BYTE DeviceType,BYTE DeviceNo,CString Depict) 
{ 
	m_ComPort = Port; 
	m_ComBitRate = BitRate; 
	m_DeviceType= DeviceType; 
	m_DeviceNo =DeviceNo; 
	m_Depict = Depict; 
} 
 
void CComPort::AdjustDevConnect() 
{	     
		if(IsConnected) 
		{		 
			nTimeCount++; 
			if(nTimeCount>TimeOutCount) 
			{			 
				IsConnected = FALSE; 
				nTimeCount=-1; 
				NotifyStatus(FALSE);//设备的连接状态发生变化时向中心发送通知表格 
				DWORD  lParam= (LPARAM)MAKELONG( 
			    MAKEWORD(m_ComPort,m_DeviceNo), 
				MAKEWORD(0,0));		 
		        AfxGetMainWnd()->PostMessage(WM_COMMAND, IDM_LINKDEVUPDATE,lParam);							 
			} 
		} 
} 
 
int CComPort::GetMyDeviceNo() 
{ 
  return(m_DeviceNo); 
} 
 
void CComPort::SendSelfControl() 
{ 
	 BYTE sBuff[11]; 
     sBuff[0]=0; 
	 sBuff[1]=11; 
	 sBuff[2]=RegionNo; 
	 sBuff[3]=MainLinkCode; 
	 sBuff[4]=ModeStageCmd; 
	 sBuff[5]=m_DeviceType; 
	 sBuff[6]=m_DeviceNo; 
	 sBuff[7]=SelfControl; 
	 sBuff[8]=0; 
	 SendTable(sBuff,11); 
}