Esempio n. 1
0
        protected override void DoProtocol()
        {
            Packet[] buffer          = new Packet[_MAX_SEQ + 1]; /* buffers for the outbound stream */
            byte     ackExpected     = 0;                        /* oldest frame as yet unacknowledged */
            byte     nextFrameToSend = 0;                        /* MAX SEQ > 1; used for outbound stream */
            byte     frameExpected   = 0;                        /* next frame expected on inbound stream */
            byte     nbBuffered      = 0;                        /* number of output buffers currently in use */

            // Creates events that trigger the thread changing
            var waitHandles = new WaitHandle[]
            {
                _closingEvents[_actorType], _networkLayerReadyEvents[_actorType], _frameArrivalEvents[_actorType],
                _frameErrorEvents[_actorType], _frameTimeoutEvents[_actorType]
            };

            /* allow network layer ready events */
            EnableNetworkLayer();

            var running = true;

            while (running)
            {
                // Wait trigger events to activate the thread action
                var index = WaitHandle.WaitAny(waitHandles);

                // Execute the task related to the event raised
                switch (index)
                {
                case _STOP_RUNNING:
                    // Received the closing event (_closingEvent)
                    running = false;
                    break;

                case _NETWORK_LAYER_READY:
                    // The network layer has a packet to send (_networkLayerReadyEvent)
                    // In our case, a new packet read from the input file
                    // Accept, save, and transmit a new frame.
                    // Fetch new packet
                    nbBuffered++; /* expand the sender’s window */
                    if (nbBuffered < _MAX_SEQ)
                    {
                        EnableNetworkLayer();
                    }
                    else
                    {
                        DisableNetworkLayer();
                    }

                    buffer[nextFrameToSend] = FromNetworkLayer();
                    SendData(nextFrameToSend, frameExpected, buffer); /* transmit the frame */
                    nextFrameToSend = Inc(nextFrameToSend);           /* advance sender’s upper window edge */
                    break;

                case _FRAME_ARRIVAL:
                    // A data or control frame has arrived (_frameArrivalEvent)
                    // In our case, a new packet to write to the output file or received an ack
                    // get incoming frame from physical layer
                    //var r = FromPhysicalLayer();  /* scratch variable */
                    var a = FromPhysicalLayer(); /* scratch variable */
                    //Decode frame and correct errors using Hamming protocol
                    var r = Hamming.decodeHamming(a);
                    if (r == null)
                    {
                        // _frameErrorEvents[(byte)(1 - _threadId)].Set();
                        break; //reject frame
                    }

                    if (r.Seq == frameExpected)
                    {
                        // Frames are accepted only in order.
                        ToNetworkLayer(r.Info);             /* pass packet to network layer */
                        frameExpected = Inc(frameExpected); /* advance lower edge of receiver’s window */
                    }
                    // Ack n implies n − 1, n − 2, etc.Check for this.
                    while (Between(ackExpected, r.Ack, nextFrameToSend))
                    {
                        // Handle piggybacked ack.
                        nbBuffered--;                   /* one frame fewer buffered */
                        StopTimer(ackExpected);         /* frame arrived intact; stop timer */
                        ackExpected = Inc(ackExpected); /* contract sender’s window */
                    }
                    break;

                case _CKSUM_ERROR:
                    // Just ignore bad frames (_frameErrorEvent)
                    break;

                case _TIMEOUT:
                    // Trouble; retransmit all outstanding frames (_frameTimeoutEvent)
                    nextFrameToSend = ackExpected; /* start retransmitting here */
                    for (byte i = 1; i <= nbBuffered; i++)
                    {
                        SendData(nextFrameToSend, frameExpected, buffer); /* resend frame */
                        nextFrameToSend = Inc(nextFrameToSend);           /* prepare to send the next one */
                    }
                    break;
                }

                if (nbBuffered < _MAX_SEQ)
                {
                    EnableNetworkLayer();
                }
                else
                {
                    DisableNetworkLayer();
                }
            }
            Console.WriteLine(string.Format("**** The Data Link Layer of the {0} thread terminated ****", _actorType));
        }
