void Slave::SendUnsolicited(APDU& arAPDU) { mRspIIN.BitwiseOR(mIIN); arAPDU.SetIIN(mRspIIN); mpAppLayer->SendUnsolicited(arAPDU); mUnsolExpectCON = (arAPDU.GetControl()).CON; }
void ACS_Base::ProcessResponse(AppLayerChannel* c, APDU& arAPDU, bool aExpectFIR) { AppControlField acf = arAPDU.GetControl(); if(acf.SEQ == c->Sequence()) { if(acf.FIR == aExpectFIR) { c->CancelTimer(); if(acf.FIN) { c->ChangeState(ACS_Idle::Inst()); c->DoFinalResponse(arAPDU); } else { c->IncrSequence(); c->ChangeState(ACS_WaitForFinalResponse::Inst()); c->StartTimer(); c->DoPartialResponse(arAPDU); } } else { ERROR_LOGGER_BLOCK(c->GetLogger(), LEV_WARNING, "Unexpected fir bit " << acf.FIR, ALERR_BAD_FIR_FIN); } } else { ERROR_LOGGER_BLOCK(c->GetLogger(), LEV_WARNING, "Bad sequence number " << acf.SEQ, ALERR_BAD_SEQUENCE); } }
void AppLayer::SendRequest(APDU& arAPDU) { this->Validate(arAPDU.GetControl(), true, true, false, false); if(!IsRequest(arAPDU.GetFunction())) throw ArgumentException(LOCATION, "Non-request function code"); mSolicited.Send(arAPDU, this->GetRetries(arAPDU.GetFunction())); }
void AppLayer::SendUnsolicited(APDU& arAPDU) { this->Validate(arAPDU.GetControl(), false, true, true, true); if(arAPDU.GetFunction() != FC_UNSOLICITED_RESPONSE ) throw ArgumentException(LOCATION, "Non-unsolicited function code"); mUnsolicited.Send(arAPDU, this->GetRetries(FC_UNSOLICITED_RESPONSE)); }
void AppLayer::SendResponse(APDU& arAPDU) { this->Validate(arAPDU.GetControl(), false, false, true, false); if(arAPDU.GetFunction() != FC_RESPONSE) throw ArgumentException(LOCATION, "Non-response function code"); mSolicited.Send(arAPDU, this->GetRetries(FC_RESPONSE)); }
void ACS_Idle::Send(AppLayerChannel* c, APDU& arAPDU, size_t aNumRetry) { AppControlField acf = arAPDU.GetControl(); FunctionCodes func = arAPDU.GetFunction(); acf.SEQ = (acf.FIR && func == FC_RESPONSE) ? c->Sequence() : c->IncrSequence(); arAPDU.SetControl(acf); c->ChangeState(NextState(c, arAPDU.GetFunction(), acf.CON)); c->SetRetry(aNumRetry); c->QueueSend(arAPDU); }
void SolicitedChannel::OnRequest(APDU& arAPDU) { AppControlField acf = arAPDU.GetControl(); SequenceInfo seq = SI_OTHER; if (acf.SEQ == this->Sequence()) { LOG_BLOCK(LEV_WARNING, "Received previous sequence"); seq = SI_PREV; } else if (acf.SEQ == NextSeq(this->Sequence())) { seq = SI_CORRECT; } mSequence = acf.SEQ; mpAppLayer->mpUser->OnRequest(arAPDU, seq); }
void ACS_Base::OnResponse(AppLayerChannel* c, APDU& arAPDU) { LOGGER_BLOCK(c->GetLogger(), LEV_WARNING, "Unexpected response with sequence: " << arAPDU.GetControl().SEQ); }
void Slave::HandleDirectOperate(const APDU& arRequest, SequenceInfo aSeqInfo) { 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, true, 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, true, 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, true, 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, true, 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, true, hdr.info(), aSeqInfo, arRequest.GetControl().SEQ)); break; default: mRspIIN.SetFuncNotSupported(true); ERROR_BLOCK(LEV_WARNING, "Object/Function mismatch", SERR_OBJ_FUNC_MISMATCH); break; } } }