// cctv_C301.cpp: implementation of the CcctvC3JT class. // ////////////////////////////////////////////////////////////////////// #include "cctvC3jt.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// //keycode:0-9 static int KeyCode[10]={75, 62, 63, 64, 66, 67, 68, 70, 71, 72}; //keycode:上移 下移 左移 右移 放大 缩小 近焦 远焦 光圈开 光圈关 static int Operation[10]={96, 97, 98, 99, 86, 87, 88, 89, 90, 91}; CcctvC3JT::CcctvC3JT() { } CcctvC3JT::~CcctvC3JT() { } sint32 CcctvC3JT::TxProc() { E_RAW_ComStat coms = pLink->GetCommStatus(); if (coms == CMST_RX_CNT) return 0; if (ProcCmd())//处理外部下发命令 return 1; if(0DelACmd(rtuno); return FALSE;}//未登录不接受命令 TxBufwrite(); } if ((GetNowSecond() - m_LastSendTime) > m_reloginTime){ Login(name,pwd,ip,port); } if(!m_bLogin){ if ((GetNowSecond() - m_LastSendTime) > m_RcvTimeOuts) Login(name,pwd,ip,port); } return 1; } void CcctvC3JT::TrimBlank(char *buf,int len) { int i=0,j=0; for(i=0;iGetRtuNo(); unsigned char rtuaddr = pRtu->GetRtuAddr(rtuno); uint8 buf[512]; int datalen = 0 ,datanum =0; int buflen=pRxBuf->GetReadableSize(); char tmp[512]=""; int keylen=5; char *ctmp=NULL,cVal[16]=""; if(buflen>512)buflen=512; int nowtime = GetNowSecond(); E_RAW_ComStat coms = pLink->GetCommStatus(); if ( coms == CMST_RX_CNT && (nowtime-m_LastSendTime) >= m_RcvTimeOuts) { //超时不重发,直接跳到下一个终端 pRxBuf->Move(buflen); pLink->RegisterFrm(FRAME_RX_TIMEOUT); pLink->SetCommStatus(CMST_TX_CNT); PrintLog(LOG_VIOLATION, "数据超时\n"); // PRawCtrl->PutAYx(rtuno, 0, 0); return 1; } //登陆返回结果2/100 if (buflen<60) //无数据或数据不够不改变链路通讯状态,继续等待 return 1; datalen = pRxBuf->Read(buf,buflen,DEF_BUFF_NOMOVE); keylen=5; ctmp=NULL; if(NULL==(ctmp=GetAkeyStart((CHAR*)buf,"/body",keylen))) { return 1; } while(datalen>=100 && !(buf[0]=='<' && buf[1]=='?' && buf[2]=='x' && buf[3]=='m' && buf[4]=='l')){ pRxBuf->Move(1); datalen = pRxBuf->Read(buf,buflen,DEF_BUFF_NOMOVE); } memcpy(tmp,buf,buflen); TrimBlank(tmp,buflen); int tLog=0; keylen=5; ctmp=NULL;memset(cVal,0,16); if(NULL!=(ctmp=GetAkeyVal(tmp,"login",keylen))) { if(keylen>15) keylen=15; memcpy(cVal,ctmp,keylen); tLog=atoi(cVal); PrintLog(LOG_INFORMATION,"login=%s ", cVal); } keylen=5; ctmp=NULL;memset(cVal,0,16); if(NULL!=(ctmp=GetAkeyVal(tmp,"state",keylen))) { if(keylen>15) keylen=15; memcpy(cVal,ctmp,keylen); m_state=atoi(cVal); if(1==m_state && 1==tLog){ PRawCtrl->PutAYx(rtuno,0,m_state&1); m_bLogin=TRUE; } else if(0==tLog) {m_bLogin=FALSE;PRawCtrl->PutAYx(rtuno,0,0);} PrintLog(LOG_INFORMATION,"state=%s ", cVal); } m_state=0; keylen=8; ctmp=NULL;memset(cVal,0,16); if(NULL!=(ctmp=GetAkeyVal(tmp,"infotype",keylen))) { if(keylen>15) keylen=15; memcpy(cVal,ctmp,keylen); m_infotype=atoi(cVal); PrintLog(LOG_INFORMATION,"infotype=%s ", cVal); } /*infotype=1按键,2平台回复*/ /*keyvalue=0-9数字,10方向停止,11-18上下左右-左上-左下-右上-右下(步长0-8),20-21变倍大小,22-23近远,24-25光圈大小, 26DEVC,27CAM,28MON,29TOUR,30MAC,31PATTERN,32AUTOPAN,33GOTO,34ENTER,35MULT,36WIN,37CAN-G,38MON-G,39GROUP,40SET,41PT,42LOCK,43SHIFT,44ESC 45跳页,46上一页,47下一页,48轮巡开始,49轮巡停止,50轮巡暂停*/ /*platinfotype=1选择消息回复;2轮巡回复;3云台;4报警;5回显;6状态信息(Mon,Win通道,Cam) */ keylen=12; ctmp=NULL;memset(cVal,0,16); if(NULL!=(ctmp=GetAkeyVal(tmp,"platinfotype",keylen))) { if(keylen>15) keylen=15; memcpy(cVal,ctmp,keylen); m_platinfotype=atoi(cVal); PrintLog(LOG_INFORMATION,"platinfotype=%s ", cVal); } keylen=7; ctmp=NULL;memset(cVal,0,16); if(NULL!=(ctmp=GetAkeyVal(tmp,"message",keylen))) { memset(m_msg,0,100); if(keylen>99) keylen=99; memcpy(m_msg,ctmp,keylen); PrintLog(LOG_INFORMATION,"message=%s ", m_msg); } keylen=3; ctmp=NULL;memset(cVal,0,16); if(NULL!=(ctmp=GetAkeyVal(tmp,"Mon",keylen))) { if(keylen>15) keylen=15; memcpy(cVal,ctmp,keylen); m_mon=atoi(cVal); PrintLog(LOG_INFORMATION,"Mon=%s ", cVal); } keylen=3; ctmp=NULL;memset(cVal,0,16); if(NULL!=(ctmp=GetAkeyVal(tmp,"Win",keylen))) { if(keylen>15) keylen=15; memcpy(cVal,ctmp,keylen); m_win=atoi(cVal); PrintLog(LOG_INFORMATION,"Win=%s ", cVal); } keylen=3; ctmp=NULL;memset(cVal,0,16); if(NULL!=(ctmp=GetAkeyVal(tmp,"Cam",keylen))) { if(keylen>15) keylen=15; memcpy(cVal,ctmp,keylen); m_cam=atoi(cVal); PrintLog(LOG_INFORMATION,"Cam=%s ", cVal); } keylen=5; ctmp=NULL; if(NULL!=(ctmp=GetAkeyStart((CHAR*)buf,"/body",keylen))) { pRxBuf->Move(ctmp-(CHAR*)buf+7+4);///r/d/r/d pLink->SetCommStatus(CMST_NORMAL); pLink->RegisterFrm(FRAME_RX_SUC); } return 1; } void CcctvC3JT::Init(S_PROTOCOLCFG *pcfg) { memset(mHead,0,40); strcat(mHead,""); PRawCtrl = pcfg->PRawCtrl; pRxBuf = pcfg->pRxBuf; pTxBuf = pcfg->pTxBuf; pCmdMem = pcfg->pCmdMem; pRtu = pcfg->pRtu; pLink = pcfg->pLink; pTable = pcfg->pTable; pZfDataCtrl = pcfg->pZfDataCtrl; // pHis = pcfg->pHis; m_infotype=0; m_keyval=0; m_state=0; m_step=0; m_platinfotype=0; memset(m_msg,0,100); m_mon=0; m_win=0; m_cam=0; m_mult=0; // pRxBuf->Move(pRxBuf->GetReadableSize()); // pTxBuf->Move(pTxBuf->GetReadableSize()); m_reloginTime = pLink->GetAllDataScanInterval(); m_RcvTimeOuts = pLink->GetRxTimeouts(); m_ID = 1; m_bLogin = FALSE; m_bCmd = FALSE; m_LastSendTime=0; if(m_reloginTime <= 0) m_reloginTime = 60; if(m_RcvTimeOuts <= 0) m_RcvTimeOuts = 10; //read cfg/cctv.ini //char name[]="admin",pwd[]="admin",ip[]="192.168.1.108",port[]="9000"; char filename[512]; CReadConf readconf; char *pWorkPath; pWorkPath=getenv("FEPROOT"); if(pWorkPath!=NULL) sprintf(filename,"%s%s",pWorkPath,"/cfg/cctv.ini"); readconf.ReadString("LoginInfo","PlatIP",ip,filename,"127.0.0.1"); readconf.ReadString("LoginInfo","PlatPort",port,filename,"502"); readconf.ReadString("LoginInfo","UserName",name,filename,"admin"); readconf.ReadString("LoginInfo","Password",pwd,filename,"admin"); TxFlag=-1; TxIndex=0; } char* CcctvC3JT::GetAkeyStart(char * buf,char *key,int &len) { int rlen=0; char key1[16]="<"; memcpy(key1+1,key,len);key1[1+len]='>';key1[2+len]=0; char *str1=strstr(buf,key1); if(NULL != str1){ return str1; } return NULL; } char* CcctvC3JT::GetAkeyVal(char * buf,char *key,int &len) { int rlen=0; char key1[16]="<"; memcpy(key1+1,key,len);key1[1+len]='>';key1[2+len]=0; char key2[16]="';key2[3+len]=0; char *str1=strstr(buf,key1); char *str2=strstr(buf,key2); if(NULL != str1 && NULL != str2){ rlen=str2-str1-len-2; str1+=len+2; if(rlen>0)len=rlen; return str1; } return NULL; } /*infotype=1按键,2平台回复*/ /*keyvalue=0-9数字,10方向停止,11-18上下左右-左上-左下-右上-右下(step步长0-8),20-21变倍大小,22-23近远,24-25光圈大小, 26DEVC,27CAM,28MON,29TOUR,30MAC,31PATTERN,32AUTOPAN,33GOTO,34ENTER,35MULT,36WIN,37CAN-G,38MON-G,39GROUP,40SET,41PT,42LOCK,43SHIFT,44ESC 45跳页,46上一页,47下一页,48轮巡开始,49轮巡停止,50轮巡暂停*/ /*platinfotype=1选择消息回复;2轮巡回复;3云台;4报警;5回显;6状态信息(Mon,Win通道,Cam) */ BOOL CcctvC3JT::ProcCmd() { if(0GetRtuNo(); unsigned char rtuaddr = pRtu->GetRtuAddr(rtuno); S_RAWCMD rawcmd; while (pCmdMem->GetCmdNum(rtuno) > 0) { if (pCmdMem->GetACmd(rtuno, &rawcmd) == 0) break; if (rawcmd.type == DC_K_CMD_CCTVCTRL) { m_bCmd = TRUE; CSI_D_CCTV_CMD *CctvCmd; CctvCmd = (CSI_D_CCTV_CMD *)rawcmd.data; m_cmdAddr = rawcmd.src; int len = 0; uint8 nSpeed = CctvCmd->Val/0x100; uint8 nOper = CctvCmd->Val %0x100; int nPtz=PTZConv(nOper); if(nPtz>=11 && nPtz<=18) nSpeed*=11;//竟天步长*6/64运算 if(nPtz>=22 && nPtz<=23)nPtz-=2;//用变倍大20替换焦距+22;用变倍小21替换焦距-23;//wyf 20190214 char scangroup[16]="0"; char sta[16]="",cam[16]="",mon[16]="",win[16]="",ptz[16]="",speed[16]="",cmdval[16]=""; sprintf(cam,"%d",CctvCmd->Cam);/*sprintf(mon,"%d",CctvCmd->Mon);*/sprintf(mon,"%d",CctvCmd->decode);//Yansx 2019-02-28 sprintf(cmdval,"%d",nOper);sprintf(sta,"%d",CctvCmd->Sta);sprintf(win,"%d",CctvCmd->Win);sprintf(ptz,"%d",nPtz);sprintf(speed,"%d",nSpeed); switch (CctvCmd->Func) { case 1://CCTV_FUNC_MON: //摄像头选择=数字+DEVC键26+数字+MON28+数字+CAM键27 TxFlag=CctvCmd->Func; memset(&m_tBuf,0,sizeof(m_tBuf)); PrintLog(LOG_INFORMATION,"开始切换目标监视器%d:,摄像机编号%d,解码器编号%d", CctvCmd->Mon,CctvCmd->Cam,CctvCmd->decode); /* for(i=0;iMult){ PrintLog(LOG_INFORMATION, "切换为[%d X %d]分屏",CctvCmd->Mult+1,CctvCmd->Mult+1); PressKey("35","1","0"); m_tBuf.FrameNum++; PressKey("35","0","0"); m_tBuf.FrameNum++; m_mult=CctvCmd->Mult; } //WYF 20190127 Add Mult 35 func TxIndex=0; TxBufwrite(); break; case 4://CCTV_FUNC_VIEW: TxFlag=CctvCmd->Func; memset(&m_tBuf,0,sizeof(m_tBuf)); PrintLog(LOG_INFORMATION,"开始调用预置位"); for(i=0;iFunc; memset(&m_tBuf,0,sizeof(m_tBuf)); PrintLog(LOG_INFORMATION,"开始设置预置位"); for(i=0;iFunc; memset(&m_tBuf,0,sizeof(m_tBuf)); PrintLog(LOG_INFORMATION,"开始PTZ控制,控制类型%d,速度%d[监视器%d:,摄像机编号%d,解码器编号%d]", nOper, nSpeed, CctvCmd->Mon,CctvCmd->Cam,CctvCmd->decode); // PressKey("10","1","0");m_tBuf.FrameNum++;//停止方向 // PressKey("10","0","0");m_tBuf.FrameNum++;//停止方向 if(nPtz>=11 && nPtz<=18){ // PressKey(ptz,"0","0"); m_tBuf.FrameNum++;//先发停止 PressKey(ptz,"1",speed);m_tBuf.FrameNum++; PressKey(ptz,"0","0");m_tBuf.FrameNum++;//按键弹起 // PressKey("0","0","0"); m_tBuf.FrameNum++;//按照大华键盘实际报文.txt?????是否要 // PressKey("10","1","0");m_tBuf.FrameNum++;//停止方向 // PressKey("10","0","0");m_tBuf.FrameNum++;//停止方向 } if(nPtz>=20 && nPtz<=25){//变倍大-小、聚焦近-远、光圈大-小 PressKey(ptz,"1","0"); m_tBuf.FrameNum++; PressKey(ptz,"0","0"); m_tBuf.FrameNum++; } TxIndex=0; TxBufwrite(); break; case 3://CCTV_FUNC_SCAN:轮巡//50暂停不支持 TxFlag=CctvCmd->Func; memset(&m_tBuf,0,sizeof(m_tBuf)); PrintLog(LOG_INFORMATION, "轮巡值%d", CctvCmd->Val); if(0==nOper){ PressKey("49",cmdval,"0");m_tBuf.FrameNum++; } else { for(i=0;iFunc; memset(&m_tBuf,0,sizeof(m_tBuf)); PrintLog(LOG_INFORMATION, "轮巡暂停"); PressKey("50",cmdval,"0"); m_tBuf.FrameNum++;//1-暂停;0-暂停取消 PressKey("10","1","0"); m_tBuf.FrameNum++;//停止方向 PressKey("10","0","0"); m_tBuf.FrameNum++;//停止方向 TxIndex=0; TxBufwrite(); break; default: memset(&m_tBuf,0,sizeof(m_tBuf)); TxFlag=-1; break; } pCmdMem->DelACmd(rtuno); return TRUE; } else//对其它的下发命令不处理 pCmdMem->DelACmd(rtuno); break; } return FALSE; } int CcctvC3JT::GetNowSecond() { CSeTime SE_T; TCriterionTime tmptime; SE_T.GetNow(&tmptime); return (int)tmptime; } void CcctvC3JT::SetExtendedPara(uint16 no, sint32 val) { if ( no == 1 ) { if (val == 1) m_ID = val + 59; else m_ID = 1; } else m_ID = 1; } //1:Challenge_request;2:Challenge_response;3:Auth_login_success;4;Auth_login_fail;5:Auth_login;6:Auth_logout void CcctvC3JT::Login(char *name,char *pwd,char *ip,char *port) { m_bLogin=FALSE; char buf[256]; int p = 0; memcpy(buf+p,mHead,HEADLEN);p+=HEADLEN; buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=6; buf[p++]='\r';buf[p++]='\n'; //body////////////////////////////////////////////////////// strcpy(buf+p,""); p+=7; buf[p]='1'; p+=1;//登入 strcpy(buf+p,""); p+=8; buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=10; strncpy(buf+p,name,strlen(name)); p+=strlen(name);//name strcpy(buf+p,""); p+=11; buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=10; strncpy(buf+p,pwd,strlen(pwd)); p+=strlen(pwd);//pwd strcpy(buf+p,""); p+=11; buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=4; strncpy(buf+p,ip,strlen(ip)); p+=strlen(ip);//ip192.168.1.1 strcpy(buf+p,""); p+=5; buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=6; strncpy(buf+p,port,strlen(port)); p+=strlen(port);//port9000 strcpy(buf+p,""); p+=7; buf[p++]='\r';buf[p++]='\n'; //body////////////////////////////////////////////////////// strcpy(buf+p,""); p+=7; buf[p++]='\r';buf[p++]='\n';buf[p++]='\r';buf[p++]='\n'; pTxBuf->Write((uint8 *)buf,p); pLink->SetCommStatus(CMST_RX_CNT); pLink->RegisterFrm(FRAME_TX_SUC); m_LastSendTime = GetNowSecond(); PrintLog(LOG_INFORMATION,"发送登录命令%d",p); return; } void CcctvC3JT::PressKey(char *keyval,char *state,char *step) { char buf[256]; int p = 0; memcpy(buf+p,mHead,HEADLEN);p+=HEADLEN; buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=6; buf[p++]='\r';buf[p++]='\n'; //body////////////////////////////////////////////////////// strcpy(buf+p,""); p+=10; buf[p]='1'; p+=1;//按键infotype=1 strcpy(buf+p,""); p+=11; buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=10; strncpy(buf+p,keyval,strlen(keyval)); p+=strlen(keyval);//1按下,0弹起 strcpy(buf+p,""); p+=11; buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=7; strncpy(buf+p,state,strlen(state)); p+=strlen(state);//主要用于云台操作步长,默认使用变步长 strcpy(buf+p,""); p+=8; buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=6; strncpy(buf+p,step,strlen(step)); p+=strlen(step);//主要用于云台操作步长,默认使用变步长 strcpy(buf+p,""); p+=7; buf[p++]='\r';buf[p++]='\n'; //body////////////////////////////////////////////////////// strcpy(buf+p,""); p+=7; buf[p++]='\r';buf[p++]='\n';buf[p++]='\r';buf[p++]='\n'; m_tBuf.Len[m_tBuf.FrameNum]=p; memcpy(m_tBuf.Buf[m_tBuf.FrameNum],buf,p); // pTxBuf->Write((uint8 *)buf,p); // pLink->SetCommStatus(CMST_NORMAL); // pLink->RegisterFrm(FRAME_TX_SUC); // m_LastSendTime = GetNowSecond(); // PrintLog(LOG_INFORMATION,"发送key=%s命令state=%s,step=%s,time=%d",keyval,state,step,m_LastSendTime); return; } void CcctvC3JT::TxBufwrite() { int now=GetNowSecond(); if(TxIndex1){ pTxBuf->Write((uint8 *)m_tBuf.Buf[TxIndex],m_tBuf.Len[TxIndex]); TxIndex++; pLink->SetCommStatus(CMST_NORMAL); pLink->RegisterFrm(FRAME_TX_SUC); m_LastSendTime = GetNowSecond(); } } else{ pTxBuf->Write((uint8 *)m_tBuf.Buf[TxIndex],m_tBuf.Len[TxIndex]); TxIndex++; pLink->SetCommStatus(CMST_NORMAL); pLink->RegisterFrm(FRAME_TX_SUC); m_LastSendTime = GetNowSecond(); } } else{ TxIndex=0; memset(&m_tBuf,0,sizeof(m_tBuf)); TxFlag=-1; } // PrintLog(LOG_INFORMATION,"CCTV按键发送时间:%d",m_LastSendTime); return; } void CcctvC3JT::Aim(uint8 oper,uint8 wall,uint8 task,uint8 mon,uint8 mult,uint8 win,uint8 cam)//,uint8 ptz,uint8 ptzpara) { char buf[256]; int p = 0; memcpy(buf+p,mHead,HEADLEN);p+=HEADLEN; buf[p++]='\r';buf[p++]='\n';buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=6; buf[p++]='\r';buf[p++]='\n';buf[p++]='\r';buf[p++]='\n'; strcpy(buf+p,""); p+=10; buf[p]='2'; p+=1;//登入 strcpy(buf+p,""); p+=11; buf[p++]='\r';buf[p++]='\n';buf[p++]='\r';buf[p++]='\n'; ////////// strcpy(buf+p,""); p+=7; buf[p++]='\r';buf[p++]='\n';buf[p++]='\r';buf[p++]='\n'; pTxBuf->Write((uint8 *)buf,p); pLink->SetCommStatus(CMST_NORMAL); m_LastSendTime = GetNowSecond(); PrintLog(LOG_INFORMATION,"发送切视频命令%d",p); /* BYTE buf[20]; int p = 0; buf[p] = 0x68;p++; buf[p] = 0xee;p++; buf[p] = 0x00;p++; buf[p] = 0x00;p++; buf[p] = 14;p++; buf[p] = 0x00;p++;// buf[p] = oper;p++;//操作 buf[p] = 0x00;p++;// buf[p] = wall;p++;//电视墙 buf[p] = task;p++;//任务id buf[p] = mon;p++;//屏(解码器通道)编号 buf[p] = mult;p++;//分割屏数--- buf[p] = win;p++;//窗口编号 buf[p] = cam;p++;//通道视频源 buf[p] = 0x00;p++;//ptz buf[p] = 0x00;p++;//ptzpara buf[p] = 0x00;p++;// buf[p] = 0x00;p++;//rec buf[p] = 0x00;p++;//recpara */ return; } //2bytes,11:电视墙;12:任务;21:选屏;22:分隔切换;23:选窗口;24:切换视频源;31:云台;41:录像;51:抓拍 //1 2 3 4 5 6 7 8 9 10 11 12 //角色值 操作大类LoHi 电视墙 任务 屏 分割 窗 通道视频源 云台 云台参数LoHi 录像 录像参数 int CcctvC3JT::PTZConv(uint8 ptz) { int tPtz=0; tPtz=ptz; switch(tPtz){ case 0://停 case 1://上下左右 case 2: case 3: case 4: tPtz+=10; break; case 11://左上,左下,右上,右下 case 12: case 13: case 14: tPtz+=4; break; case 5://变倍大小,光圈大小 case 6: case 9: case 10: tPtz+=15; break; case 8://近焦 tPtz+=14; break; case 7://远焦 tPtz+=16; break; } return tPtz; } //规约对象创建函数 #ifdef __unix extern "C" CProtocol* CreateProtocol(char *defpara) #else extern "C" __declspec(dllexport) CProtocol* CreateProtocol(char *defpara) #endif { CProtocol *pEpv = new CcctvC3JT; return pEpv; }