public override void SendDelayAcquisitionCommand(CauseOfTransmission cot, int ca, CP16Time2a delay) { ASDU asdu = new ASDU(appLayerParameters, CauseOfTransmission.ACTIVATION, false, false, (byte)appLayerParameters.OA, ca, false); asdu.AddInformationObject(new DelayAcquisitionCommand(0, delay)); EnqueueUserData(asdu); }
public override void SendControlCommand(CauseOfTransmission cot, int ca, InformationObject sc) { ASDU controlCommand = new ASDU(appLayerParameters, cot, false, false, (byte)appLayerParameters.OA, ca, false); controlCommand.AddInformationObject(sc); EnqueueUserData(controlCommand); }
public override void SendTestCommandWithCP56Time2a(int ca, ushort tsc, CP56Time2a time) { ASDU asdu = new ASDU(appLayerParameters, CauseOfTransmission.ACTIVATION, false, false, (byte)appLayerParameters.OA, ca, false); asdu.AddInformationObject(new TestCommandWithCP56Time2a(tsc, time)); EnqueueUserData(asdu); }
public override void SendResetProcessCommand(CauseOfTransmission cot, int ca, byte qrp) { ASDU asdu = new ASDU(appLayerParameters, CauseOfTransmission.ACTIVATION, false, false, (byte)appLayerParameters.OA, ca, false); asdu.AddInformationObject(new ResetProcessCommand(0, qrp)); EnqueueUserData(asdu); }
public override void SendReadCommand(int ca, int ioa) { ASDU asdu = new ASDU(appLayerParameters, CauseOfTransmission.REQUEST, false, false, (byte)appLayerParameters.OA, ca, false); asdu.AddInformationObject(new ReadCommand(ioa)); EnqueueUserData(asdu); }
public override void SendClockSyncCommand(int ca, CP56Time2a time) { ASDU asdu = new ASDU(appLayerParameters, CauseOfTransmission.ACTIVATION, false, false, (byte)appLayerParameters.OA, ca, false); asdu.AddInformationObject(new ClockSynchronizationCommand(0, time)); EnqueueUserData(asdu); }
private ASDU NewAsdu(InformationObject io) { ASDU asdu = new ASDU(master.GetApplicationLayerParameters(), CauseOfTransmission.FILE_TRANSFER, false, false, 0, ca, false); asdu.AddInformationObject(io); return(asdu); }
public override void SendCounterInterrogationCommand(CauseOfTransmission cot, int ca, byte qcc) { ASDU asdu = new ASDU(appLayerParameters, cot, false, false, (byte)appLayerParameters.OA, ca, false); asdu.AddInformationObject(new CounterInterrogationCommand(0, qcc)); EnqueueUserData(asdu); }
public override void SendTestCommand(int ca) { ASDU asdu = new ASDU(parameters, CauseOfTransmission.ACTIVATION, false, false, (byte)parameters.OA, ca, false); asdu.AddInformationObject(new TestCommand()); EnqueueUserData(asdu); }
public override void SendInterrogationCommand(CauseOfTransmission cot, int ca, byte qoi) { ASDU asdu = new ASDU(parameters, cot, false, false, (byte)parameters.OA, ca, false); asdu.AddInformationObject(new InterrogationCommand(0, qoi)); EnqueueUserData(asdu); }
public bool HandleFileAsdu(ASDU asdu) { bool handled = true; switch (asdu.TypeId) { case TypeID.F_AF_NA_1: /* 124 - ACK file, ACK section */ logger("Received file/section ACK F_AF_NA_1"); if (asdu.Cot == CauseOfTransmission.FILE_TRANSFER) { if (transferState != FileServerState.UNSELECTED_IDLE) { IFileProvider file = selectedFile.provider; FileACK ack = (FileACK)asdu.GetElement(0); if (ack.AckQualifier == AcknowledgeQualifier.POS_ACK_FILE) { logger("Received positive file ACK"); if (transferState == FileServerState.WAITING_FOR_FILE_ACK) { selectedFile.provider.TransferComplete(true); availableFiles.RemoveFile(selectedFile.provider); selectedFile = null; transferState = FileServerState.UNSELECTED_IDLE; } else { logger("Unexpected file transfer state --> abort file transfer"); transferState = FileServerState.SEND_ABORT; } } else if (ack.AckQualifier == AcknowledgeQualifier.NEG_ACK_FILE) { logger("Received negative file ACK - stop transfer"); if (transferState == FileServerState.WAITING_FOR_FILE_ACK) { selectedFile.provider.TransferComplete(false); selectedFile.selectedBy = null; selectedFile = null; transferState = FileServerState.UNSELECTED_IDLE; } else { logger("Unexpected file transfer state --> abort file transfer"); transferState = FileServerState.SEND_ABORT; } } else if (ack.AckQualifier == AcknowledgeQualifier.NEG_ACK_SECTION) { logger("Received negative file section ACK - repeat section"); if (transferState == FileServerState.WAITING_FOR_SECTION_ACK) { currentSectionOffset = 0; sectionChecksum = 0; ASDU sectionReady = new ASDU(alParameters, CauseOfTransmission.FILE_TRANSFER, false, false, 0, file.GetCA(), false); sectionReady.AddInformationObject( new SectionReady(selectedFile.provider.GetIOA(), selectedFile.provider.GetNameOfFile(), currentSectionNumber, currentSectionSize, false)); connection.SendASDU(sectionReady); transferState = FileServerState.TRANSMIT_SECTION; } else { logger("Unexpected file transfer state --> abort file transfer"); transferState = FileServerState.SEND_ABORT; } } else if (ack.AckQualifier == AcknowledgeQualifier.POS_ACK_SECTION) { if (transferState == FileServerState.WAITING_FOR_SECTION_ACK) { currentSectionNumber++; int nextSectionSize = selectedFile.provider.GetSectionSize(currentSectionNumber); ASDU responseAsdu = new ASDU(alParameters, CauseOfTransmission.FILE_TRANSFER, false, false, 0, file.GetCA(), false); if (nextSectionSize == -1) { logger("Reveived positive file section ACK - send last section indication"); responseAsdu.AddInformationObject( new FileLastSegmentOrSection(file.GetIOA(), file.GetNameOfFile(), (byte)currentSectionNumber, LastSectionOrSegmentQualifier.FILE_TRANSFER_WITHOUT_DEACT, fileChecksum)); transferState = FileServerState.WAITING_FOR_FILE_ACK; } else { logger("Reveived positive file section ACK - send next section ready indication"); currentSectionSize = nextSectionSize; responseAsdu.AddInformationObject( new SectionReady(selectedFile.provider.GetIOA(), selectedFile.provider.GetNameOfFile(), currentSectionNumber, currentSectionSize, false)); transferState = FileServerState.WAITING_FOR_SECTION_CALL; } connection.SendASDU(responseAsdu); sectionChecksum = 0; } else { logger("Unexpected file transfer state --> abort file transfer"); transferState = FileServerState.SEND_ABORT; } } } else { // No file transmission in progress --> what to do? logger("Unexpected File ACK message -> ignore"); } } else { asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION; connection.SendASDU(asdu); } break; case TypeID.F_SC_NA_1: /* 122 - Call/Select directoy/file/section */ logger("Received call/select F_SC_NA_1"); if (asdu.Cot == CauseOfTransmission.FILE_TRANSFER) { FileCallOrSelect sc = (FileCallOrSelect)asdu.GetElement(0); if (sc.SCQ == SelectAndCallQualifier.SELECT_FILE) { if (transferState == FileServerState.UNSELECTED_IDLE) { logger("Received SELECT FILE"); CS101n104File file = availableFiles.GetFile(asdu.Ca, sc.ObjectAddress, sc.NOF); if (file == null) { asdu.Cot = CauseOfTransmission.UNKNOWN_INFORMATION_OBJECT_ADDRESS; connection.SendASDU(asdu); } else { ASDU fileReady = new ASDU(alParameters, CauseOfTransmission.FILE_TRANSFER, false, false, 0, asdu.Ca, false); // check if already selected if (file.selectedBy == null) { file.selectedBy = this; fileReady.AddInformationObject(new FileReady(sc.ObjectAddress, sc.NOF, file.provider.GetFileSize(), true)); } else { fileReady.AddInformationObject(new FileReady(sc.ObjectAddress, sc.NOF, 0, false)); } connection.SendASDU(fileReady); selectedFile = file; transferState = FileServerState.WAITING_FOR_FILE_CALL; } } else { logger("Unexpected SELECT FILE message"); } } else if (sc.SCQ == SelectAndCallQualifier.DEACTIVATE_FILE) { logger("Received DEACTIVATE FILE"); if (transferState != FileServerState.UNSELECTED_IDLE) { if (selectedFile != null) { selectedFile.selectedBy = null; selectedFile = null; } transferState = FileServerState.UNSELECTED_IDLE; } else { logger("Unexpected DEACTIVATE FILE message"); } } else if (sc.SCQ == SelectAndCallQualifier.REQUEST_FILE) { logger("Received CALL FILE"); if (transferState == FileServerState.WAITING_FOR_FILE_CALL) { if (selectedFile.provider.GetIOA() != sc.ObjectAddress) { logger("Unkown IOA"); asdu.Cot = CauseOfTransmission.UNKNOWN_INFORMATION_OBJECT_ADDRESS; connection.SendASDU(asdu); } else { ASDU sectionReady = new ASDU(alParameters, CauseOfTransmission.FILE_TRANSFER, false, false, 0, asdu.Ca, false); sectionReady.AddInformationObject(new SectionReady(sc.ObjectAddress, selectedFile.provider.GetNameOfFile(), 0, 0, false)); connection.SendASDU(sectionReady); logger("Send SECTION READY"); currentSectionNumber = 0; currentSectionOffset = 0; currentSectionSize = selectedFile.provider.GetSectionSize(0); transferState = FileServerState.WAITING_FOR_SECTION_CALL; } } else { logger("Unexpected FILE CALL message"); } } else if (sc.SCQ == SelectAndCallQualifier.REQUEST_SECTION) { logger("Received CALL SECTION"); if (transferState == FileServerState.WAITING_FOR_SECTION_CALL) { if (selectedFile.provider.GetIOA() != sc.ObjectAddress) { logger("Unkown IOA"); asdu.Cot = CauseOfTransmission.UNKNOWN_INFORMATION_OBJECT_ADDRESS; connection.SendASDU(asdu); } else { transferState = FileServerState.TRANSMIT_SECTION; } } else { logger("Unexpected SECTION CALL message"); } } } else if (asdu.Cot == CauseOfTransmission.REQUEST) { logger("Call directory received"); availableFiles.SendDirectoy(connection, false); } else { asdu.Cot = CauseOfTransmission.UNKNOWN_CAUSE_OF_TRANSMISSION; connection.SendASDU(asdu); } break; default: handled = false; break; } return(handled); }
internal void SendDirectoy(IMasterConnection masterConnection, bool spontaneous) { CauseOfTransmission cot; if (spontaneous) { cot = CauseOfTransmission.SPONTANEOUS; } else { cot = CauseOfTransmission.REQUEST; } lock (availableFiles) { int size = availableFiles.Count; int i = 0; int currentCa = -1; int currentIOA = -1; ASDU directoryAsdu = null; foreach (CS101n104File file in availableFiles) { bool newAsdu = false; if (file.provider.GetCA() != currentCa) { currentCa = file.provider.GetCA(); newAsdu = true; } if (currentIOA != (file.provider.GetIOA() - 1)) { newAsdu = true; } if (newAsdu) { if (directoryAsdu != null) { masterConnection.SendASDU(directoryAsdu); directoryAsdu = null; } } currentIOA = file.provider.GetIOA(); i++; if (directoryAsdu == null) { directoryAsdu = new ASDU(masterConnection.GetApplicationLayerParameters(), cot, false, false, 0, currentCa, true); } bool lastFile = (i == size); byte sof = 0; if (lastFile) { sof = 0x20; } InformationObject io = new FileDirectory(currentIOA, file.provider.GetNameOfFile(), file.provider.GetFileSize(), sof, new CP56Time2a(file.provider.GetFileDate())); if (!directoryAsdu.AddInformationObject(io) == false) { masterConnection.SendASDU(directoryAsdu); directoryAsdu = new ASDU(masterConnection.GetApplicationLayerParameters(), cot, false, false, 0, currentCa, true); directoryAsdu.AddInformationObject(io); } } if (directoryAsdu != null) { masterConnection.SendASDU(directoryAsdu); } } }
public void HandleFileTransmission() { if (transferState != FileServerState.UNSELECTED_IDLE) { if (transferState == FileServerState.TRANSMIT_SECTION) { if (selectedFile != null) { IFileProvider file = selectedFile.provider; ASDU fileAsdu = new ASDU(alParameters, CauseOfTransmission.FILE_TRANSFER, false, false, 0, file.GetCA(), false); if (currentSectionOffset == currentSectionSize) { // send last segment fileAsdu.AddInformationObject( new FileLastSegmentOrSection(file.GetIOA(), file.GetNameOfFile(), currentSectionNumber, LastSectionOrSegmentQualifier.SECTION_TRANSFER_WITHOUT_DEACT, sectionChecksum)); fileChecksum += sectionChecksum; sectionChecksum = 0; logger("Send LAST SEGMENT"); connection.SendASDU(fileAsdu); transferState = FileServerState.WAITING_FOR_SECTION_ACK; } else { int currentSegmentSize = currentSectionSize - currentSectionOffset; if (currentSegmentSize > maxSegmentSize) { currentSegmentSize = maxSegmentSize; } byte[] segmentData = new byte[currentSegmentSize]; file.GetSegmentData(currentSectionNumber, currentSectionOffset, currentSegmentSize, segmentData); fileAsdu.AddInformationObject( new FileSegment(file.GetIOA(), file.GetNameOfFile(), currentSectionNumber, segmentData)); byte checksum = 0; foreach (byte octet in segmentData) { checksum += octet; } connection.SendASDU(fileAsdu); sectionChecksum += checksum; logger("Send SEGMENT (CHS=" + sectionChecksum + ")"); currentSectionOffset += currentSegmentSize; } } } } }