⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 communication.cpp

📁 gps对时
💻 CPP
字号:
// Communication.cpp: implementation of the CCommunication class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RegionComm.h"
#include "Communication.h"
#include "Comthrd.h"
#include "procdatathrd.h"
#include "RegionSocket.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern NEAR bool bDogServerAskMeExit;//lv 2003 5 17 add
extern NEAR bool bUserActive[20];
extern NEAR HANDLE hSetUser[20];
extern NEAR int iUsers;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCommunication::CCommunication()
{
	m_cRegionNo = 1;
	m_pServerSocket = (CRegionSocket *) new CRegionSocket(this);
	m_aProcessEvent.RemoveAll();m_aReceiveEvent.RemoveAll(); 
    m_pCommThread=NULL;m_pProcessThread=NULL;
}

CCommunication::~CCommunication()
{	
	for (int i = 0; i < m_aCom.GetSize(); i++)
		delete m_aCom[i];
	m_aCom.RemoveAll();
	m_aProcessEvent.RemoveAll();
	m_aReceiveEvent.RemoveAll();
    if(m_pServerSocket!=NULL)
	  delete m_pServerSocket;
}
//增加设备
BOOL CCommunication::AddTscCom(BYTE PortNo,DWORD dwBaudRate,BYTE DeviceType,BYTE DeviceNo,CString Depict)
{	
	int i;
	CComPort * pComPort;
    
	if(!CreateThreadEvents())
		return(FALSE);
	CSingleLock  commLock(&muxCommArray);
    commLock.Lock(); //访问端口对象
	
	for (i = 0; i < m_aCom.GetSize(); i++)
		if (m_aCom[i]->m_ComPort == PortNo) 	
			return FALSE;		

	pComPort = (CComPort *) new CComPort(this);
	pComPort->SetPamera(PortNo,dwBaudRate,DeviceType,DeviceNo,Depict);

	if (!pComPort->Open())
	{
		delete pComPort;		
		return FALSE;
	}
    try
	{
		m_aCom.Add(pComPort);	
		m_aReceiveEvent.Add( pComPort->GetReceiveEvent()); 
		m_aProcessEvent.Add(pComPort->m_hProcessEvent);	
	}
	catch(CMemoryException *eMem)
	{
		eMem->Delete(); 
        delete pComPort;
		return(FALSE);
	}
	//以下分别通知通信和处理线程
	if(m_pCommThread!=NULL)
	{
	   pComPort->WaitCommEvent();	
	   SetEvent(ComChangeEvent);
	}
	if(m_pProcessThread!=NULL)
	   SetEvent(ProcessChangeEvent);
	return TRUE;
}
//删除设备
void CCommunication::DeleteTscCom(BYTE inPortNo)
{
	int cSize,index;

	CSingleLock  commLock(&muxCommArray);
    commLock.Lock(); //访问端口对象

	cSize=m_aCom.GetSize(); 

	for (index = 0; index < cSize; index++)
		if (inPortNo == m_aCom[index]->m_ComPort)
			break;
	if(index >= cSize)
		return;

	CComPort * pComPort = m_aCom[index];
	BYTE PortNo = pComPort->m_ComPort;
	CString strPort;
	strPort.Format("COM%d",PortNo); 
	AfxGetApp()->WriteProfileString("ComSetting",strPort,NULL); 
	//pComPort->DeleteAllDev();
	//以下分别通知通信和处理线程
    SetEvent(ComChangeEvent);
	SetEvent(ProcessChangeEvent); 
	m_aReceiveEvent.RemoveAt(index+2);
	m_aCom.RemoveAt(index);
	m_aProcessEvent.RemoveAt(index+2);
    
	if(pComPort->IsConnected) 
      pComPort->NotifyStatus(FALSE); 
    delete pComPort;
	AfxGetMainWnd()->PostMessage(WM_COMMAND, IDM_DELETECOM, PortNo);
}

//创建通讯口数据接收线程,创建通讯口数据转发线程
BOOL CCommunication::Run()
{
	if(!CreateThreadEvents())
		return(FALSE);
	//启动通讯口数据接收线程
	StartComm();
	//启动通讯口数据转发线程
	StartProcData();
	return TRUE;
}