Esempio n. 2
0
        protected override void DoProtocol()
        {
            byte ackExpected     = 0;                  /* lower edge of sender's window */
            byte nextFrameToSend = 0;                  /* upper edge of sender's window */
            byte frameExpected   = 0;                  /* lower edge of receiver's window */
            byte tooFar          = _NR_BUFS;           /* upper edge of receiver's windows*/

            Packet[] outBuffer = new Packet[_NR_BUFS]; /* buffers for the outbound stream */
            Packet[] inBuffer  = new Packet[_NR_BUFS]; /* buffers for the inboound stream */
            bool[]   arrived   = new bool[_NR_BUFS];
            for (int i = 0; i < _NR_BUFS; i++)
            {
                arrived[i] = false;
            }
            byte nbBuffered = 0; /* number of output buffers currently in use */

            // Creates events that trigger the thread changing
            var waitHandles = new WaitHandle[]
            {
                _closingEvents[_actorType], _networkLayerReadyEvents[_actorType], _frameArrivalEvents[_actorType],
                _frameErrorEvents[_actorType], _frameTimeoutEvents[_actorType], _ackTimeoutEvent
            };

            /* allow network layer ready events */
            EnableNetworkLayer();

            var running = true;

            while (running)
            {
                // Wait trigger events to activate the thread action
                var index = WaitHandle.WaitAny(waitHandles);

                // Execute the task related to the event raised
                switch (index)
                {
                case _STOP_RUNNING:
                    // Received the closing event (_closingEvent)
                    running = false;
                    Console.WriteLine("EVENT STOP RUNNING");
                    break;

                case _NETWORK_LAYER_READY:
                    // The network layer has a packet to send (_networkLayerReadyEvent)
                    // In our case, a new packet read from the input file
                    // Accept, save, and transmit a new frame.
                    // Fetch new packet
                    nbBuffered++; /* expand the window */
                    if (nbBuffered < _NR_BUFS)
                    {
                        EnableNetworkLayer();
                    }
                    else
                    {
                        DisableNetworkLayer();
                    }
                    outBuffer[nextFrameToSend % _NR_BUFS] = FromNetworkLayer();
                    SendData(FrameKind.Data, nextFrameToSend, frameExpected, outBuffer); /* transmit the frame */
                    nextFrameToSend = Inc(nextFrameToSend);                              /* advance  upper window edge */

                    break;

                case _FRAME_ARRIVAL:
                    // A data or control frame has arrived (_frameArrivalEvent)
                    // In our case, a new packet to write to the output file or received an ack
                    // get incoming frame from physical layer
                    var a = FromPhysicalLayer(); /* scratch variable */
                    //Decode frame and correct errors using Hamming protocol
                    var r = Hamming.decodeHamming(a);

                    if (r == null)
                    {
                        // goto case _CKSUM_ERROR;
                        break; //reject frame
                    }
                    if (r.Kind == FrameKind.Data)
                    {
                        if ((r.Seq != frameExpected) && _no_nak)
                        {
                            SendData(FrameKind.Nak, 0, frameExpected, outBuffer);
                        }
                        else
                        {
                            StartAckTimer();
                        }

                        if (Between(frameExpected, r.Seq, tooFar) && (arrived[r.Seq % _NR_BUFS] == false))
                        {
                            arrived[r.Seq % _NR_BUFS]  = true;   //mark buffer as full
                            inBuffer[r.Seq % _NR_BUFS] = r.Info; //insert data

                            while (arrived[frameExpected % _NR_BUFS])
                            {
                                ToNetworkLayer(inBuffer[frameExpected % _NR_BUFS]);
                                _no_nak = true;
                                arrived[frameExpected % _NR_BUFS] = false;
                                frameExpected = Inc(frameExpected);
                                tooFar        = Inc(tooFar);
                                StartAckTimer();
                            }
                        }
                    }

                    if ((r.Kind == FrameKind.Nak) && Between(ackExpected, (byte)((r.Ack + 1) % (_MAX_SEQ + 1)), nextFrameToSend))
                    {
                        SendData(FrameKind.Data, (byte)((r.Ack + 1) % (_MAX_SEQ + 1)), frameExpected, outBuffer);
                    }
                    while (Between(ackExpected, r.Ack, nextFrameToSend))
                    {
                        nbBuffered--;
                        StopTimer(ackExpected % _NR_BUFS); /* frame arrived intact; stop timer */
                        ackExpected   = Inc(ackExpected);  /* contract sender’s window */
                        _oldest_frame = ackExpected;
                    }

                    break;

                case _CKSUM_ERROR:
                    if (_no_nak)
                    {
                        SendData(FrameKind.Nak, 0, frameExpected, outBuffer); //damaged frame
                    }
                    break;

                case _TIMEOUT:
                    SendData(FrameKind.Data, _oldest_frame, frameExpected, outBuffer);

                    break;

                case _ACK_TIMEOUT:
                    SendData(FrameKind.Ack, 0, frameExpected, outBuffer);
                    break;
                }

                if (nbBuffered < _NR_BUFS)
                {
                    EnableNetworkLayer();
                }
                else
                {
                    DisableNetworkLayer();
                }
            }
            Console.WriteLine(string.Format("**** The Data Link Layer of the {0} thread terminated ****", _actorType));
        }