void Slave::HandleEnableUnsolicited(const APDU& arRequest, bool aIsEnable) { mResponse.Set(FC_RESPONSE); if (mConfig.mDisableUnsol) { mRspIIN.SetFuncNotSupported(true); } else { if (aIsEnable) { this->mDeferredUnsol = true; } for (HeaderReadIterator hdr = arRequest.BeginRead(); !hdr.IsEnd(); ++hdr) { switch (MACRO_DNP_RADIX(hdr->GetGroup(), hdr->GetVariation())) { case (MACRO_DNP_RADIX(60, 2)): mConfig.mUnsolMask.class1 = aIsEnable; break; case (MACRO_DNP_RADIX(60, 3)): mConfig.mUnsolMask.class2 = aIsEnable; break; case (MACRO_DNP_RADIX(60, 4)): mConfig.mUnsolMask.class3 = aIsEnable; break; default: mRspIIN.SetFuncNotSupported(true); LOG_BLOCK(LEV_WARNING, "Cannot enable/disable unsol for " << hdr->GetBaseObject()->Name()); break; } } } }
void DataPoll::ReadData(const APDU& f) { ResponseLoader loader(mpLogger, mpObs, mpVtoReader); HeaderReadIterator hdr = f.BeginRead(); for ( ; !hdr.IsEnd(); ++hdr) { loader.Process(hdr); } }
TaskResult SimpleRspBase::_OnFinalResponse(const APDU& arAPDU) { if(arAPDU.BeginRead().Count() > 0) { LOG_BLOCK(LEV_WARNING, "Unexpected object headers in response: " << this->Name()); } return TR_SUCCESS; }
void Master::ProcessDataResponse(const APDU& arResponse) { try { ResponseLoader loader(this->mpLogger, this->mpPublisher, this->GetVtoReader()); for(HeaderReadIterator hdr = arResponse.BeginRead(); !hdr.IsEnd(); ++hdr) loader.Process(hdr); } catch(Exception ex) { EXCEPTION_BLOCK(LEV_WARNING, ex) } }
void Slave::HandleVtoTransfer(const APDU& arRequest) { for(HeaderReadIterator hdr = arRequest.BeginRead(); !hdr.IsEnd(); ++hdr) { switch(hdr->GetGroup()) { case 112: this->HandleWriteVto(hdr); break; default: mRspIIN.SetFuncNotSupported(true); ERROR_BLOCK(LEV_WARNING, "Object/Function mismatch", SERR_OBJ_FUNC_MISMATCH); break; } } }
void ResponseLoaderTestObject::Load(const std::string& arAPDU) { fdo.Clear(); HexSequence hs(arAPDU); APDU f; f.Write(hs, hs.Size()); f.Interpret(); ResponseLoader rl(mpLogger, &fdo); for(HeaderReadIterator hdr = f.BeginRead(); !hdr.IsEnd(); ++hdr) { rl.Process(hdr); } }
void Slave::ConfigureDelayMeasurement(const APDU& arRequest) { HeaderReadIterator hdr = arRequest.BeginRead(); if (hdr.Count() > 0) { mRspIIN.SetFuncNotSupported(true); } Group52Var2* pObj = Group52Var2::Inst(); mResponse.Set(FC_RESPONSE); IndexedWriteIterator i = mResponse.WriteIndexed(pObj, 1, QC_1B_CNT); i.SetIndex(0); pObj->mTime.Set(*i, 0); }
void Slave::HandleOperate(const APDU& arRequest, SequenceInfo aSeqInfo) { if (aSeqInfo == SI_PREV && mLastRequest == arRequest) { return; } mResponse.Set(FC_RESPONSE); for (HeaderReadIterator hdr = arRequest.BeginRead(); !hdr.IsEnd(); ++hdr) { ObjectReadIterator i = hdr.BeginRead(); switch (MACRO_DNP_RADIX(hdr->GetGroup(), hdr->GetVariation())) { case (MACRO_DNP_RADIX(12, 1)): this->RespondToCommands<BinaryOutput>(Group12Var1::Inst(), i, boost::bind(&Slave::Operate<BinaryOutput>, this, _1, _2, false, hdr.info(), aSeqInfo, arRequest.GetControl().SEQ)); break; case (MACRO_DNP_RADIX(41, 1)): this->RespondToCommands<Setpoint>(Group41Var1::Inst(), i, boost::bind(&Slave::Operate<Setpoint>, this, _1, _2, false, hdr.info(), aSeqInfo, arRequest.GetControl().SEQ)); break; case (MACRO_DNP_RADIX(41, 2)): this->RespondToCommands<Setpoint>(Group41Var2::Inst(), i, boost::bind(&Slave::Operate<Setpoint>, this, _1, _2, false, hdr.info(), aSeqInfo, arRequest.GetControl().SEQ)); break; case (MACRO_DNP_RADIX(41, 3)): this->RespondToCommands<Setpoint>(Group41Var3::Inst(), i, boost::bind(&Slave::Operate<Setpoint>, this, _1, _2, false, hdr.info(), aSeqInfo, arRequest.GetControl().SEQ)); break; case (MACRO_DNP_RADIX(41, 4)): this->RespondToCommands<Setpoint>(Group41Var4::Inst(), i, boost::bind(&Slave::Operate<Setpoint>, this, _1, _2, false, hdr.info(), aSeqInfo, arRequest.GetControl().SEQ)); break; default: mRspIIN.SetFuncNotSupported(true); ERROR_BLOCK(LEV_WARNING, "Object/Function mismatch", SERR_OBJ_FUNC_MISMATCH); break; } } }
void Slave::HandleWrite(const APDU& arRequest) { for (HeaderReadIterator hdr = arRequest.BeginRead(); !hdr.IsEnd(); ++hdr) { switch (hdr->GetGroup()) { case 112: this->HandleWriteVto(hdr); continue; } switch (MACRO_DNP_RADIX(hdr->GetGroup(), hdr->GetVariation())) { case (MACRO_DNP_RADIX(80, 1)): this->HandleWriteIIN(hdr); break; case (MACRO_DNP_RADIX(50, 1)): this->HandleWriteTimeDate(hdr); break; default: mRspIIN.SetFuncNotSupported(true); ERROR_BLOCK(LEV_WARNING, "Object/Function mismatch", SERR_OBJ_FUNC_MISMATCH); break; } } }
TaskResult TimeSync::_OnFinalResponse(const APDU& arAPDU) { if(mDelay < 0) { ptime now = mpTimeSrc->GetUTC(); HeaderReadIterator hri = arAPDU.BeginRead(); if(hri.Count() != 1) { LOG_BLOCK(LEV_WARNING, "DelayMeas response w/ unexcpected header count"); return TR_FAIL; } if(!hri->GetBaseObject()->Equals(Group52Var2::Inst())) { LOG_BLOCK(LEV_WARNING, "DelayMeas response w/ unexpected object: " << hri->GetBaseObject()->Name()); return TR_FAIL; } ObjectReadIterator ori = hri.BeginRead(); if(ori.Count() != 1) { LOG_BLOCK(LEV_WARNING, "DelayMeas got more than 1 object in response"); return TR_FAIL; } millis_t send_rcv_time = (now - mStart).total_milliseconds(); millis_t rtu_turn_around = Group52Var2::Inst()->mTime.Get(*ori); // The later shouldn't happen, but could cause a negative delay which would // result in a weird time setting mDelay = (send_rcv_time >= rtu_turn_around) ? (send_rcv_time - rtu_turn_around)/2 : 0; return TR_CONTINUE; } else { return TR_SUCCESS; } }