public override void HandleMessage(FunctionCodePrimary fcp, bool isBroadcast, int address, bool fcb, bool fcv, byte[] msg, int userDataStart, int userDataLength) { // check frame count bit if fcv == true if (fcv) { if (CheckFCB(fcb) == false) { return; } } switch (fcp) { case FunctionCodePrimary.REQUEST_LINK_STATUS: DebugLog("SLL - REQUEST LINK STATUS"); { bool accessDemand = applicationLayer.IsClass1DataAvailable(); linkLayer.SendFixedFrameSecondary(FunctionCodeSecondary.STATUS_OF_LINK_OR_ACCESS_DEMAND, linkLayerAddress, accessDemand, false); } break; case FunctionCodePrimary.RESET_REMOTE_LINK: DebugLog("SLL - RESET REMOTE LINK"); { expectedFcb = true; if (linkLayer.linkLayerParameters.UseSingleCharACK) { linkLayer.SendSingleCharACK(); } else { linkLayer.SendFixedFrameSecondary(FunctionCodeSecondary.ACK, linkLayerAddress, false, false); } applicationLayer.ResetCUReceived(false); } break; case FunctionCodePrimary.RESET_FCB: DebugLog("SLL - RESET FCB"); { expectedFcb = true; if (linkLayer.linkLayerParameters.UseSingleCharACK) { linkLayer.SendSingleCharACK(); } else { linkLayer.SendFixedFrameSecondary(FunctionCodeSecondary.ACK, linkLayerAddress, false, false); } applicationLayer.ResetCUReceived(true); } break; case FunctionCodePrimary.REQUEST_USER_DATA_CLASS_2: DebugLog("SLL - REQUEST USER DATA CLASS 2"); { BufferFrame asdu = applicationLayer.GetCLass2Data(); bool accessDemand = applicationLayer.IsClass1DataAvailable(); if (asdu != null) { linkLayer.SendVariableLengthFrameSecondary(FunctionCodeSecondary.RESP_USER_DATA, linkLayerAddress, accessDemand, false, asdu); } else { if (linkLayer.linkLayerParameters.UseSingleCharACK && (accessDemand == false)) { linkLayer.SendSingleCharACK(); } else { linkLayer.SendFixedFrameSecondary(FunctionCodeSecondary.RESP_NACK_NO_DATA, linkLayerAddress, accessDemand, false); } } } break; case FunctionCodePrimary.REQUEST_USER_DATA_CLASS_1: DebugLog("SLL - REQUEST USER DATA CLASS 1"); { BufferFrame asdu = applicationLayer.GetClass1Data(); bool accessDemand = applicationLayer.IsClass1DataAvailable(); if (asdu != null) { linkLayer.SendVariableLengthFrameSecondary(FunctionCodeSecondary.RESP_USER_DATA, linkLayerAddress, accessDemand, false, asdu); } else { if (linkLayer.linkLayerParameters.UseSingleCharACK && (accessDemand == false)) { linkLayer.SendSingleCharACK(); } else { linkLayer.SendFixedFrameSecondary(FunctionCodeSecondary.RESP_NACK_NO_DATA, linkLayerAddress, accessDemand, false); } } } break; case FunctionCodePrimary.USER_DATA_CONFIRMED: DebugLog("SLL - USER DATA CONFIRMED"); if (userDataLength > 0) { if (applicationLayer.HandleReceivedData(msg, isBroadcast, userDataStart, userDataLength)) { bool accessDemand = applicationLayer.IsClass1DataAvailable(); linkLayer.SendFixedFrameSecondary(FunctionCodeSecondary.ACK, linkLayerAddress, accessDemand, false); } } break; case FunctionCodePrimary.USER_DATA_NO_REPLY: DebugLog("SLL - USER DATA NO REPLY"); if (userDataLength > 0) { applicationLayer.HandleReceivedData(msg, isBroadcast, userDataStart, userDataLength); } break; default: DebugLog("SLL - UNEXPECTED LINK LAYER MESSAGE"); linkLayer.SendFixedFrameSecondary(FunctionCodeSecondary.LINK_SERVICE_NOT_IMPLEMENTED, linkLayerAddress, false, false); break; } }
private void SendStatusOfLink(int address) { linkLayer.SendFixedFrameSecondary(FunctionCodeSecondary.STATUS_OF_LINK_OR_ACCESS_DEMAND, address, false, false); }