// 通讯口数据接收线程开始
void CCommunication::StartComm()
{
	m_pCommThread = new CComThrd();
	if(m_pCommThread == NULL)
	{
		//MessageBox("pthread== NULL","",MB_OK);
		return ;
	}
	// 调试版检查m_pCommThrd线程
	ASSERT_VALID(m_pCommThread);
	m_pCommThread->m_pThreadParams = NULL;
	// 创建线程
	if(!m_pCommThread->CreateThread(CREATE_SUSPENDED))
	{
		delete m_pCommThread;
		m_pCommThread= NULL;
		//MessageBox("Create m_pCommThread faile","",MB_OK);		
		return;
	}
	// 设置线程优先级 -》高一级
	VERIFY(m_pCommThread->SetThreadPriority(THREAD_PRIORITY_NORMAL));
	m_pCommThread->SetOwner(this);
	for(int i=0;i<m_aCom.GetSize();i++)
		m_aCom[i]->WaitCommEvent(); 
	m_pCommThread->ResumeThread();

}
// 表格处理线程开始
void CCommunication::StartProcData()
{
	m_pProcessThread = new CProcDataThrd();
	if(m_pCommThread == NULL)
	{
		//MessageBox("pthread== NULL","",MB_OK);
		return ;
	}
	
	// 调试版检查通讯口数据转发线程
	ASSERT_VALID(m_pProcessThread );
	m_pProcessThread ->m_pThreadParams = NULL;
	// 创建线程
	if(!m_pProcessThread ->CreateThread(CREATE_SUSPENDED))
	{
		delete m_pProcessThread ;
		m_pProcessThread = NULL;
		//MessageBox("Create m_pProcessThread  faile","",MB_OK);		
		return;
	}
	// 设置线程优先级 -》高一级
	VERIFY(m_pProcessThread ->SetThreadPriority(THREAD_PRIORITY_NORMAL));
	m_pProcessThread->SetOwner(this);
	m_pProcessThread ->ResumeThread();
}

//串口查询
int CCommunication::FindComIndex(BYTE iDevNo)
{
	int i;

    CSingleLock  commLock(&muxCommArray);//何时释放??
    commLock.Lock(); //访问端口对象	
	for(i = 0;i<m_aCom.GetSize();i++)
		if(m_aCom[i]->m_DeviceNo== iDevNo)			
			return i;		
	return -1;

}

//数据转发给串口设备
void CCommunication::ConvertToDevice(BYTE DeviceType, BYTE DeviceNo, BYTE *tabBuff, int tabCount)
{
//	BYTE TmpBuff[m_MaxTableLen];
	int i;
	if(tabCount>m_MaxTableLen)//add logfile
		return;
	for(i=0;i<tabCount;i++)
		TmpBuff[i]=tabBuff[i];

	DeviceType=0;
	//no BroadCast
	if(DeviceNo <255)
	{
		int ComIndex = FindComIndex(DeviceNo);
		if(ComIndex>=0)
			if(m_aCom[ComIndex]->IsConnected)
			   m_aCom[ComIndex]->SendTable(TmpBuff,tabCount);
		return;
	}	
	//BroadCast DeviceNo
	if(DeviceNo ==255)
	{
		for( i = 0 ;i<m_aCom.GetSize();i++)
		{
			CComPort *pComPort = m_aCom.GetAt(i);			
			if(pComPort->IsConnected)
			{		    		
					TmpBuff[6] = pComPort->GetMyDeviceNo();
					pComPort->SendTable(TmpBuff,tabCount);
			}			
		}
	}

}
//发设备状态通知给中心
void CCommunication::SendNotifyAllDev()
{
	int i;
	CComPort *pComport;
	for (i = 0; i < m_aCom.GetSize(); i++) 
	{
		pComport = m_aCom[i];		
		m_pServerSocket->NotifyLineStatusTab(0,
		   pComport->GetMyDeviceNo(),pComport->IsConnected);	
	}

}
//判断设备是否超时
void CCommunication::AdjustDevConnect()
{
	for(int i = 0; i<m_aCom.GetSize();i++)
	{
		CComPort *pComPort = m_aCom.GetAt(i);
		pComPort->AdjustDevConnect();
	}
}

void CCommunication::TryToReadAllComm()
{
	int i, length;
	HANDLE hObjects[MaxWaitObjects];
	DWORD dwObject;
    BOOL bChangeCom;
	bChangeCom=TRUE;
    
	CSingleLock  commLock(&muxCommArray);	
	hObjects[0]=hSetUser[0];
	while (TRUE)
	{	
		if(bChangeCom)
		{
			commLock.Lock();		
			length = m_aReceiveEvent.GetSize();
			for(i=0;i<length;i++)
			{
				hObjects[i+1]=m_aReceiveEvent[i];
//				TRACE("Receive Event %d:%d\n",i,hObjects[i]);
			}
			commLock.Unlock();
			bChangeCom=FALSE;
		}	
		//WaitForMultipleObjects最多可以控制64个参数,0:线程状态 1:退出 2:打开或关闭新的端口 3开始为串口(即最多控制61个串口)
		dwObject = WaitForMultipleObjects(length+1, hObjects, FALSE, INFINITE);
		if (dwObject == WAIT_FAILED) 
		{
			DWORD dwError = GetLastError();
			continue;;
		}
		i = dwObject - WAIT_OBJECT_0-1;
		if(i<-1) continue;
		switch(i)
		{
		  case -1:
			  ResetEvent(hObjects[0]);
			  bUserActive[0]=true;
//			  TRACE("\nbUserActive[0]=true");
			  break;
		  case 0:  //退出事件通知		
			  return;
		  case 1:  //打开或关闭新的端口	
			  bChangeCom=TRUE;
			  continue;
			  break;
		  default:
			  ResetEvent(hObjects[i+1]);		
			  DWORD dwEvtMask =m_aCom[i-2]->m_dwEventMask;
			  if (m_aCom[i-2]->m_dwEventMask & EV_RXCHAR) //数据到达
			  {				
				m_aCom[i-2]->ReadComData();					
				m_aCom[i-2]->WaitCommEvent();			
			  }
			  break;
		}
	}
}

