163 lines
4.3 KiB
C#
163 lines
4.3 KiB
C#
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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
|
|
{
|
|
/// <summary>
|
|
/// Interface that debug clients must implement to receive packets
|
|
/// from DebugAdapter instances. The DebugAdapter and client
|
|
/// interact synchronously.
|
|
/// </summary>
|
|
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; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method to simulate arrival of a packet.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
}
|