/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity / Netstack // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: LoopbackAdapter.cs // using NetStack.Common; using System; using System.Collections; using System.Threading; using Drivers.Net; using Microsoft.Contracts; namespace NetStack.NetDrivers { /// /// Interface that debug clients must implement to receive packets /// from DebugAdapter instances. The DebugAdapter and client /// interact synchronously. /// public interface IDebugAdapterClient { void RegisterAdapter(DebugAdapter adapter); void Receive(NetPacket packet); } public class DebugAdapter : IAdapter { private const int RingSize = 64; private IDebugAdapterClient! client; private EthernetAddress address; private AutoResetEvent! writeEvent; private AutoResetEvent! readEvent; private ArrayList! rxBuffer; private ArrayList! txBuffer; static int instantiations = 0; [NotDelayed] public DebugAdapter(IDebugAdapterClient! debugClient) { instantiations++; // // Microsoft OUI 00:50:f2:xx:xx:xx // It doesn't really matter, but something other // than zero is preferable for testing purposes. // int x = 0x222111 ^ instantiations; address = new EthernetAddress(0x00, 0x50, 0xf2, (byte)(x >> 16), (byte)(x >> 8), (byte)(x & 0xff)); writeEvent = new AutoResetEvent(false); readEvent = new AutoResetEvent(false); txBuffer = new ArrayList(); rxBuffer = new ArrayList(); this.client = debugClient; base(); debugClient.RegisterAdapter(this); } public string DriverName { get { return "Debug Adapter"; } } public string DriverVersion { get { return "0.1"; } } public EthernetAddress HardwareAddress { get { return address; } } public uint LinkSpeed { get { return 10 * 1000 * 1000; } } public int TxSlotsFree { get { return RingSize - rxBuffer.Count; } } /// /// Method to simulate arrival of a packet. /// public bool ReceivePacket(NetPacket packet) { Console.WriteLine("GetReceivePacket"); if (rxBuffer.Count < RingSize) { rxBuffer.Add(packet); readEvent.Set(); return true; } return false; } public void GetReceivedPackets(Queue! outQueue) { Console.WriteLine("GetReceivedPackets"); for (int i = 0; i < rxBuffer.Count; i++) { outQueue.Enqueue(rxBuffer[i]); } rxBuffer.Clear(); readEvent.Reset(); } public uint GetTransmittedPackets() { uint count = (uint)txBuffer.Count; txBuffer.Clear(); writeEvent.Reset(); return count; } public void PopulateRxRing(uint count) { // Do nothing } public void PopulateTxRing(NetPacket[]! packets, uint packetCount) { for (uint i = 0; i < packetCount; i++) { NetPacket! packet = (!)packets[i]; // Add an equivalently sized packet back to recycle list txBuffer.Add(new NetPacket(packet.Length)); // Give packet to client client.Receive(packet); } writeEvent.Set(); } public WaitHandle GetReadHandle() { return readEvent; } public WaitHandle GetWriteHandle() { return writeEvent; } } }