Beispiel #1
0
        /// <summary>
        /// Invoked on behalf of PHY whenever new data has been received.
        /// </summary>
        /// <param name="data">The data that was received.</param>
        void OnDataReceived(byte[] data)
        {
            data.ThrowIfNull("data");
            var frame = Frame.Deserialize(data);

            WriteMac("Received an Ethernet frame.");
            // Compute checksum and compare to the one contained in the frame.
            var fcs = Frame.ComputeCheckSequence(frame);

            if (fcs != frame.CheckSequence)
            {
                WriteMac("Detected a bad frame check sequence, discarding.");
                return;
            }
            // Drop our own frames.
            if (frame.Source == MacAddress)
            {
                return;
            }
            // Examine the frame and see if it's for us; If not, discard it.
            if (frame.Destination != MacAddress &&
                frame.Destination != broadcastAddress)
            {
                WriteMac("Recipient mismatch, discarding.");
                return;
            }
            //Extract the payload and hand it up to the Network layer.
            InterruptReason = Lan.Interrupt.DataReceived;
            Interrupt.RaiseEvent(this,
                                 new DataReceivedEventArgs(frame.Payload, frame.Type));
        }
Beispiel #2
0
 /// <summary>
 /// Invoked om behalf of PHY whenever a frame has been transmitted.
 /// </summary>
 void OnDataTransmitted()
 {
     WriteMac("Finished transmitting Ethernet frame.");
     // The idle period between two consecutive frames must at least be 96
     // bittimes long as per IEEE 802.3 specification.
     emptyingFifo = sendFifo.Count != 0;
     // If the FIFO's not empty yet, issue another transmission. Otherwise
     // let the upper layer know we're ready for more data.
     if (sendFifo.Count > 0)
     {
         Simulation.Callback(interframeGapTime, EmptySendFifo);
     }
     else
     {
         Simulation.Callback(interframeGapTime, () => {
             InterruptReason = Lan.Interrupt.SendFifoEmpty;
             Interrupt.RaiseEvent(this, null);
         });
     }
 }