void Slave::SendUnsolicited(APDU& arAPDU)
{
	mRspIIN.BitwiseOR(mIIN);
	arAPDU.SetIIN(mRspIIN);
	mpAppLayer->SendUnsolicited(arAPDU);
	mUnsolExpectCON = (arAPDU.GetControl()).CON;
}
Example #2
0
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);
	}
}
Example #3
0
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()));
}
Example #4
0
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));	
}
Example #5
0
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));	
}
Example #6
0
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);
}
Example #7
0
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);
}
Example #8
0
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;
		}
	}
}