Example #1
0
        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);
        }
Example #2
0
        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;
                        }
                    }
                }
            }
        }