Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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;
                        }
                    }
                }
            }
        }