📄 communication.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 + -