Example #1
0
        public void RequestFile(int ca, int ioa, NameOfFile nof, IFileReceiver fileReceiver)
        {
            this.ca           = ca;
            this.ioa          = ioa;
            this.nof          = nof;
            this.fileReceiver = fileReceiver;

            ASDU selectFile = NewAsdu(new FileCallOrSelect(ioa, nof, 0, SelectAndCallQualifier.SELECT_FILE));

            master.SendASDU(selectFile);

            state = FileClientState.WAITING_FOR_FILE_READY;
        }
Example #2
0
        public bool HandleFileAsdu(ASDU asdu)
        {
            bool asduHandled = true;

            switch (asdu.TypeId)
            {
            case TypeID.F_SC_NA_1:             /* File/Section/Directory Call/Select */

                DebugLog("Received SELECT/CALL");

                if (state == FileClientState.WAITING_FOR_FILE_READY)
                {
                    if (asdu.Cot == CauseOfTransmission.UNKNOWN_TYPE_ID)
                    {
                        if (fileReceiver != null)
                        {
                            fileReceiver.Finished(FileErrorCode.UNKNOWN_SERVICE);
                        }
                    }
                    else if (asdu.Cot == CauseOfTransmission.UNKNOWN_COMMON_ADDRESS_OF_ASDU)
                    {
                        if (fileReceiver != null)
                        {
                            fileReceiver.Finished(FileErrorCode.UNKNOWN_CA);
                        }
                    }
                    else if (asdu.Cot == CauseOfTransmission.UNKNOWN_INFORMATION_OBJECT_ADDRESS)
                    {
                        if (fileReceiver != null)
                        {
                            fileReceiver.Finished(FileErrorCode.UNKNOWN_IOA);
                        }
                    }
                    else
                    {
                        if (fileReceiver != null)
                        {
                            fileReceiver.Finished(FileErrorCode.PROTOCOL_ERROR);
                        }
                    }
                }
                else
                {
                    if (fileReceiver != null)
                    {
                        fileReceiver.Finished(FileErrorCode.PROTOCOL_ERROR);
                    }
                }

                ResetStateToIdle();

                break;

            case TypeID.F_FR_NA_1:             /* File ready */

                DebugLog("Received FILE READY");

                if (state == FileClientState.WAITING_FOR_FILE_READY)
                {
                    //TODO check ca, ioa, nof

                    FileReady fileReady = (FileReady)asdu.GetElement(0);

                    if (fileReady.Positive)
                    {
                        ASDU callFile = NewAsdu(new FileCallOrSelect(ioa, nof, 0, SelectAndCallQualifier.REQUEST_FILE));
                        master.SendASDU(callFile);

                        DebugLog("Send CALL FILE");

                        state = FileClientState.WAITING_FOR_SECTION_READY;
                    }
                    else
                    {
                        if (fileReceiver != null)
                        {
                            fileReceiver.Finished(FileErrorCode.FILE_NOT_READY);
                        }

                        ResetStateToIdle();
                    }
                }
                else if (state == FileClientState.IDLE)
                {
                    //TODO call user callback to

                    //TODO send positive or negative ACK

                    state = FileClientState.WAITING_FOR_SECTION_READY;
                }
                else
                {
                    AbortFileTransfer(FileErrorCode.PROTOCOL_ERROR);
                }

                break;

            case TypeID.F_SR_NA_1:             /* Section ready */

                DebugLog("Received SECTION READY");

                if (state == FileClientState.WAITING_FOR_SECTION_READY)
                {
                    SectionReady sc = (SectionReady)asdu.GetElement(0);

                    if (sc.NotReady == false)
                    {
                        ASDU callSection = NewAsdu(new FileCallOrSelect(ioa, nof, 0, SelectAndCallQualifier.REQUEST_SECTION));
                        master.SendASDU(callSection);

                        DebugLog("Send CALL SECTION");

                        segmentOffset = 0;
                        state         = FileClientState.RECEIVING_SECTION;
                    }
                    else
                    {
                        AbortFileTransfer(FileErrorCode.SECTION_NOT_READY);
                    }
                }
                else if (state == FileClientState.IDLE)
                {
                }
                else
                {
                    if (fileReceiver != null)
                    {
                        fileReceiver.Finished(FileErrorCode.PROTOCOL_ERROR);
                    }

                    ResetStateToIdle();
                }

                break;

            case TypeID.F_SG_NA_1:             /* Segment */

                DebugLog("Received SEGMENT");

                if (state == FileClientState.RECEIVING_SECTION)
                {
                    FileSegment segment = (FileSegment)asdu.GetElement(0);

                    if (fileReceiver != null)
                    {
                        fileReceiver.SegmentReceived(segment.NameOfSection, segmentOffset, segment.LengthOfSegment, segment.SegmentData);
                    }

                    segmentOffset += segment.LengthOfSegment;
                }
                else if (state == FileClientState.IDLE)
                {
                }
                else
                {
                    AbortFileTransfer(FileErrorCode.PROTOCOL_ERROR);
                }

                break;


            case TypeID.F_LS_NA_1:             /* Last segment or section */

                DebugLog("Received LAST SEGMENT/SECTION");

                if (state != FileClientState.IDLE)
                {
                    FileLastSegmentOrSection lastSection = (FileLastSegmentOrSection)asdu.GetElement(0);

                    if (lastSection.LSQ == LastSectionOrSegmentQualifier.SECTION_TRANSFER_WITHOUT_DEACT)
                    {
                        if (state == FileClientState.RECEIVING_SECTION)
                        {
                            ASDU segmentAck = NewAsdu(new FileACK(ioa, nof, lastSection.NameOfSection, AcknowledgeQualifier.POS_ACK_SECTION, FileError.DEFAULT));

                            master.SendASDU(segmentAck);

                            DebugLog("Send SEGMENT ACK");

                            state = FileClientState.WAITING_FOR_SECTION_READY;
                        }
                        else
                        {
                            AbortFileTransfer(FileErrorCode.PROTOCOL_ERROR);
                        }
                    }
                    else if (lastSection.LSQ == LastSectionOrSegmentQualifier.FILE_TRANSFER_WITH_DEACT)
                    {
                        /* slave aborted transfer */

                        if (fileReceiver != null)
                        {
                            fileReceiver.Finished(FileErrorCode.ABORTED_BY_REMOTE);
                        }

                        ResetStateToIdle();
                    }
                    else if (lastSection.LSQ == LastSectionOrSegmentQualifier.FILE_TRANSFER_WITHOUT_DEACT)
                    {
                        if (state == FileClientState.WAITING_FOR_SECTION_READY)
                        {
                            ASDU fileAck = NewAsdu(new FileACK(ioa, nof, lastSection.NameOfSection, AcknowledgeQualifier.POS_ACK_FILE, FileError.DEFAULT));

                            master.SendASDU(fileAck);

                            DebugLog("Send FILE ACK");

                            if (fileReceiver != null)
                            {
                                fileReceiver.Finished(FileErrorCode.SUCCESS);
                            }

                            ResetStateToIdle();
                        }
                        else
                        {
                            DebugLog("Illegal state: " + state.ToString());

                            AbortFileTransfer(FileErrorCode.PROTOCOL_ERROR);
                        }
                    }
                }

                break;

            default:

                asduHandled = false;
                break;
            }


            return(asduHandled);
        }
Example #3
0
 private void ResetStateToIdle()
 {
     fileReceiver = null;
     state        = FileClientState.IDLE;
 }