#include "SE102c.h" #pragma pack(1) /* CSE102c::CSE102c() { } CSE102c::~CSE102c() { } */ void CSE102c::Init(S_PROTOCOLCFG * pcfg) { PRawCtrl = pcfg->PRawCtrl; pRxBuf = pcfg->pRxBuf; pTxBuf = pcfg->pTxBuf; pCmdMem = pcfg->pCmdMem; pRtu = pcfg->pRtu; pLink = pcfg->pLink; pTable = pcfg->pTable; pZfDataCtrl = pcfg->pZfDataCtrl; InitStation(); } void CSE102c::InitStation() { sint32 rtuno = pLink->GetRtuNo(); int buflen = pRxBuf->GetReadableSize(); pRxBuf->Move(buflen); buflen = pTxBuf->GetReadableSize(); pTxBuf->Move(buflen); LostNum = 0; int curtime = GetNowSecond(); cmdType = 0; LastTxTime = curtime; LastRxTime = curtime; LastCallkwhTime = curtime; LastSyncTime = curtime; AppLayerStat = IEC102_APP_STATE_WAITSTART; SendSeqNo = 0; ReceiveSeqNo = 0; ConSeqNo = 0; ResendCount = 0; ResendCountLimit = pLink->GetRetryTimes(); //CallAllDataFlag = 1; // CallKwhDataFlag = 0; Timeout2 = 1; Timeout3 = 15; RecordTime = 0; RtuTimeFlag = 0; SendACKFlag = 0; pLink->SetCommStatus(CMST_NORMAL); LastCmdNeedRet = 0; } int CSE102c::SendStartFormat() { uint8* ptr = senddata.databuf; static int start = 0; senddata.headP = senddata.trailP = 0; int curtime = GetNowSecond(); if (curtime - LastTxTime < Timeout2 || curtime - LastRxTime < Timeout2) { return -1; } *ptr++ = 0x10; *ptr++ = 0x49; *ptr++ = 0x01; *ptr++ = 0x00; *ptr++ = 0x4a; *ptr++ = 0x16; senddata.trailP = ptr - senddata.databuf; AppToLink(); PrintLog(LOG_INFORMATION, "发送start连接命令! 序号:%d",++start); //if (AppLayerStat == IEC102_APP_STATE_IDLE) //空闲状态下才能刷新LastTxTime! LastTxTime = curtime; return 1; } int CSE102c::SendResetFormat() { uint8* ptr = senddata.databuf; senddata.headP = senddata.trailP = 0; int curtime = GetNowSecond(); if (curtime - LastTxTime < Timeout2 || curtime - LastRxTime < Timeout2) { return -1; } *ptr++ = 0x10; *ptr++ = 0x40; *ptr++ = 0x01; *ptr++ = 0x00; *ptr++ = 0x41; *ptr++ = 0x16; senddata.trailP = ptr - senddata.databuf; AppToLink(); // if (AppLayerStat == IEC102_APP_STATE_IDLE) //空闲状态下才能刷新LastTxTime! LastTxTime = curtime; PrintLog(LOG_INFORMATION, "发送复位连接命令! "); return 1; } void CSE102c::CallKwhData(short endAddr, short startAddr) { static int callKwh = 0; int curtime = GetNowSecond(); if (curtime - LastTxTime < Timeout2 || curtime - LastRxTime < Timeout2) { //PrintLog(LOG_INFORMATION, "发送电度命令失败! "); return ; } RecordTime = GetNowSecond(); int rtuno = pLink->GetRtuNo(); uint16 addr = pRtu->GetRtuAddr(rtuno); uint8 *Buff = senddata.databuf; DC_D_DATAUNITID DataHead; senddata.headP = senddata.trailP = 0; DataHead.TypeID = C_CI_ZJ_2; DataHead.VSQ.Num = 1; DataHead.VSQ.SQ = 0; DataHead.Cause = APP_COT_ACT; DataHead.CommonAddrLo = 0x01; DataHead.CommonAddrHi = 0x00; DataHead.RadAddr = 0x9f; *Buff++ = 0x68; *Buff++ = 0x0D; *Buff++ = 0x0D; int dataLen = 13; *Buff++ = 0x68; uint8* ptr = Buff; short tempJiaoyan = 0; *Buff++ = 0x53; *Buff++ = 0x01; *Buff++ = 0x00; memcpy(Buff, (uint8*)&DataHead, sizeof(DC_D_DATAUNITID)); Buff += sizeof(DC_D_DATAUNITID); //实时数据地址范围 /**Buff++ = 0x00; *Buff++ = 0x00; *Buff++ = 0xD9; // *Buff++ = 0x00;*/ uint8 startL = startAddr & 0x00ff; uint8 startH = (startAddr & 0xff00) >> 8; uint8 endL = endAddr & 0x00ff; uint8 endH = (endAddr & 0xff00) >> 8; *Buff++ = startL; *Buff++ = startH; *Buff++ = endL; // *Buff++ = endH; PrintLog(LOG_INFORMATION, ">>>>>> 实时电度召唤报文 startAddr:%d ,endAddr:%d ,startL:%d, endL:%d ", startAddr,endAddr,startL,endL); for (int i = 0; i < dataLen; ++i) { tempJiaoyan += *(ptr++); } *Buff++ = tempJiaoyan & 0x00ff; *Buff++ = 0x16; senddata.trailP = Buff - senddata.databuf; AppToLink(); AppLayerStat = IEC102_APP_STATE_WAITALLKWHCONF; Timeout3 = Timeout2; PrintLog(LOG_INFORMATION, ">>>>>> 发送实时电度召唤命令 序号:%d",++callKwh); //每发送一I帧数据SendSeqNo加1,清发送确认标志SendACKFlag。 //SendSeqNo = (SendSeqNo + 1) % 0x8000; //SendACKFlag = 0; LastTxTime = GetNowSecond(); // LastCmdNeedRet = LASTCALL_ACCDATA; } void CSE102c::App_CheckState() { int curtime = GetNowSecond(); sint32 rtuno = pLink->GetRtuNo(); short endAddr = pRtu->GetKwhNum(rtuno); int secnum; switch (AppLayerStat) { case IEC102_APP_STATE_IDLE: break; case IEC102_APP_STATE_WAITSTART: SendStartFormat(); break; case IEC102_APP_STATE_UNRESET: // PrintLog(LOG_INFORMATION, "发送复位连接命令! "); SendResetFormat(); break; case IEC102_APP_STATE_WAITTIMECONF: // PrintLog(LOG_INFORMATION, "发送召唤二级数据命令! "); Call5KwhData();; break; case IEC102_APP_STATE_WAITALLKWHCONF: // PrintLog(LOG_INFORMATION, "发送召唤二级数据命令! "); Call7KwhData(); break; case IEC102_APP_STATE_WAITGRPDATA: // PrintLog(LOG_INFORMATION, "发送召唤历史数据命令! "); SendHidataToSubstation();; break; case IEC102_APP_STATE_WAITGRPKWH: CallKwhData(endAddr); break; case IEC102_APP_STATE_WAITALLKWH: if (curtime - LastTxTime >30) { AppLayerStat = IEC102_APP_STATE_IDLE; CallKwhDataFlag = 0; } break; default: PrintLog(LOG_INFORMATION, "IEC104 Invalid primary app state "); break; } } /*电度接收处理 */ void CSE102c::App_ReceiveProc() { sint32 rtuno = pLink->GetRtuNo(); uint8 * ptr = recvdata.databuf; //sint32 KwhValue; //uint16 index = 0; DC_D_DATAUNITID * pDataHead = (DC_D_DATAUNITID *)recvdata.databuf; uint8 TypeID = pDataHead->TypeID; uint8 number = pDataHead->VSQ.Num; uint8 sq = pDataHead->VSQ.SQ; switch (TypeID) { case M_IT_TA_2: //case M_SP_TA_2: RecordTime = GetNowSecond(); PrintLog(LOG_INFORMATION, "收到KWH帧 类型%d ", TypeID); App_KwhProc(); break; default: PrintLog(LOG_INFORMATION, "收到没有解释的报文 类型%d ", TypeID); break; } recvdata.headP = recvdata.trailP = 0; } int CSE102c::App_PipeProc() { sint32 rtuno = pLink->GetRtuNo(); //if (pCmdMem->GetCmdNum(rtuno) <= 0) // return FALSE; S_RAWCMD rawcmd; //if (pCmdMem->GetACmd(rtuno, &rawcmd) == 0) // return FALSE; //if (rawcmd.type == DC_K_CMD_SYNCTIME) { //后台发对时命令 RtuTimeFlag = 1; pCmdMem->DelACmd(rtuno); return FALSE; } /*{ pCmdMem->DelACmd(rtuno); return FALSE; } return FALSE*/; } void CSE102c::App_KwhProc() { sint32 rtuno = pLink->GetRtuNo(); uint8 * Buff = recvdata.databuf; DC_D_DATAUNITID * pDataHead = (DC_D_DATAUNITID *)recvdata.databuf; uint8 TypeID = pDataHead->TypeID; uint8 number = pDataHead->VSQ.Num; uint8 sq = pDataHead->VSQ.SQ; sint32 KwhValue; uint8 Qual; int i; uint16 index = *(Buff + DC_D_HEADLEN ) + ( *(Buff + DC_D_HEADLEN + 1) << 8); PrintLog(LOG_INFORMATION, "收到电度报文 索引%d ", index); //注意,电度值字节序问题 switch (TypeID) { case M_IT_TA_2://2:电度 for (i = 0; i= recvdata.trailP) { PrintLog(LOG_INFORMATION, "电度信息体数目异常 "); break; }*/ uint8 tempInt = *(Buff + DC_D_HEADLEN + 2); uint8 firstValue = *(Buff + DC_D_HEADLEN + i * DC_D_INFOADDRLEN + 2); uint8 tempSe = *(Buff + DC_D_HEADLEN + i * DC_D_INFOADDRLEN + 3); sint32 tempSecond = tempSe << 8; sint32 secondValue = (*(Buff + DC_D_HEADLEN + i * DC_D_INFOADDRLEN + 3)) << 8; sint32 thirdValue = ((*(Buff + DC_D_HEADLEN + i * DC_D_INFOADDRLEN + 4)) << 8) << 8; sint32 fourValue = (((*(Buff + DC_D_HEADLEN + i * DC_D_INFOADDRLEN + 5)) << 8) << 8 )<< 8; KwhValue = firstValue + secondValue + thirdValue + fourValue; if (index > 216) { RecordTime = GetNowSecond(); } PrintLog(LOG_INFORMATION, "收到电度报文 索引%d 电度:%d", index, KwhValue); PRawCtrl->PutAKwh(rtuno, index, KwhValue); //recvdata.headP += 5; if (sq) { index++; } else { index = *(Buff + DC_D_HEADLEN + (i + 1)* DC_D_INFOADDRLEN) + (*(Buff + DC_D_HEADLEN + 1 + (i + 1)* DC_D_INFOADDRLEN) << 8); } } break; case M_SP_TA_2://1:带时标的电度 /*CP56Time2a tmTime; for (i = 0; i= recvdata.trailP) { PrintLog(LOG_INFORMATION, "带时标电度信息体数目异常 "); break; } #ifdef NET_BYTEORDER KwhValue = (*(Buff + recvdata.headP + 3)) << 24 + (*(Buff + recvdata.headP + 2)) << 16 + (*(Buff + recvdata.headP + 1)) << 8 + *(Buff + recvdata.headP); #else KwhValue = *((sint32 *)(Buff + recvdata.headP)); #endif Qual = *(Buff + recvdata.headP + 4); recvdata.headP += 5; memcpy((uint8 *)&tmTime, Buff + recvdata.headP, sizeof(CP56Time2a)); if ((Qual & 0x80) == 0) { PRawCtrl->PutAKwh(rtuno, index, KwhValue); } recvdata.headP += sizeof(CP56Time2a); index = (*(Buff + recvdata.headP) + (*(Buff + recvdata.headP + 1) * 256)); recvdata.headP += DC_D_INFOADDRLEN; }*/ break; default: PrintLog(LOG_INFORMATION, "收到没有解释的报文 类型%d ", TypeID); } } //描述: 检测是否须召唤全数据、电度,同步时钟,并置相应标志. void CSE102c::App_CheckTime() { int curtime = GetNowSecond(); if (pLink->GetKwhScanInterval()>0) { if (curtime - LastCallkwhTime >= pLink->GetKwhScanInterval() * 60) { CallKwhDataFlag = 1; LastCallkwhTime = curtime; } } int spacetime = pRtu->GetSyncTimeInt(pLink->GetRtuNo()); if (spacetime>0) { if (int(curtime - LastSyncTime) >= spacetime * 60) { RtuTimeFlag = 1; LastSyncTime = curtime; } } } int CSE102c::GetNowSecond() { CSeTime SE_T; TCriterionTime tmptime; SE_T.GetNow(&tmptime); return (int)tmptime; } void CSE102c::App_RxFixFrame(uint8 *buf, int buflen) { sint32 rtuno = pLink->GetRtuNo(); pLink->RegisterFrm(FRAME_RX_SUC); if (buf[1] == 0x0b) { PrintLog(LOG_INFORMATION, "收到启动确认帧 "); SendSeqNo = 0; ReceiveSeqNo = 0; AppLayerStat = IEC102_APP_STATE_UNRESET; //SendResetFormat(); } else if (buf[1] == 0x00) { PrintLog(LOG_INFORMATION, "收到复位确认帧 "); SendSeqNo = 0; ReceiveSeqNo = 0; SendACKFlag = 1; AppLayerStat = IEC102_APP_STATE_IDLE; } else { PrintLog(LOG_INFORMATION, "收到未知帧 "); } pLink->RegisterFrmCode(RAW_CODEDIR_UP, (char *)buf, 6); pRxBuf->Move(buflen); } int CSE102c::App_RxVarFrame(uint8 *buf, int buflen) { unsigned char initflag = 0; sint32 rtuno = pLink->GetRtuNo(); int time = GetNowSecond(); int tempInt = time - RecordTime; int DataLen = buf[1]; ReceiveSeqNo++; //存放的是当前的序列号 memcpy(recvdata.databuf, buf + 7, DataLen - 3); //recvdata.trailP = DataLen + 2; //recvdata.headP = 0; if (buf[7] == 0x80) { PrintLog(LOG_INFORMATION, "收到对时确认帧 "); RecordTime = GetNowSecond(); AppLayerStat = IEC102_APP_STATE_WAITGRPKWH; } else if (buf[7] == 0x02) { static int sendID = 0; if (AppLayerStat == IEC102_APP_STATE_WAITTIMECONF || AppLayerStat == IEC102_APP_STATE_WAITGRPKWH) AppLayerStat = IEC102_APP_STATE_WAITALLKWHCONF; else if (AppLayerStat == IEC102_APP_STATE_WAITALLKWHCONF || AppLayerStat == IEC102_APP_STATE_WAITGRPDATA) AppLayerStat = IEC102_APP_STATE_WAITTIMECONF; App_ReceiveProc();//接收处理 //if (/*(tempInt) % 30 == 0 || tempInt % 12 == 0 || tempInt % 13 == 0 || */tempInt % 12 == 0) //单字符格式 { // AppLayerStat = IEC102_APP_STATE_WAITGRPKWH; // PrintLog(LOG_INFORMATION, "收到二级数据的报文 发送实时数据序号%d ", ++sendID); } //if ((tempInt) % 1200 == 0) //单字符格式 { //AppLayerStat = IEC102_APP_STATE_WAITGRPDATA; } } else { PrintLog(LOG_INFORMATION, "收到可变长未知确认帧 typeID:%d",buf[7]); } *buf++ = 4 + DataLen + 2; SendACKFlag++; pLink->RegisterFrm(FRAME_RX_SUC); pLink->RegisterFrmCode(RAW_CODEDIR_UP, (char *)buf, DataLen + 6); pRxBuf->Move(DataLen + 6); return 1; } sint32 CSE102c::RxProc() { uint8 buf[512]; int buflen = pRxBuf->GetReadableSize(); if (buflen <= 0) { //PrintLog(LOG_INFORMATION, "收到数据帧格式错误"); return -1; } int nRet = 0; sint32 datalen = 0; LastRxTime = GetNowSecond(); //收到帧,刷新接收计时器 int tempInt = LastRxTime - RecordTime; if (buflen == 1) { Timeout3 = 15; //PrintLog(LOG_INFORMATION, "收到单字符确认帧 :buflen:%d,发送号:%d", buflen, SendSeqNo); if (AppLayerStat == IEC102_APP_STATE_WAITTIMECONF || AppLayerStat == IEC102_APP_STATE_WAITGRPKWH) AppLayerStat = IEC102_APP_STATE_WAITALLKWHCONF; else if (AppLayerStat == IEC102_APP_STATE_WAITALLKWHCONF || AppLayerStat == IEC102_APP_STATE_WAITGRPDATA) AppLayerStat = IEC102_APP_STATE_WAITTIMECONF; //if (tempInt > 300) if (tempInt > 300) //召唤实时数据间隔5分钟 { static int sendAID = 0; AppLayerStat = IEC102_APP_STATE_WAITGRPKWH; PrintLog(LOG_INFORMATION, "<<<<<<<<<收到单字节的报文 发送实时数据序号%d 时间差:%d", ++sendAID,tempInt); } //if ((tempInt) % 1200 == 0) //单字符格式 //{ // AppLayerStat = IEC102_APP_STATE_WAITGRPDATA; //} pLink->RegisterFrmCode(RAW_CODEDIR_UP, (char *)buf, buflen); pRxBuf->Move(buflen); } else { while ((buflen = pRxBuf->GetReadableSize()) >= 6 ) { if (buflen > 512) buflen = 512; datalen = pRxBuf->Read(buf, buflen, DEF_BUFF_NOMOVE); if (buf[0] != 0x68 && buf[0] != 0x10 ) { sint32 unuse = 0; while (unuse < datalen) { if (buf[unuse] != 0x68 && buf[unuse] != 0x10) unuse++; else { break; } } pRxBuf->Move(unuse); continue; } if (buf[0] == 0x68) //可变帧帧格式 { nRet = App_RxVarFrame(buf, buflen); if (!nRet) break; } else if (buf[0] == 0x10) //固定帧帧格式 { App_RxFixFrame(buf, buflen); break; } else { } } } return 1; } void CSE102c::AppToLink() { int curtime = GetNowSecond(); /*if (curtime - LastTxTime < Timeout2 || curtime - LastRxTime < Timeout2) { return; }*/ uint8 * ptr = senddata.databuf; int len = senddata.trailP; pLink->RegisterFrmCode(RAW_CODEDIR_DOWN, (char *)ptr, len); pTxBuf->Write(ptr, len); PrintLog(LOG_INFORMATION, ">>>>>> 发送命令success "); } void CSE102c::SendTimeToSubstation() { int rtuno = pLink->GetRtuNo(); uint16 addr = pRtu->GetRtuAddr(rtuno); int curtime = GetNowSecond(); if (curtime - LastTxTime < Timeout2 || curtime - LastRxTime < Timeout2) { return; } CP56Time2b T_102; memset(&T_102,0,sizeof(T_102)); DC_D_DATAUNITID DataHead; uint8 *Buff = senddata.databuf; senddata.headP = senddata.trailP = 0; uint16 SendNum, RevNum; SendNum = SendSeqNo << 1; RevNum = ReceiveSeqNo << 1; DataHead.TypeID = C_SYN_TA_2; DataHead.VSQ.Num = 1; DataHead.VSQ.SQ = 0; DataHead.Cause = APP_COT_ACT; DataHead.RadAddr = 0x00; DataHead.CommonAddrLo = 0x01;//addr % 256; DataHead.CommonAddrHi = 0x00;//addr / 256; const uint8 sendLen = 16; *Buff++ = 0x68; *Buff++ = 0x10; *Buff++ = 0x10; *Buff++ = 0x68; uint8* ptr = Buff; *Buff++ = 0x73; *Buff++ = 0x01; *Buff++ = 0x00; //*Buff++ = 4 + DC_D_HEADLEN + 3 + sizeof(CP56Time2b); memcpy(Buff, (uint8*)&DataHead, DC_D_HEADLEN); Buff += DC_D_HEADLEN; //*Buff++ = 0; //*Buff++ = 0; //*Buff++ = 0; //InfoAddr 3 byte SSE_CLOCK systime; CSeTime SE_T; SE_T.GetNow(&systime); T_102.MinuteInfo.minute = systime.minute; T_102.HourInfo.hour = systime.hour; T_102.DayInfo.dfw = systime.day; //T_101.DaysWeeks.Weeks = systime.wday; T_102.MonthInfo.month = systime.month; T_102.YearInfo.year = (systime.year - 2000); T_102.SecondStruct.mileSecond = systime.msecond; T_102.SecondStruct.second = systime.second; uint16 tempT = 0; uint8 tempP = *ptr; uint8 tempS = *(ptr + 1); uint8 tempB = *(ptr + 2); uint8 tempC = *(ptr + 6); /*for (int i = 0; i < sendLen; ++i) { tempT += *(ptr + i); }*/ memcpy(Buff, (uint8*)&T_102, sizeof(CP56Time2b) -1); uint8 tempF = *(ptr + 9); tempT = 0x74 + 0x88 + *(ptr + 9) + *(ptr + 10) + *(ptr + 11) + *(ptr + 12) + *(ptr + 13) + *(ptr + 14) + *(ptr + 15); uint8 tempE = *(ptr + 15); T_102.jiaoYan = tempT & 0x00ff; uint8 timeLen = sizeof(CP56Time2b); Buff += (timeLen -1); *Buff++ = T_102.jiaoYan; *Buff++ = 0x16; senddata.trailP = Buff - senddata.databuf; AppToLink(); //SendSeqNo = (SendSeqNo + 1) % 0x8000; SendACKFlag = 0; LastTxTime = GetNowSecond();; AppLayerStat = IEC102_APP_STATE_WAITTIMECONF; RecordTime = GetNowSecond(); PrintLog(LOG_INFORMATION, ">>>>>> 发送对时命令 "); LastCmdNeedRet = LASTCALL_SETTIME; } int CSE102c::SendHidataToSubstation(/*CP40Time2a &time_start, CP40Time2a &time_end, short addr_end, short addr_start*/) { uint8* buff = senddata.databuf; uint8* ptr; CP40Time2a T_102_s,T_102_e; memset(&T_102_s,0,sizeof(T_102_s)); memset(&T_102_e, 0, sizeof(T_102_e)); DC_D_DATAUNITID DataHead; senddata.headP = senddata.trailP = 0; SSE_CLOCK systime; CSeTime SE_T; SE_T.GetNow(&systime); int curtime = GetNowSecond(); if (curtime - LastTxTime < Timeout3 || curtime - LastRxTime < Timeout3) { return -1; } *buff++ = 0x68; *buff++ = 0x17; *buff++ = 0x17; *buff++ = 0x68; *buff++ = 0x53; *buff++ = 0x01; *buff++ = 0x00; DataHead.TypeID = C_CI_NR_2; DataHead.VSQ.Num = 1; DataHead.VSQ.SQ = 0; DataHead.Cause = APP_COT_ACT; DataHead.RadAddr = 0x9f; DataHead.CommonAddrLo = 0x01;//addr % 256; DataHead.CommonAddrHi = 0x00; memcpy(buff, (uint8*)&DataHead, DC_D_HEADLEN); buff += DC_D_HEADLEN; ptr = buff; //信息体地址 *buff++ = 0x00; *buff++ = 0x00; *buff++ = 0xDC; *buff++ = 0x00; T_102_s.MinuteInfo.minute = systime.minute; T_102_s.HourInfo.hour = systime.hour; T_102_s.YearInfo.year = systime.year; T_102_s.DayInfo.dfm = systime.day - 7; T_102_e.MinuteInfo.minute = systime.minute; T_102_e.HourInfo.hour = systime.hour; T_102_e.YearInfo.year = systime.year; T_102_e.DayInfo.dfm = systime.day; uint8 T2aLen = sizeof(CP40Time2a); memcpy(buff, (uint8*)&T_102_s, sizeof(CP40Time2a)); buff += sizeof(CP40Time2a); memcpy(buff, (uint8*)&T_102_e, sizeof(CP40Time2a)); buff += sizeof(CP40Time2a); uint8 tempPtr = *(ptr - 1); uint8 tempA = *(ptr + 2); uint8 tempE = *(ptr + 9); uint16 tempBuff = 0; const int TimeLen = 14; tempBuff = 0x53 + 0x01 + 0x78 + 0x01 + 0x06 + 0x01 + 0x9f;// for (int i = 0; i < TimeLen; ++i) { tempBuff += *(ptr + i); } *buff++ = tempBuff & 0x00ff; *buff++ = 0x16; senddata.trailP = buff - senddata.databuf; AppToLink(); PrintLog(LOG_INFORMATION, ">>>>>> 发送请求历史报文命令 "); // if (AppLayerStat == IEC102_APP_STATE_IDLE) //空闲状态下才能刷新LastTxTime! LastTxTime = curtime; return 1; } sint32 CSE102c::TxProc() { App_CheckTime(); if (AppLayerStat == IEC102_APP_STATE_IDLE)//加一个或判断 { ResendCount = 0;//清上次重发的重发次数记忆值 if (App_PipeProc()) { //ofstream outfile; //outfile.open("changetime.txt", ios::app); //outfile << "se104c规约发送 :" << endl; //outfile << "AppLayerStat :" << AppLayerStat << endl; //outfile << "时间点 :" << log_Time() << endl; //outfile << "完成:" << endl << endl; //outfile.close(); return 1; } if (RtuTimeFlag) { //时钟同步处理 SendTimeToSubstation(); RtuTimeFlag = 0; return 1; } if (CallKwhDataFlag) { //电度总召唤处理 if (CallKwhDataFlag == 5) // Call5KwhData();//CallKwhData(QCC_CALLALLKWH | 0x40); else if (CallKwhDataFlag == 7) //读取 Call7KwhData();//CallKwhData(QCC_CALLALLKWH); // CallKwhDataFlag=0; return 1; } //Send U(TESTFR act) format } else App_CheckState(); if (SendACKFlag == 10) //Send S format { //SendHidataToSubstation(); // { // PrintLog(LOG_INFORMATION, "<<<<< 发送S帧 帧号:%d ", ReceiveSeqNo); // return 1; // } } return 1; } int CSE102c::Call5KwhData() { uint8* ptr = senddata.databuf; senddata.headP = senddata.trailP = 0; int curtime = GetNowSecond(); if (curtime - LastTxTime < Timeout3 || curtime - LastRxTime < Timeout3) { return -1; } *ptr++ = 0x10; *ptr++ = 0x5b; *ptr++ = 0x01; *ptr++ = 0x00; *ptr++ = 0x5c; *ptr++ = 0x16; senddata.trailP = ptr - senddata.databuf; AppToLink(); PrintLog(LOG_INFORMATION, ">>>>>> 发送召唤二级数据5b命令 "); CallKwhDataFlag = 7; //if (AppLayerStat == IEC102_APP_STATE_IDLE) //空闲状态下才能刷新LastTxTime! LastTxTime = curtime; return 1; } int CSE102c::Call7KwhData() { uint8* ptr = senddata.databuf; senddata.headP = senddata.trailP = 0; int curtime = GetNowSecond(); if (curtime - LastTxTime < Timeout3 || curtime - LastRxTime < Timeout3) { return -1; } *ptr++ = 0x10; *ptr++ = 0x7b; *ptr++ = 0x01; *ptr++ = 0x00; *ptr++ = 0x7c; *ptr++ = 0x16; senddata.trailP = ptr - senddata.databuf; AppToLink(); PrintLog(LOG_INFORMATION, ">>>>>> 发送召唤二级数据7b命令 "); CallKwhDataFlag = 5; // if (AppLayerStat == IEC102_APP_STATE_IDLE) //空闲状态下才能刷新LastTxTime! LastTxTime = curtime; return 1; } sint32 CSE102c::MsgProc(sint32 msg) { if (msg == DEF_MSG_COMMDOWN) InitStation(); return 1; }