void CCommunication::ProcessCommData()
{

	int i, length;
	HANDLE hObjects[MaxWaitObjects];
	DWORD dwObject;
	BOOL bChangeCom;
	bChangeCom=TRUE;
    CSingleLock  commLock(&muxCommArray);
	hObjects[0]=hSetUser[1];
	while (TRUE) 
	{	
		if(bChangeCom)
		{
			commLock.Lock();		
			length =m_aProcessEvent.GetSize();
			for(i=0;i<length;i++)
			{
				hObjects[i+1]=m_aProcessEvent[i];
//				TRACE("Process Event %d:%d\n",i,hObjects[i]);
			}
			commLock.Unlock();
			bChangeCom=FALSE;
		}
		dwObject = WaitForMultipleObjects(length+1, hObjects, FALSE, INFINITE);
		if (dwObject == WAIT_FAILED) 
		{
			DWORD dwError = GetLastError();		
			continue ;
		}
		i = dwObject - WAIT_OBJECT_0-1;
		if(i<-1)  continue;
		switch (i) 
		{
		  case -1:
			  ResetEvent(hObjects[0]);
			  bUserActive[1]=true;
//			  TRACE("\nbUserActive[1]=true");
			  break;
		  case 0://退出
			  return;
		  case 1:  //打开或关闭新的端口
			  TRACE("Process CommChange!\n");
			  bChangeCom=TRUE;
			  continue;
			  break;
	      default:
			 ResetEvent(hObjects[i+1]);						 
			 m_aCom[i-2]->ProcessTable();
		    	break;			 
		}
	}
}

void CCommunication::StopAllRunningThread()
{
	SetEvent(ExitEvent);
   if (m_pCommThread != NULL)		
		::WaitForSingleObject(m_pCommThread->m_hThread, INFINITE);		
	if (m_pProcessThread != NULL) 		
		::WaitForSingleObject(m_pProcessThread->m_hThread, INFINITE);
}

BOOL CCommunication::CreateThreadEvents()
{//创建线程的同步事件

	if( m_aReceiveEvent.GetSize()>0  &&
		m_aProcessEvent.GetSize()>0 )
		return(TRUE);  //只有第一此进入时才创建线程退出和端口打开关闭通知事件
	if(NULL==(ExitEvent=::CreateEvent(NULL,TRUE,FALSE,NULL)))
		return(FALSE); //创建退出通知事件

	if(NULL==(ComChangeEvent=::CreateEvent(NULL,FALSE,FALSE,NULL)))
		return(FALSE); //创建端口打开或关闭通知事件
	if(NULL==(ProcessChangeEvent=::CreateEvent(NULL,FALSE,FALSE,NULL)))
		return(FALSE); //创建端口打开或关闭通知事件

    m_aReceiveEvent.Add(ExitEvent);
	m_aProcessEvent.Add(ExitEvent);
	
	m_aReceiveEvent.Add(ComChangeEvent);
	m_aProcessEvent.Add(ProcessChangeEvent);
	return(TRUE);
}

int CCommunication::GetComIndexByPort(BYTE iPortNo)
{	
	int i;
    CSingleLock  commLock(&muxCommArray);//何时释放??
    commLock.Lock(); //访问端口对象	
	for(i = 0;i<m_aCom.GetSize();i++)
		if(m_aCom[i]->m_ComPort== iPortNo)			
			return i;		
	return -1;
}


void CCommunication::SendCenter()
{
	m_pServerSocket->SendCenter();
}

void CCommunication::Degrade()
{
	TRACE("\nDegrade");
	for(int i = 0; i<m_aCom.GetSize();i++)
	{
		CComPort *pComPort = m_aCom.GetAt(i);
		if(pComPort->mUserMode.Mode==SimHand || pComPort->mUserMode.Mode==SpecifyStage || pComPort->mUserMode.Mode==AssignLampOffMode || pComPort->mUserMode.Mode==AssignYellowFlashMode)
		{
			pComPort->SendSelfControl();
		}
	}
}

void CCommunication::DegradeUserID(BYTE ID)
{
	TRACE("\nDegradeUserID");
	for(int i = 0; i<m_aCom.GetSize();i++)
	{
		CComPort *pComPort = m_aCom.GetAt(i);
		if(pComPort->mUserMode.ID==ID)
			if(pComPort->mUserMode.Mode==SimHand || pComPort->mUserMode.Mode==SpecifyStage || pComPort->mUserMode.Mode==AssignLampOffMode || pComPort->mUserMode.Mode==AssignYellowFlashMode)
			{
				pComPort->SendSelfControl();
			}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -