📄 source.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "source.h"
#include "DataProc.h"
#include "option.h"
#include "dynamic.h"
#include "dido.h"
#include "syris.h"
#include "ZKPark.h"
#include "datetool.h"
#include "Cbuilder.h"
#include "Capture.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//定义已打开通讯端口,以维护之
typedef struct tagCOMM_PORT{
int hHandle;
DWORD nNetID;
int nIPPort;
}COMM_PORT,*PCOMM_PORT;
//打开控制器通讯端口
static int OpenCRCommPort(CONTROLER *pCR);
//显示打开控制器端口错误
static void ShowOpenCRCommError(CONTROLER *pCR);
//关闭已打开的通讯句柄
static void CloseCommPort(void);
//获取通讯端口
static COMM_PORT *GetCommPort(int nItem);
//根据NetID获取通讯端口
static COMM_PORT *GetCommPortWithNetID(DWORD nNetID,int nIPPort);
//添加已打开通讯端口
static int AddCommPort(int hHandle,DWORD nNetID,int nIPPort);
//设置ZKPark当前时间
static int SetCurTimeToZKPark(void);
//在SY200NT控制器上读取刷卡记录
static int ReadRecordOnSY200NT(CONTROLER *pCR,void *pRec);
//在ZKPark控制器上读取刷卡记录
static int ReadRecordOnZKPark(CONTROLER *pCR,void *pRec);
//显示无效或无反应的控制器
static int ShowInvalidControler(CONTROLER *pCR);
//获取IOData上的车道
static void *GetRoadwayOnIOData(void *pIORec);
//在ZKPark控制器上读取刷卡记录
static int SendCommandToZKPark(CONTROLER *pCR,int nState,long lParam);
static TList *pCommList; //已打开通讯句柄队列
//初始化刷卡来源
int InitDataSource()
{
void *pCur,*pHead;
CONTROLER *pCR;
int i;
pHead = GetControlerList(); //获取本地控制器
for(i=0;;i++){
pCur = GetDotOnTList(pHead,i);
if(pCur==NULL)break;
pCR = LookControler(pCur);
if(GetCROnLineFlag(pCR) && GetCRUnLinkFlag(pCR)==0)//控制器在本地主机上
OpenCRCommPort(pCR);
if(IsValidControler(pCR))//获取一个有效控制器(在用的)
InitCRCapture(pCR);
}
return(TRUE);
}
//打开控制器通讯端口
int OpenCRCommPort(CONTROLER *pCR)
{
int nNetID,nIPPort,nCRType;
int bIPNet;
int hHandle;
COMM_PORT *pOpen;
char szIP[20];
nNetID = pCR->nNetID;
nIPPort = pCR->nIPPort;
nCRType = pCR->nType;
bIPNet = GetCRIPNetFlag(pCR);
if(bIPNet==0)nIPPort=0;//COMM节点,IP端口应=0
else GetIPStr(szIP,nNetID);//Ethernet节点,转换IP地址
pOpen = GetCommPortWithNetID(nNetID,nIPPort);
if(pOpen!=NULL)hHandle = pOpen->hHandle;
else {
if(nCRType == 0){//SY200NT
if(bIPNet==0)hHandle=Syris_InitComm(nNetID);
else hHandle=Syris_InitTCP(szIP,nIPPort,NULL);
}
else if(nCRType==1){//ZKPark(中矿主板)
if(bIPNet==0)hHandle=ZKPark_InitComm(nNetID);
else hHandle=ZKPark_InitTCP(szIP,nIPPort,NULL);
if(hHandle!=0) //设置ZKPark当前时间
SetCurTimeToZKPark();
}
else hHandle=0;
if(nCRType<=1 && hHandle==0)//显示打开控制器端口错误
ShowOpenCRCommError(pCR);
AddCommPort(hHandle,nNetID,nIPPort);
}
pCR->hHandle = hHandle;
return(hHandle);
}
//设置ZKPark当前时间
int SetCurTimeToZKPark(void)
{
SYSTEMTIME t;
int rc;
GetLocalTime(&t);
rc=ZKPark_SetDatetime(t.wYear,t.wMonth,t.wDay,
t.wHour,t.wMinute,t.wSecond);
return(rc);
}
//显示打开控制器端口错误
void ShowOpenCRCommError(CONTROLER *pCR)
{
static char pszTextComm[]="控制器 \"%s\"\n\n其宿主机接口 \"%s\"\n\n"
"不存在或已被占用!",
pszTextIP[]="控制器 \"%s\"\n\n其网络IP地址 \"%s\"\n"
"端口 \"%d\"\n\n不存在或已被占用!";
int nNetID,nIPPort;
int bIPNet;
char szBuf[150],szStr[20],szName[30];
nNetID = pCR->nNetID;
nIPPort = pCR->nIPPort;
bIPNet = GetCRIPNetFlag(pCR);
GetNetIDStr(szStr,nNetID,bIPNet);//获取网络标识
GetCRNameText(szName,pCR);
if(bIPNet==0)//COMM口
wsprintf(szBuf,pszTextComm,szName,szStr);
else //Ethernet节点
wsprintf(szBuf,pszTextIP,szName,szStr,nIPPort);
Application->MessageBox(szBuf,GetMainTitle(),MB_OK|MB_ICONSTOP|MB_APPLMODAL);
}
//关闭刷卡来源(关闭通讯端口)
void CloseDataSource(void)
{
int i;
void *pCur,*pHead;
CONTROLER *pCR;
//将控制器的通讯句柄复位为0
pHead = GetControlerList();
for(i=0;;i++){
pCur = GetDotOnTList(pHead,i);
if(pCur==NULL)break;
pCR = LookControler(pCur);
pCR->hHandle=0;
CloseCRCapture(pCR);//关闭控制器拥有车道的图象捕捉卡
}
CloseCommPort();//关闭通讯端口
}
//获取通讯端口
COMM_PORT *GetCommPort(int nItem)
{
void *pCur;
COMM_PORT *pOpen;
pCur = GetDotOnTList(pCommList,nItem);
pOpen =(COMM_PORT*)ListContent(pCur);
return(pOpen);
}
//根据NetID获取通讯端口
COMM_PORT *GetCommPortWithNetID(DWORD nNetID,int nIPPort)
{
COMM_PORT *pOpen;
int i;
for(i=0;;i++){
pOpen = GetCommPort(i);
if(pOpen==NULL)break;
if(pOpen->nNetID==nNetID && pOpen->nIPPort==nIPPort)
break;
}
return(pOpen);
}
//添加已打开通讯端口
int AddCommPort(int hHandle,DWORD nNetID,int nIPPort)
{
COMM_PORT a;
void *pCur;
int i;
ZeroMemory(&a,sizeof(a));
a.hHandle=hHandle;
a.nNetID=nNetID;
a.nIPPort=nIPPort;
if(pCommList==NULL)pCommList = new TList;
pCur=AddContentToTList(pCommList,&a,sizeof(a));//增加内容到TList链末尾
return((int)pCur);
}
//关闭已保存的通讯句柄
void CloseCommPort()
{
COMM_PORT *pOpen;
int hHandle;
int i;
Source_CloseCurrent();//关闭当前通讯句柄
for(i=0;;i++){//关闭已打开的通讯句柄
pOpen=GetCommPort(i);
if(pOpen==NULL)break;
hHandle = pOpen->hHandle;
if(hHandle!=0)
Source_Close(hHandle);//关闭通讯句柄
}
DelTList(pCommList);
delete pCommList;
pCommList=NULL;
}
//读取刷卡数据
int ReadDataSource(void)
{
static BYTE nFlag;
int i,j,rc,nType;
void *pCur,*pCRList;
CONTROLER *pCR;
IODATA ioRec;
if(nFlag)return(FALSE);//防止重入
nFlag=TRUE;
pCRList = GetControlerList(); //获取本地控制器
for(i=0;;i++){
pCur = GetDotOnTList(pCRList,i);
if(pCur==NULL)break;
pCR = LookControler(pCur);
rc = IsValidControler(pCR);//获取一个有效控制器(在用的)
if(rc==FALSE)continue;
rc=-1;
nType = pCR->nType;
for(j=0;j<20 && rc<0 ;j++){//错误时,最多重试20次
if(nType==0)//SY200NT
rc=ReadRecordOnSY200NT(pCR,&ioRec);//在控制器上读取刷卡记录
else if(nType==1)//ZKPark(中矿)
rc=ReadRecordOnZKPark(pCR,&ioRec);//在控制器上读取刷卡记录
else rc=0;
}
if(rc>0){ //有数据
GetRoadwayOnIOData(&ioRec);
rc=IODataProc(&ioRec); //处理数据
}
else if(rc<0){ //出错
rc=ShowInvalidControler(pCR);
if(rc!=IDRETRY)SetCRPauseFlag(pCR,TRUE);//将控制器设置为暂停使用
}
}
nFlag=FALSE;
return(rc);
}
//在SY200NT控制器上读取刷卡记录
int ReadRecordOnSY200NT(CONTROLER *pCR,void *pRec)
{
IODATA *t;
char szBuf[100],szStr[10];
int rc,n,nCRID;
//读取资料
nCRID = pCR->nAddrID;
Syris_SetCurHandle(pCR->hHandle);
rc = Syris_ReadIodata(nCRID,szBuf);
if(rc==SYRIS_NOERROR){//计算记录总数
lstrcpyn(szStr,szBuf,5);
n=atoi(szStr);
}
else n=0;
if(n>0){
t = (IODATA *)pRec;
ZeroMemory(t,sizeof(IODATA));
t->pCR = pCR;
t->nCRNo = pCR->nCRNo;
t->nCRID = nCRID;
t->nReaderID = szBuf[4]-'0';
lstrcpyn(szStr,szBuf+5,9);
t->nDate=DateToDWORD(szStr);
lstrcpyn(szStr,szBuf+13,7);
t->nTime=TimeToDWORD(szStr);
lstrcpyn(szStr,szBuf+19,5);
if(szStr[0]!='X')//有效卡
t->nCardNo=atol(szStr);
else if(szStr[2]!='X'){//无效卡
rc = Syris_ReadCardID(nCRID,szStr+2,szBuf);//读取无效卡片内码资料
if(rc==SYRIS_NOERROR){
lstrcpyn(szStr,szBuf,9);
t->nCardHI= strtoul(szStr,NULL,16);
lstrcpyn(szStr,szBuf+8,9);
t->nCardID= strtoul(szStr,NULL,16);
}
}
else n=0;
t->nDataType=IODATA_CARDDATA;
Syris_DelOneIodata(nCRID);//删除资料
}
if(rc==SYRIS_NOERROR){
if(n>0)rc=1;
else rc=0;
}
else rc=-1;
return(rc);
}
//在ZKPark控制器上读取刷卡记录
int ReadRecordOnZKPark(CONTROLER *pCR,void *pRec)
{
IODATA *t;
char szBuf[100],szStr[10];
int rc,n,nID,nPort;
int nData, nType;
//读取资料
ZKPark_SetCurHandle(pCR->hHandle);
rc = ZKPark_ReadIOData(&nData,&nType);
if(rc==ZKPARK_NOERROR){
t = (IODATA *)pRec;
ZeroMemory(t,sizeof(IODATA));
t->pCR=pCR;
t->nTime=GetTimeOnNow();
t->nDate=GetDateOnNow();
t->nCRNo = pCR->nCRNo;
t->nCardID=nData;
t->nRoadNo = pCR->wzRoadNo[0];
if(nType == ZKPARK_CARDDATA)
nType=IODATA_CARDDATA;
else if(nType == ZKPARK_CARCOME)
nType=IODATA_CARCOME;
else if(nType == ZKPARK_CARGONE)
nType=IODATA_CARGONE;
t->nDataType = nType;
rc=1;
}
else if(rc==ZKPARKERR_NOTEXT)rc=0;
else rc=-1;
return(rc);
}
//显示无效或无反应的控制器
int ShowInvalidControler(CONTROLER *pCR)
{
static char pszText[]="控制器 \"%s\" 没有反应!\n"
"请检查线路及电源。\n\n"
"选择\"取消\",\n该控制器将被暂停使用!";
int rc;
char szBuf[200],szStr[30];
GetCRNameText(szStr,pCR);
wsprintf(szBuf,pszText,szStr);
rc = Application->MessageBox(szBuf,GetMainTitle(),
MB_RETRYCANCEL|MB_ICONSTOP|MB_APPLMODAL);
return(rc);
}
//测试控制器
int TestAllControler(void)
{
CONTROLER *pCR;
void *pCur,*pCRList;
int i,rc,nType;
pCRList = GetControlerList(); //获取本地控制器
for(i=0;;i++){
pCur = GetDotOnTList(pCRList,i);
if(pCur==NULL)break;
pCR = LookControler(pCur);
rc= IsValidControler(pCR);//获取一个有效控制器(在用的)
if(rc==FALSE)continue;
rc=-1;
nType = pCR->nType;
while(rc!=0){//准备重试
if(nType==0)//SY200NT
rc=Syris_CheckControl(pCR->nAddrID);
else if(nType==1)//ZKPark(中矿)
rc=ZKPark_CheckControl();//在控制器上读取刷卡记录
else rc=0;
if(rc!=0){
rc=ShowInvalidControler(pCR);
if(rc!=IDRETRY)
{ SetCRPauseFlag(pCR,TRUE); rc=0;}
}
}
}
return(rc);
}
//获取IOData上的车道(根据编号或通讯ID获取车道)
void *GetRoadwayOnIOData(void *pIORec)
{
IODATA *t;
CONTROLER *pCR;
ROADWAY *pRoad;
int i,nRoads,nRoadNo,nReaderID;
WORD *pRoadNo;
t = (IODATA *)pIORec;
nRoadNo = t->nRoadNo;
nReaderID = t->nReaderID;
pRoad=NULL;
pCR = (CONTROLER *)t->pCR;
if(pCR==NULL)//根据编号获取本地控制器
pCR = (CONTROLER *)GetCROnListWithNo(GetControlerList(),
t->nCRNo);
if(pCR!=NULL){
nRoads = pCR->nRoads;
pRoadNo = pCR->wzRoadNo;
for(i=0;i<nRoads;i++){//根据编号或通讯ID获取车道
pRoad = (ROADWAY *)GetRoadwayWithNo(pRoadNo[i]);
if(pRoad!=NULL){//比较编号或读卡机通讯ID
if(nRoadNo!=0 && nRoadNo==(int)pRoad->nNo)break;
else if(nReaderID!=0 && nReaderID==(int)pRoad->nReaderID)break;
}
}
if(i>=nRoads)pRoad=NULL;
}
if(pRoad!=NULL){ //存在该车道
t->nReaderID = pRoad->nReaderID;
t->nRoadNo = pRoad->nNo;
t->nStatus = pRoad->nType;
t->pRoad= pRoad;
}
return(pRoad);
}
//答复读取刷卡数据
int SendCommandToSource(void *pCR,int nState,long lParam)
{
int i,rc,nType;
CONTROLER *t;
t = (CONTROLER *)pCR;
nType = t->nType;
if(nType==1)//ZKPark(中矿)
rc=SendCommandToZKPark(t,nState,lParam);//在控制器上写命令
else rc=0;
return(rc);
}
//在ZKPark控制器上读取刷卡记录
int SendCommandToZKPark(CONTROLER *pCR,int nState,long lParam)
{
int rc;
//设置通讯句柄
ZKPark_SetCurHandle(pCR->hHandle);
switch(nState){//答复停车场指令
case PARK_BARRUP: //人工抬闸
ZKPark_SetBarrUp(); break;
case PARK_VALIDCARD: //有效卡片(抬闸)
rc = ZKPark_SetValidCard(); break;
case PARK_COLLECTCARD: //请插卡回收
rc = ZKPark_SetCollectCard(); break;
case PARK_INVALIDCARD: //无效卡片
rc = ZKPark_SetInvalidCard(); break;
case PARK_HAVEPARKIN : //此卡已在场
rc = ZKPark_SetCardHaveIn(); break;
case PARK_NOPARKIN : //此卡未入场
rc = ZKPark_SetCardNoIn(); break;
case PARK_OVERDATE : //此卡已过期
rc = ZKPark_SetOverDate(); break;
case PARK_OVERTIME : //此卡已超时
rc = ZKPark_SetOverTime(); break;
case PARK_NOTPAID : //未交费
rc = ZKPark_SetNotPaid(); break;
case PARK_CARDLOSS : //此卡已挂失
rc = ZKPark_SetCardLoss(); break;
case PARK_CARDLOCK : //此卡已锁定
rc = ZKPark_SetCardLock(); break;
case PARK_WAITING : //请等待
rc = ZKPark_SetWaitPlease(); break;
case PARK_PARKFULL : //车位已满
rc = ZKPark_SetParkFull(); break;
case PARK_PARKSURPLUS: //车位有余
rc = ZKPark_SetParkPlease(); break;
case PARK_BARRSTOP : //人工停闸
rc = ZKPark_SetBarrStop(); break;
case PARK_BARRDOWN : //人工落闸
rc = ZKPark_SetBarrDown(); break;
case PARK_COMMERROR : //通讯错误
rc = ZKPark_SetCommError(); break;
case PARK_RELAYON : //继电器闭合
rc = ZKPark_SetDelayOn(); break;
case PARK_RELAYOFF : //继电器断开
rc = ZKPark_SetDelayOff(); break;
case PARK_WARNON : //警报
if(lParam!=0) SetRoadWarnFlag((ROADWAY *)lParam,TRUE);
rc = ZKPark_SetDelayOn(); break;
case PARK_WARNOFF : //解除警报
if(lParam!=0) SetRoadWarnFlag((ROADWAY *)lParam,FALSE);
rc = ZKPark_SetDelayOff(); break;
default:rc=0;
}
return(rc);
}
//获取一个有效控制器是否在用的
int IsValidControler(void *pCR)
{
CONTROLER *t;
int rc;
rc=FALSE;
t = (CONTROLER *)pCR;
if(t!=NULL && GetCRPauseFlag(t)==0)//未暂停且通讯句柄有效
rc=Source_GetActive(t->hHandle);
return(rc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -