Esempio n. 1
0
        private void TransmitLoop(CancellationToken token)
        {
            while (true)
            {
                byte[] buffer = null;
                if (stream == null)
                {
                    return;
                }
                try
                {
                    buffer = LibC.ReadDataWithTimeout(stream.Handle, MTU, 1000, () => token.IsCancellationRequested);
                }
                catch (ArgumentException)
                {
                    // stream was closed
                    return;
                }
                catch (ObjectDisposedException)
                {
                    return;
                }

                if (token.IsCancellationRequested)
                {
                    return;
                }
                if (buffer == null || buffer.Length == 0)
                {
                    continue;
                }
                var ethernetFrame = EthernetFrame.CreateEthernetFrameWithCRC(buffer);
                FrameReady?.Invoke(ethernetFrame);
            }
        }
Esempio n. 2
0
        private async Task ReadPacketAsync()
        {
            var buffer = new byte[Mtu];

            while (!cts.IsCancellationRequested)
            {
                try
                {
                    if (await deviceFile.ReadAsync(buffer, 0, buffer.Length, cts.Token) > 0)
                    {
                        var frame = EthernetFrame.CreateEthernetFrameWithCRC(buffer);
                        Link.TransmitFrameFromInterface(frame);
                        this.NoisyLog("Frame of length {0} received from host.", frame.Bytes.Length);
                    }
                }
                catch (IOException)
                {
                    if (networkInterface.OperationalStatus != OperationalStatus.Up)
                    {
                        this.NoisyLog("I/O exception while interface is not up, waiting {0}s.", Misc.NormalizeDecimal(GracePeriod.TotalSeconds));
                        // probably the interface is not opened yet
                        await Task.Delay(GracePeriod);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
        private void transmitFrame()
        {
            var td = new transmitDescriptor(machine.SystemBus);

            td.Fetch(transmitDescriptorBase | transmitDescriptorOffset);

            if (!td.Enable)
            {
                return; //if decriptor is disabled there is nothing to send (just return)
            }

            var packetBytes = machine.SystemBus.ReadBytes((long)td.PacketAddress, (int)td.Length);
            var packet      = EthernetFrame.CreateEthernetFrameWithCRC(packetBytes);

            if (Link.IsConnected)
            {
                this.Log(LogLevel.Info, "Sending packet length {0}", packet.Bytes.Length);
                this.Log(LogLevel.Info, "Packet address = 0x{0:X}", td.PacketAddress);
                Link.TransmitFrameFromInterface(packet);
            }

            registers.Status |= 1u << 3;

            if (td.Wrap)
            {
                transmitDescriptorOffset = 0;
            }
            else
            {
                if (transmitDescriptorOffset != 0x3f8)
                {
                    transmitDescriptorOffset += 8;
                }
                else
                {
                    transmitDescriptorOffset = 0;
                }
            }

            if (td.InterruptEnable && ((registers.Control & (1u << 2)) != 0))
            {
                //if interrupts enabled
                registers.Status |= 1u << 3; //transmitter interrupt bit
                this.IRQ.Set();
                this.IRQ.Unset();
            }

            td.Enable            = false;
            td.Wrap              = false;
            td.InterruptEnable   = false;
            td.Length            = 0;
            td.UnderrunError     = false;
            td.AttemptLimitError = false;
            td.WriteBack();
        }
Esempio n. 4
0
        private void TransmitPacket()
        {
            var packetSize = transmitBufferEnd - transmitBufferStart; // -1 for the per packet control byte, but transmitBufferEnd points to the last byte of the packet
            var data       = new byte[packetSize];

            Array.Copy(ethernetBuffer, transmitBufferStart + 1, data, 0, packetSize);
            var frame = EthernetFrame.CreateEthernetFrameWithCRC(data);

            // status vector is not implemented yet
            this.Log(LogLevel.Debug, "Sending frame {0}.", frame);
            Link.TransmitFrameFromInterface(frame);
            transmitPacketInterrupt.Value = true;
            RefreshInterruptStatus();
        }
Esempio n. 5
0
        public void WriteDataBulk(USBPacket packet)
        {
            if (packet.data == null)
            {
                return;
            }

            byte[] packetToSend;
            if (packet.data[5] != 64)
            {
                packetToSend = new byte[packet.data.Length - 8];
                Array.Copy(packet.data, 8, packetToSend, 0, packetToSend.Length);
            }
            else
            {
                packetToSend = new byte[packet.data.Length - 12];
                Array.Copy(packet.data, 12, packetToSend, 0, packetToSend.Length);

                if ((packetToSend[14] & 0xF0) == 0x40) //IP packet
                {
                    ushort cksum;
                    IPHeaderLength = (ushort)((packetToSend[14] & 0x0F) * 4);
                    if (packetToSend[23] == 0x06) // TCP packet
                    {
                        IPpacket tcpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.TCP);
                        tcpPacket.ReadFromBuffer(packetToSend);
                        cksum  = tcpPacket.GetChecksum();
                        cksum -= 1;
                        packetToSend[MACHeaderLegth + IPHeaderLength + 16] = (byte)((cksum >> 8) & 0xFF);
                        packetToSend[MACHeaderLegth + IPHeaderLength + 17] = (byte)((cksum) & 0xFF);
                    }
                    else if (packetToSend[23] == 0x11) // UDP packet
                    {
                        IPpacket udpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.UDP);
                        udpPacket.ReadFromBuffer(packetToSend);
                        cksum  = udpPacket.GetChecksum();
                        cksum -= 1;
                        packetToSend[MACHeaderLegth + IPHeaderLength + 6] = (byte)((cksum >> 8) & 0xFF);
                        packetToSend[MACHeaderLegth + IPHeaderLength + 7] = (byte)((cksum) & 0xFF);
                    }
                }
            }

            var frame = EthernetFrame.CreateEthernetFrameWithCRC(packetToSend);

            FrameReady?.Invoke(frame);
        }
Esempio n. 6
0
        public byte Transmit()
        {
            lock (lockObj)
            {
                int  len;
                byte whichPacket;

                if ((transmitControl & TransmitEnabled) == 0)
                {
                    return(0);
                }
                if (txFifo.Count == 0)
                {
                    return(0);
                }
                while (txFifo.Count > 0)
                {
                    whichPacket = txFifo.Dequeue();
                    var currentBuffer = memoryBuffer[whichPacket];
                    len  = currentBuffer.Data[2];
                    len |= currentBuffer.Data[3] << 8;
                    len -= 6;

                    byte [] indata = new byte[len];

                    for (int j = 0; j < len; j++)
                    {
                        indata[j] = currentBuffer.Data[j + 4];
                    }

                    if ((control & ControlAutorelease) != 0)
                    {
                        currentBuffer.IsAllocated = false;
                    }
                    else
                    {
                        sentFifo.Enqueue((byte)whichPacket);
                    }
                    var frame = EthernetFrame.CreateEthernetFrameWithCRC(indata);
                    Link.TransmitFrameFromInterface(frame);
                }
                Update();
                return(0);
            }
        }
        private void SendFrames()
        {
            this.Log(LogLevel.Noisy, "Sending frame");
            var transmitDescriptor = new TxDescriptor(machine.SystemBus);
            var packetData         = new List <byte>();

            transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            while (!transmitDescriptor.IsUsed)
            {
                transmitDescriptor.IsUsed = true;
                this.Log(LogLevel.Noisy, "GOING TO READ FROM {0:X}, len={1}", transmitDescriptor.Address1, transmitDescriptor.Buffer1Length);
                packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address1, transmitDescriptor.Buffer1Length));
                if (!transmitDescriptor.IsNextDescriptorChained)
                {
                    packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address2, transmitDescriptor.Buffer2Length));
                }

                transmitDescriptor.WriteBack();

                if (transmitDescriptor.IsEndOfRing)
                {
                    dmaTransmitDescriptorListAddress = dmaTransmitDescriptorListAddressBegin;
                }
                else if (transmitDescriptor.IsNextDescriptorChained)
                {
                    dmaTransmitDescriptorListAddress = transmitDescriptor.Address2;
                }
                else
                {
                    dmaTransmitDescriptorListAddress += 8;
                }
                if (transmitDescriptor.IsLast)
                {
                    this.Log(LogLevel.Noisy, "Sending frame of {0} bytes.", packetData.Count);
                    if (Link.IsConnected)
                    {
                        var frame = EthernetFrame.CreateEthernetFrameWithoutCRC(packetData.ToArray());

                        if (transmitDescriptor.ChecksumInstertionControl > 0)
                        {
                            this.Log(LogLevel.Noisy, "Calculating checksum (mode {0}).", transmitDescriptor.ChecksumInstertionControl);
                            if (transmitDescriptor.ChecksumInstertionControl == 1)
                            {
                                //IP only
                                frame.FillWithChecksums(supportedEtherChecksums, null);
                            }
                            else
                            {
                                //IP and payload
                                frame.FillWithChecksums(supportedEtherChecksums, supportedIPChecksums);
                            }
                        }
                        this.Log(LogLevel.Debug, Misc.DumpPacket(frame, true, machine));

                        packetSent = true;
                        //We recreate the EthernetFrame because the CRC should be appended after creating inner checksums.
                        var frameWithCrc = EthernetFrame.CreateEthernetFrameWithCRC(frame.Bytes);
                        Link.TransmitFrameFromInterface(frameWithCrc);
                    }
                }
                transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            }

            //set TransmitBufferUnavailable
            dmaStatus |= TransmitBufferUnavailableStatus;
            if ((dmaInterruptEnable & (StartStopTransmission)) == 0)
            {
                IRQ.Set();
            }
            this.Log(LogLevel.Noisy, "Frame sent.");
        }
Esempio n. 8
0
        private void SendFrames()
        {
            lock (sync)
            {
                txBufferDescriptor txBD = new txBufferDescriptor(machine.SystemBus);
                bool        interrupt   = false;
                List <byte> packet      = new List <byte>();


                txBD.Fetch(registers.TxQueueBaseAddr);

                while (!txBD.Used)
                {
                    while (!txBD.Last)
                    {
                        packet.AddRange(machine.SystemBus.ReadBytes(txBD.Word0, txBD.Length));
                        txBD.Used = true;
                        txBD.WriteBack();
                        if (txBD.Wrap)
                        {
                            registers.TxQueueBaseAddr = txBufferBase;
                        }
                        else
                        {
                            registers.TxQueueBaseAddr += 8;
                        }
                        txBD.Fetch(registers.TxQueueBaseAddr);
                    }
                    interrupt = false;
                    txBD.Used = true;

                    packet.AddRange(machine.SystemBus.ReadBytes(txBD.Word0, txBD.Length));

                    if ((registers.DMAConfig & 1u << 11) != 0) //if checksum offload enable
                    {
                        if ((packet[14] & 0xF0) == 0x40)       //IP packet
                        {
                            ushort cksum;
                            IPHeaderLength = (ushort)((packet[14] & 0x0F) * 4);
                            if (packet[23] == 0x06) // TCP packet
                            {
                                IPpacket tcpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.TCP);
                                tcpPacket.ReadFromBuffer(packet.ToArray());
                                cksum  = tcpPacket.GetChecksum();
                                cksum -= 1;
                                packet[MACHeaderLegth + IPHeaderLength + 16] = (byte)((cksum >> 8) & 0xFF);
                                packet[MACHeaderLegth + IPHeaderLength + 17] = (byte)((cksum) & 0xFF);
                            }
                            else if (packet[23] == 0x11) // UDP packet
                            {
                                IPpacket udpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.UDP);
                                udpPacket.ReadFromBuffer(packet.ToArray());
                                cksum  = udpPacket.GetChecksum();
                                cksum -= 1;
                                packet[MACHeaderLegth + IPHeaderLength + 6] = (byte)((cksum >> 8) & 0xFF);
                                packet[MACHeaderLegth + IPHeaderLength + 7] = (byte)((cksum) & 0xFF);
                            }
                        }
                    }

                    if (Link.IsConnected)
                    {
                        EthernetFrame frame;

                        if (!txBD.NoCRC)
                        {
                            frame = EthernetFrame.CreateEthernetFrameWithCRC(packet.ToArray());
                        }
                        else
                        {
                            frame = EthernetFrame.CreateEthernetFrameWithoutCRC(packet.ToArray());
                        }

                        this.Log(LogLevel.Noisy, "Sending packet length {0}", packet.ToArray().Length);
                        Link.TransmitFrameFromInterface(frame);
                    }

                    txBD.WriteBack();

                    if (txBD.Wrap)
                    {
                        registers.TxQueueBaseAddr = txBufferBase;
                    }
                    else
                    {
                        registers.TxQueueBaseAddr += 8;
                    }

                    registers.TxStatus |= 1u << 5; //tx complete
                    txBD.Fetch(registers.TxQueueBaseAddr);

                    if (txBD.Used)
                    {
                        registers.TxStatus |= 0x01;
                        if ((registers.InterruptMask & (1u << 3)) == 0)
                        {
                            registers.InterruptStatus |= 1u << 3;
                            interrupt = true;
                        }
                    }

                    if ((registers.InterruptMask & (1u << 7)) == 0)
                    {
                        registers.InterruptStatus |= 1u << 7;
                        interrupt = true;
                    }

                    if (interrupt)
                    {
                        IRQ.Set();
                    }
                }
            }
        }