📄 tokenshadow.cpp
字号:
// TokenShadow.cpp : implementation file
//
#include "stdafx.h"
#include "Token.h"
#include "TokenShadow.h"
#include "afxmt.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern HWND hBackPanelWnd;
extern HWND hDealWnd;
extern CString ComName;
extern int nCardPoped;
extern int nCardDealed;
extern CTokenShadow* m_TokenShadow;
extern CEvent m_TokenShadowEvent;
UINT WatchTokenProc(LPVOID lpParam);
/////////////////////////////////////////////////////////////////////////////
// CTokenShadow
IMPLEMENT_DYNCREATE(CTokenShadow, CWinTimerThread)
CTokenShadow::CTokenShadow()
{
bContinue=TRUE;
bTokenWorking=TRUE;
pTokenHandle=NULL;
pTokenWatchThread =NULL;
}
CTokenShadow::~CTokenShadow()
{
}
BOOL CTokenShadow::InitInstance()
{
/************************************************
* *
* Open the token serial port *
* *
************************************************/
#ifdef RELEASE_TOKEN
bTokenWorking=FALSE;
#endif
BOOL bTokenState = FALSE;
//Open token serial
pTokenHandle = new CTokenSerial;
bTokenState = pTokenHandle->Open(ComName,CBR_9600,NOPARITY,ONESTOPBIT,8);
if(!bTokenState)
{
delete pTokenHandle;
pTokenHandle=NULL;
TRACE("Open token serial port failed");
}
else
{
pTokenWatchThread=AfxBeginThread(WatchTokenProc , this,THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); //start a thread for watching token serial port data
ASSERT (NULL != pTokenWatchThread);
pTokenWatchThread->m_bAutoDelete = FALSE;
pTokenWatchThread->ResumeThread();
}
::PostMessage(hBackPanelWnd,THREADINIT,(WPARAM)0,(LPARAM)0);
return TRUE;
}
int CTokenShadow::ExitInstance()
{
if(pTokenWatchThread!=NULL)
{
HANDLE hEvent=OpenEvent(EVENT_ALL_ACCESS, TRUE, TOKENREADNAME);
SetEvent(hEvent);
hEvent=OpenEvent(EVENT_ALL_ACCESS, TRUE, TOKENWAITNAME);
SetEvent(hEvent);
bContinue=FALSE;
WaitForSingleObject(pTokenWatchThread->m_hThread,INFINITE);
delete pTokenWatchThread;
TRACE("\nCTokenShadow ");
pTokenWatchThread=NULL;
}
if(pTokenHandle!=NULL)
{
delete pTokenHandle;
pTokenHandle=NULL;
}
return CWinTimerThread::ExitInstance();
}
BEGIN_MESSAGE_MAP(CTokenShadow, CWinTimerThread)
//{{AFX_MSG_MAP(CTokenShadow)
ON_THREAD_MESSAGE(TOKEN_SELCHKGOOD, OnTOKEN_SELCHKGOOD)
ON_THREAD_MESSAGE(TOKEN_SELCHKBAD, OnTOKEN_SELCHKBAD)
ON_THREAD_MESSAGE(TOKEN_UPBOXNUM, OnTOKEN_UPBOXNUM)
ON_THREAD_MESSAGE(TOKEN_DOWNBOXNUM, OnTOKEN_DOWNBOXNUM)
ON_THREAD_MESSAGE(TOKEN_TOKENSTATUS, OnTOKEN_TOKENSTATUS)
ON_THREAD_MESSAGE(TOKEN_ONETOKENPOP, OnTOKEN_ONETOKENPOP)
ON_THREAD_MESSAGE(TOKEN_DEALOVER, OnTOKEN_DEALOVER)
ON_THREAD_MESSAGE(TOKEN_UPLOADDEALLOG, OnTOKEN_UPLOADDEALLOG)
ON_THREAD_MESSAGE(TOKEN_DOWNTIME, OnTOKEN_DOWNTIME)
ON_THREAD_MESSAGE(TOKEN_CARDNUM, OnTOKEN_CARDNUM)
ON_THREAD_MESSAGE(TOKEN_UPBOXNULL, OnTOKEN_UPBOXNULL)
ON_THREAD_MESSAGE(TOKEN_DOWNBOXFULL, OnTOKEN_DOWNBOXFULL)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTokenTokenShadow message handlers
/****************************************************
* *
* deal with token event *
* *
****************************************************/
long CTokenShadow::OnTOKEN_SELCHKGOOD(WPARAM wparam, LPARAM lparam)
{
TRACE("\nSelfCheckGood");
return 0;
}
long CTokenShadow::OnTOKEN_SELCHKBAD(WPARAM wparam, LPARAM lparam)
{
TRACE("\nSelfCheckBad");
return 0;
}
long CTokenShadow::OnTOKEN_UPBOXNUM(WPARAM wparam, LPARAM lparam)
{
return 0;
}
long CTokenShadow::OnTOKEN_DOWNBOXNUM(WPARAM wparam, LPARAM lparam)
{
return 0;
}
long CTokenShadow::OnTOKEN_TOKENSTATUS(WPARAM wparam, LPARAM lparam)
{
if(bTokenWorking)
{
this->pTokenHandle->ToTokenCardStatus(TRUE);
SetEvent(pTokenHandle->m_Event_CardNum);
}
TRACE("\nToken Status");
return 0;
}
long CTokenShadow::OnTOKEN_ONETOKENPOP(WPARAM wparam, LPARAM lparam)
{
if(bTokenWorking)
{
::nCardPoped++;
::PostMessage(hDealWnd,WM_USERPOPTOKENCONTINUEFROMSHADOW,(WPARAM)0,(LPARAM)0);
SetEvent(pTokenHandle->m_Event_CardPoped);
TRACE("\nPop token one,and this is the %d token",::nCardPoped);
}
return 0;
}
long CTokenShadow::OnTOKEN_DEALOVER(WPARAM wparam, LPARAM lparam)
{
TRACE("\nDeal over");
if(bTokenWorking)
{
if(::nCardDealed!=::nCardPoped)
{
::PostMessage(hDealWnd, WM_USERPOPTOKENOVERFROMSHADOW, (WPARAM)0, (LPARAM)0);
}
else
{
::PostMessage(hDealWnd, WM_USERPOPTOKENOVERFROMSHADOW, (WPARAM)1, (LPARAM)0);
}
}
return 0;
}
long CTokenShadow::OnTOKEN_UPLOADDEALLOG(WPARAM wparam, LPARAM lparam)
{
return 0;
}
long CTokenShadow::OnTOKEN_DOWNTIME(WPARAM wparam, LPARAM lparam)
{
return 0;
}
long CTokenShadow::OnTOKEN_CARDNUM(WPARAM wparam, LPARAM lparam)
{
return 0;
}
long CTokenShadow::OnTOKEN_UPBOXNULL(WPARAM wparam, LPARAM lparam)
{
::PostMessage(hBackPanelWnd, WM_EXCEPTIONALERT, (WPARAM)1, (LPARAM)0);
return 0;
}
long CTokenShadow::OnTOKEN_DOWNBOXFULL(WPARAM wparam, LPARAM lparam)
{
::PostMessage(hBackPanelWnd, WM_EXCEPTIONALERT, (WPARAM)2, (LPARAM)0);
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// Global functions
UINT WatchTokenProc(LPVOID lpParam)
{
//判断上一个数据帧是否收完
BOOL IsBuffOver=TRUE;
//串口读出字节数
DWORD read=0;
//要求串口读出数
DWORD toread=0;
//串口事件掩码字
DWORD m_ComMask=0;
//校验字
UCHAR m_Chk=0;
//命令字
UCHAR m_Command=0;
//返回结果
BOOL bSuccess=FALSE;
DWORD nRet=0;
DWORD mRet=0;
//得到串口指针和数据
CTokenShadow* pTokenShadow;
CTokenSerial* pTokenSerial;
pTokenShadow=(CTokenShadow*)lpParam;
pTokenSerial = pTokenShadow->pTokenHandle;
//定义串口缓冲区
UCHAR Buff[MAXREADBUFFLEN]={0};
DWORD BuffLen=0;
UCHAR CmdData[MAXREADBUFFLEN]={0};
DWORD CmdDataLen = 0;
UCHAR TmpBuff[MAXTMPBUFFLEN]={0};
//计数器
long i=0;
while(pTokenShadow->bContinue)
{
pTokenSerial->ClearError();
TRACE("\nWAIT...");
//监听串口事件
pTokenSerial->WaitData(m_ComMask);
//如果不是字符到达事件,返回重新监听事件
if(!(m_ComMask & EV_RXCHAR))
continue;
//清除串口错误
pTokenSerial->ClearError(_T("读前"));
if(IsBuffOver)
{
//将缓冲区读取字节数设置为0
BuffLen=0;
//将缓冲区置零清空
memset(Buff,0,sizeof(UCHAR)*MAXREADBUFFLEN);
}
else
{
if(BuffLen==1)
{
goto LENGTHBYTE;
}
else if(BuffLen>=2&&BuffLen<4)
{
goto ADDRESSBYTE;
}
else if(BuffLen>=4&&BuffLen<Buff[1])
{
goto COMMANDBYTE;
}
else if(BuffLen==Buff[1])
{
goto CHKBYTE;
}
else
{
goto TAILBYTE;
}
}
FIRSTBYTE:
//没有读出第一个字节,返回重新监听事件
if(pTokenSerial->ReadData(Buff,1,"FIRSTBYTE")<1)
continue;
BuffLen=1;
//读出第一个字节,但不是0x55,重新读取第一个字节
if(Buff[0]!=0x55)
goto FIRSTBYTE;
LENGTHBYTE:
m_Chk=0;
//没有读出长度字节,将读帧完成标志置否,返回重新监听事件
if(pTokenSerial->ReadData(Buff+1,1,"LENGTHBYTE")<1)
{
IsBuffOver=FALSE;
continue;
}
BuffLen=2;
m_Chk=m_Chk^Buff[1];
ADDRESSBYTE:
toread=4-BuffLen;
//读取收发地址。如果读出长度小于2,将读帧完成标志置否,返回重新监听事件
if(read=pTokenSerial->ReadData(Buff+2,toread,"ADDRESSBYTE")<toread)
{
BuffLen+=read;
IsBuffOver=FALSE;
continue;
}
//接受地址不是本机地址,抛弃该帧
if(Buff[3]!=TERMI_ADDRESS)
{
//没有读完废弃帧,返回重新监听事件
if(pTokenSerial->ReadData(TmpBuff,Buff[Buff[1]-4])<Buff[Buff[1]-4])
continue;
//读完废弃帧,重新读取第一个字节
goto FIRSTBYTE;
}
BuffLen=4;
m_Chk=m_Chk^Buff[2];
m_Chk=m_Chk^Buff[3];
COMMANDBYTE:
//读取除帧尾和校验位外剩余字节
toread=Buff[1]-BuffLen;
for(i=toread;i>0;i=i-1)
{
//读取字节失败,将读帧完成标志置否,返回重新监听事件
if(pTokenSerial->ReadData(Buff+BuffLen,1,"COMMANDBYTE")<1)
{
IsBuffOver=FALSE;
continue;
}
BuffLen+=1;
m_Chk=m_Chk^Buff[BuffLen-1];
}
CHKBYTE:
//读取校验位失败,将读帧完成标志置否,返回重新监听事件
if(pTokenSerial->ReadData(Buff+BuffLen,1,"CHKBYTE")<1)
{
IsBuffOver=FALSE;
continue;
}
//校验不对,抛弃该帧,重新读取第一个字节
if(m_Chk!=Buff[BuffLen])
{
//没有读完废弃帧,返回重新监听事件
if(pTokenSerial->ReadData(TmpBuff,1)<1)
continue;
//读完废弃帧,重新读取第一个字节
goto FIRSTBYTE;
}
BuffLen+=1;
TAILBYTE:
//读取帧尾失败,将读帧完成标志置否,返回重新监听事件
if(pTokenSerial->ReadData(Buff+BuffLen,1,"TAILBYTE")<1)
{
IsBuffOver=FALSE;
continue;
}
BuffLen+=1;
//帧尾不是0xAA,抛弃该帧,重新读取第一个字节
if(Buff[BuffLen-1]!=0xAA)
goto FIRSTBYTE;
//完成一个帧的读取,将读帧完成标志置真
IsBuffOver=TRUE;
//获得命令字
m_Command=Buff[4];
//获得命令帧中的数据
for(i=0; i<Buff[2]-7; i++)
CmdData[i]=Buff[5+i];
CmdDataLen=Buff[1]-5;
//重置串口中的事件
pTokenSerial->ResetHandle();
switch(m_Command)
{
case 0x30:
pTokenSerial->ToTokenAck();
pTokenShadow->PostThreadMessage(TOKEN_SELCHKGOOD,(WPARAM)0 ,(LPARAM)0);
break;
case 0x31:
pTokenSerial->ToTokenAck();
pTokenShadow->PostThreadMessage(TOKEN_SELCHKBAD,(WPARAM)0 ,(LPARAM)0);
break;
case 0x50:
SetEvent(pTokenSerial->m_Event_TokenAck);
break;
case 0x34:
pTokenShadow->PostThreadMessage(TOKEN_TOKENSTATUS,(WPARAM)CmdData ,(LPARAM)0);
break;
case 0x35:
pTokenSerial->ToTokenAck();
pTokenShadow->PostThreadMessage(TOKEN_ONETOKENPOP,(WPARAM)0 ,(LPARAM)0);
break;
case 0x36:
pTokenSerial->ToTokenAck();
::nCardDealed=CmdData[0]*256+CmdData[1];
if(::nCardDealed!=::nCardPoped)
{
pTokenShadow->PostThreadMessage(TOKEN_DEALOVER,(WPARAM)(-1) ,(LPARAM)0);
}
else
{
pTokenShadow->PostThreadMessage(TOKEN_DEALOVER,(WPARAM)0 ,(LPARAM)0);
}
break;
case 0x38:
pTokenSerial->ToTokenAck();
pTokenShadow->PostThreadMessage(TOKEN_UPBOXNULL,(WPARAM)0 ,(LPARAM)0);
break;
case 0x39:
pTokenSerial->ToTokenAck();
pTokenShadow->PostThreadMessage(TOKEN_DOWNBOXFULL,(WPARAM)0 ,(LPARAM)0);
break;
default:
break;
}
//返回读取下一个帧
goto FIRSTBYTE;
}
//将临时指针置NULL和句柄置0
pTokenShadow=NULL;
pTokenSerial=NULL;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -