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

📄 source.cpp

📁 停车场用
💻 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 + -