remove unused files, remove notion of PHY, make more realistic p2p-net-device and p2p-channel

This commit is contained in:
Craig Dowell
2007-03-27 13:04:11 -07:00
parent 1a65d66361
commit 994c7be384
16 changed files with 308 additions and 505 deletions

View File

@@ -282,8 +282,6 @@ p2p.add_sources ([
'p2p-net-device.cc',
'p2p-channel.cc',
'p2p-topology.cc',
'p2p-phy.cc',
'layer-connector.cc',
])
p2p.add_headers ([
'propagator.h',
@@ -292,8 +290,6 @@ p2p.add_inst_headers ([
'p2p-net-device.h',
'p2p-channel.h',
'p2p-topology.h',
'p2p-phy.h',
'layer-connector.h',
])

View File

@@ -207,7 +207,6 @@ int main (int argc, char *argv[])
DebugComponentEnable("Channel");
DebugComponentEnable("PointToPointChannel");
DebugComponentEnable("PointToPointNetDevice");
DebugComponentEnable("PointToPointPhy");
#endif
ObjectContainer container;

View File

@@ -1,138 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 University of Washington
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Craig Dowell <craigdo@ee.washingon.edu>
*
* Fri Feb 16 12:18:11 PST 2007 craigdo: created
*/
#include "ns3/debug.h"
#include "ns3/assert.h"
#include "layer-connector.h"
NS_DEBUG_COMPONENT_DEFINE ("LayerConnector");
namespace ns3 {
LayerConnectorUpper::LayerConnectorUpper ()
{
NS_DEBUG("LayerConnectorUpper::LayerConnectorUpper ()");
}
LayerConnectorUpper::~LayerConnectorUpper ()
{
NS_DEBUG("LayerConnectorUpper::~LayerConnectorUpper ()");
}
bool
LayerConnectorUpper::ConnectToLower (LayerConnectorLower &partner)
{
NS_DEBUG("LayerConnectorUpper::ConnectToLower (" << &partner << ")");
return DoConnectToLower(partner);
}
bool
LayerConnectorUpper::DoConnectToLower (LayerConnectorLower &partner)
{
NS_DEBUG("LayerConnectorUpper::DoConnectToLower (" << &partner << ")");
m_lowerPartner = &partner;
NS_ASSERT (m_lowerPartner);
return true;
}
bool
LayerConnectorUpper::UpperSendUp (Packet &p)
{
NS_DEBUG("LayerConnectorUpper::UpperSendUp (" << &p << ")");
return UpperDoSendUp(p);
}
bool
LayerConnectorUpper::UpperPull (Packet &p)
{
NS_DEBUG("LayerConnectorUpper::UpperPull (" << &p << ")");
return UpperDoPull(p);
}
bool
LayerConnectorUpper::UpperNotify ()
{
NS_DEBUG("LayerConnectorUpper::UpperNotify ()");
NS_ASSERT (m_lowerPartner);
return m_lowerPartner->LowerNotify(this);
}
LayerConnectorLower::LayerConnectorLower ()
{
NS_DEBUG("LayerConnectorLower::LayerConnectorLower ()");
}
LayerConnectorLower::~LayerConnectorLower ()
{
NS_DEBUG("LayerConnectorLower::~LayerConnectorLower ()");
}
bool
LayerConnectorLower::ConnectToUpper (LayerConnectorUpper &partner)
{
NS_DEBUG("LayerConnectorLower::ConnectToUpper (" << &partner << ")");
return DoConnectToUpper(partner);
}
bool
LayerConnectorLower::DoConnectToUpper (LayerConnectorUpper &partner)
{
NS_DEBUG("LayerConnectorLower::DoConnectToUpper (" << &partner << ")");
m_upperPartner = &partner;
NS_ASSERT (m_upperPartner);
return true;
}
bool
LayerConnectorLower::LowerSendUp (Packet &p)
{
NS_DEBUG("LayerConnectorLower::LowerSendUp (" << &p << ")");
NS_ASSERT (m_upperPartner);
return m_upperPartner->UpperSendUp(p);
}
bool
LayerConnectorLower::LowerPull (Packet &p)
{
NS_DEBUG("LayerConnectorLower::LowerPull (" << &p << ")");
NS_ASSERT (m_upperPartner);
return m_upperPartner->UpperPull(p);
}
bool
LayerConnectorLower::LowerNotify (LayerConnectorUpper *upper)
{
NS_DEBUG("LayerConnectorLower::LowerNotify ()");
return LowerDoNotify(upper);
}
} // namespace ns3

View File

@@ -1,97 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 University of Washington
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Craig Dowell <craigdo@ee.washingon.edu>
*
* Wed Feb 14 16:05:46 PST 2007 craigdo: created
*/
#include "ns3/packet.h"
#ifndef LAYER_CONNECTOR_H
#define LAYER_CONNECTOR_H
namespace ns3 {
class LayerConnectorLower;
class LayerConnectorUpper {
public:
LayerConnectorUpper ();
virtual ~LayerConnectorUpper ();
// called by the layer connector to introduce the lower interface to us here
bool ConnectToLower (LayerConnectorLower &lower);
// called by the lower layer to send a received packet on up the protocol
// stack to us here.
bool UpperSendUp (Packet &p);
// Call this function to tell a lower layer that there is data available
// here. It is expected that the lower layer will call pull as soon as
// possible to get the data.
bool UpperNotify ();
// called by the lower layer to get available packet data that was implied
// by a previous Notify() call.
bool UpperPull(Packet &p);
protected:
virtual bool DoConnectToLower (LayerConnectorLower &lower);
virtual bool UpperDoSendUp (Packet &p) = 0;
virtual bool UpperDoPull (Packet &p) = 0;
LayerConnectorLower *m_lowerPartner;
private:
};
class LayerConnectorLower
{
public:
LayerConnectorLower ();
virtual ~LayerConnectorLower ();
// This function is called by the layer connector to introduce the upper
// layer interface to us here
bool ConnectToUpper (LayerConnectorUpper &upper);
// Notify is called by the upper layer connector to tell us that there
// is data available. It is expected that we will call pull (below) as
// soon as possible to get the data.
bool LowerNotify (LayerConnectorUpper *upper);
// The lower connector calls this method to send a received packet on up
// the protocol stack
bool LowerSendUp (Packet &p);
// Call this function to get available packet data from the upper connector
// that was implied by a previous Notify() call.
bool LowerPull(Packet &p);
protected:
virtual bool DoConnectToUpper (LayerConnectorUpper &upper);
virtual bool LowerDoNotify (LayerConnectorUpper *upper) = 0;
LayerConnectorUpper *m_upperPartner;
private:
};
}; // namespace ns3
#endif /* LAYER_CONNECTOR_H */

View File

@@ -21,7 +21,6 @@
#include "p2p-channel.h"
#include "p2p-net-device.h"
#include "p2p-phy.h"
#include "ns3/packet.h"
#include "ns3/simulator.h"
#include "ns3/debug.h"
@@ -71,13 +70,13 @@ PointToPointChannel::PointToPointChannel(
}
void
PointToPointChannel::Attach(PointToPointPhy *phy)
PointToPointChannel::Attach(PointToPointNetDevice *device)
{
NS_DEBUG("PointToPointChannel::Attach (" << phy << ")");
NS_DEBUG("PointToPointChannel::Attach (" << device << ")");
NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
NS_ASSERT(phy);
NS_ASSERT(device);
m_link[m_nDevices].m_src = phy;
m_link[m_nDevices].m_src = device;
++m_nDevices;
//
// If we have both devices connected to the channel, then finish introducing
@@ -92,28 +91,13 @@ PointToPointChannel::Attach(PointToPointPhy *phy)
}
}
void
PointToPointChannel::TransmitCompleteEvent(Packet p, PointToPointPhy *src)
{
NS_DEBUG("PointToPointChannel::TransmitCompleteEvent (" << &p << ", " <<
src << ")");
NS_ASSERT(m_link[0].m_state != INITIALIZING);
NS_ASSERT(m_link[1].m_state != INITIALIZING);
uint32_t wire = src == m_link[0].m_src ? 0 : 1;
NS_ASSERT(m_link[wire].m_state == TRANSMITTING);
m_link[wire].m_state = IDLE;
NS_DEBUG("PointToPointChannel::TransmitCompleteEvent (): Receive()");
m_link[wire].m_dst->Receive (p);
}
bool
PointToPointChannel::Propagate(Packet& p, PointToPointPhy* src)
PointToPointChannel::TransmitStart(Packet& p, PointToPointNetDevice* src)
{
NS_DEBUG("PointToPointChannel::DoPropagate (" << &p << ", " << src << ")");
NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src <<
")");
NS_DEBUG ("PointToPointChannel::TransmitStart (): UID is " <<
p.GetUid () << ")");
NS_ASSERT(m_link[0].m_state != INITIALIZING);
NS_ASSERT(m_link[1].m_state != INITIALIZING);
@@ -122,33 +106,86 @@ PointToPointChannel::Propagate(Packet& p, PointToPointPhy* src)
if (m_link[wire].m_state == TRANSMITTING)
{
NS_DEBUG("PointToPointChannel::DoPropagate (): TRANSMITTING, return");
NS_DEBUG("PointToPointChannel::TransmitStart (): **** ERROR ****");
NS_DEBUG("PointToPointChannel::TransmitStart (): state TRANSMITTING");
return false;
}
NS_DEBUG("PointToPointChannel::TransmitStart (): switch to TRANSMITTING");
m_link[wire].m_state = TRANSMITTING;
Time txTime = Seconds (m_bps.CalculateTxTime(p.GetSize()));
Time tEvent = txTime + m_delay;
NS_DEBUG("PointToPointChannel::DoSend (): Schedule bps " <<
m_bps.GetBitRate() << " txTime " << m_bps.CalculateTxTime(p.GetSize()) <<
" prop delay " << m_delay << " Recv. delay " << tEvent);
Simulator::Schedule (tEvent, &PointToPointChannel::TransmitCompleteEvent,
this, p, src);
return true;
}
bool
PointToPointChannel::TransmitEnd(Packet& p, PointToPointNetDevice* src)
{
NS_DEBUG("PointToPointChannel::TransmitEnd (" << &p << ", " << src << ")");
NS_DEBUG ("PointToPointChannel::TransmitEnd (): UID is " <<
p.GetUid () << ")");
NS_ASSERT(m_link[0].m_state != INITIALIZING);
NS_ASSERT(m_link[1].m_state != INITIALIZING);
uint32_t wire = src == m_link[0].m_src ? 0 : 1;
NS_ASSERT(m_link[wire].m_state == TRANSMITTING);
m_link[wire].m_state = PROPAGATING;
//
// The sender is going to free the packet as soon as it has been transmitted.
// We need to copy it to get a reference so it won't e deleted.
//
Packet packet = p;
NS_DEBUG ("PointToPointChannel::TransmitEnd (): Schedule event in " <<
m_delay.GetSeconds () << "sec");
Simulator::Schedule (m_delay,
&PointToPointChannel::PropagationCompleteEvent,
this, packet, src);
return true;
}
void
PointToPointChannel::PropagationCompleteEvent(
Packet p,
PointToPointNetDevice *src)
{
NS_DEBUG("PointToPointChannel::PropagationCompleteEvent (" << &p << ", " <<
src << ")");
NS_DEBUG ("PointToPointChannel::PropagationCompleteEvent (): UID is " <<
p.GetUid () << ")");
uint32_t wire = src == m_link[0].m_src ? 0 : 1;
NS_ASSERT(m_link[wire].m_state == PROPAGATING);
m_link[wire].m_state = IDLE;
NS_DEBUG ("PointToPointChannel::PropagationCompleteEvent (): Receive");
m_link[wire].m_dst->Receive (p);
}
uint32_t
PointToPointChannel::GetNDevices (void) const
{
return m_nDevices;
}
NetDevice *
PointToPointChannel::GetDevice (uint32_t i) const
{
return m_link[i].m_src->GetDevice ();
NS_ASSERT(i < 2);
return m_link[i].m_src;
}
DataRate
PointToPointChannel::GetDataRate (void)
{
return m_bps;
}
Time
PointToPointChannel::GetDelay (void)
{
return m_delay;
}

View File

@@ -27,22 +27,22 @@
namespace ns3 {
class PointToPointPhy;
class NetDevice;
class PointToPointNetDevice;
/**
* \brief Simple Point To Point Channel.
*
* This class represents a very simple serial channel. Think full duplex
* RS-232 or RS-422 with null modem and no handshaking. There is no multi-
* drop capability on this channel -- there can be a maximum of two serial
* net devices connected. Once we start talking about multi-drop, or CSMA,
* or some other sharing mechanism, things begin getting complicated quickly.
* Rather than invent some ad-hoc mechanism, we just Keep It Simple everywhere.
* This class represents a very simple point to point channel. Think full
* duplex RS-232 or RS-422 with null modem and no handshaking. There is no
* multi-drop capability on this channel -- there can be a maximum of two
* point-to-point net devices connected. Once we start talking about multi-
* drop, or CSMA, or some other sharing mechanism, things begin getting
* complicated quickly. Rather than invent some ad-hoc mechanism, we just
* Keep It Simple everywhere.
*
* When the channel is instaniated, the constructor takes parameters for
* a single channel speed, in bits per second, and a delay time as a Time
* object. Both directions use the same speed and delay time.
* a single speed, in bits per second, and a speed-of-light delay time as a
* Time object. Both directions use the same speed and delay time.
*
* There are two "wires" in the channel. The first device connected gets the
* [0] wire to transmit on. The second device gets the [1] wire. There is a
@@ -62,16 +62,18 @@ public:
PointToPointChannel (const std::string& name,
const DataRate& bps, const Time& delay);
void Attach (PointToPointPhy* phy);
bool Propagate (Packet& p, PointToPointPhy *src);
void Attach (PointToPointNetDevice* device);
bool TransmitStart (Packet& p, PointToPointNetDevice *src);
bool TransmitEnd (Packet &p, PointToPointNetDevice *src);
void PropagationCompleteEvent(Packet p, PointToPointNetDevice *src);
virtual uint32_t GetNDevices (void) const;
virtual NetDevice *GetDevice (uint32_t i) const;
virtual DataRate GetDataRate (void);
virtual Time GetDelay (void);
private:
void TransmitCompleteEvent (Packet p, PointToPointPhy *src);
DataRate m_bps;
Time m_delay;
@@ -81,16 +83,17 @@ private:
{
INITIALIZING,
IDLE,
TRANSMITTING
TRANSMITTING,
PROPAGATING
};
class Link
{
public:
Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
WireState m_state;
PointToPointPhy *m_src;
PointToPointPhy *m_dst;
WireState m_state;
PointToPointNetDevice *m_src;
PointToPointNetDevice *m_dst;
};
Link m_link[N_DEVICES];

View File

@@ -23,18 +23,21 @@
#include <cassert>
#include "ns3/debug.h"
#include "ns3/queue.h"
#include "ns3/simulator.h"
#include "ns3/composite-trace-resolver.h"
#include "p2p-net-device.h"
#include "p2p-channel.h"
#include "p2p-phy.h"
NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice");
namespace ns3 {
PointToPointNetDevice::PointToPointNetDevice(Node* node) :
NetDevice(node, MacAddress("00:00:00:00:00:00")), m_phy(0), m_channel(0),
PointToPointNetDevice::PointToPointNetDevice(Node* node)
:
NetDevice(node, MacAddress("00:00:00:00:00:00")),
m_txMachineState(READY),
m_bps (DataRate(0xffffffff)),
m_channel(0),
m_queue(0)
{
NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << node << ")");
@@ -45,21 +48,30 @@ PointToPointNetDevice::PointToPointNetDevice(Node* node) :
EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
EnableMulticast();
EnablePointToPoint();
m_phy = new PointToPointPhy(node, this);
}
PointToPointNetDevice::~PointToPointNetDevice()
{
NS_DEBUG ("PointToPointNetDevice::~PointToPointNetDevice ()");
delete m_phy;
}
void
PointToPointNetDevice::SetDataRate(DataRate bps)
{
m_bps = bps;
}
bool
void
PointToPointNetDevice::SetInterframeGap(Time t)
{
m_tInterframeGap = t;
}
bool
PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
{
NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
assert (IsLinkUp ());
@@ -68,12 +80,142 @@ PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
tag.address = address;
p.AddTag (tag);
#endif
if (m_queue->Enqueue(p) )
//
// This class simulates a point to point device. In the case of a serial
// link, this means that we're simulating something like a UART. This is
// not a requirement for a point-to-point link, but it's a typical model for
// the device.
//
// Generally, a real device will have a list of pending packets to transmit.
// An on-device CPU frees the main CPU(s) of the details of what is happening
// in the device and feeds the USART. The main CPU basically just sees the
// list of packets -- it puts packets into the list, and the device frees the
// packets when they are transmitted.
//
// In the case of our virtual device here, the queue pointed to by m_queue
// corresponds to this list. The main CPU adds packets to the list by
// calling this method and when the device completes a send, the packets are
// freed in an "interrupt" service routine.
//
// We're going to do the same thing here. So first of all, the incoming packet
// goes onto our queue if possible. If the queue can't handle it, there's
// nothing to be done.
//
if (m_queue->Enqueue(p) == false )
{
NotifyDataAvailable ();
return true;
return false;
}
return false;
//
// If there's a transmission in progress, the "interrupt" will keep the
// transmission process going. If the device is idle, we need to start a
// transmission.
//
// In the real world, the USART runs until it finishes sending bits, and then
// pulls on the device's transmit complete interrupt wire. At the same time,
// the electrons from the last wiggle of the wire are busy propagating down
// the wire. In the case of a long speed-of-light delay in the wire, we could
// conceivably start transmitting the next packet before the end of the
// previously sent data has even reached the end of the wire. This situation
// is usually avoided (like the plague) and an "interframe gap" is introduced.
// This is usually the round-trip delay on the channel plus some hard-to-
// quantify receiver turn-around time (the time required for the receiver
// to process the last frame and prepare for reception of the next).
//
// So, if the transmit machine is ready, we need to schedule a transmit
// complete event (at which time we tell the channel we're no longer sending
// bits). A separate transmit ready event (at which time the transmitter
// becomes ready to start sending bits again is scheduled there). Finally,
// we tell the channel (via TransmitStart ()) that we've started wiggling the
// wire and bits are coming out.
//
// If the transmit machine is not ready, we just leave and the transmit ready
// event we know is coming will kick-start the transmit process.
//
if (m_txMachineState == READY)
{
return TransmitStart (p);
}
return true;
}
bool
PointToPointNetDevice::TransmitStart (Packet &p)
{
NS_DEBUG ("PointToPointNetDevice::TransmitStart (" << &p << ")");
NS_DEBUG ("PointToPointNetDevice::TransmitStart (): UID is " << p.GetUid () << ")");
//
// This function is called to start the process of transmitting a packet.
// We need to tell the channel that we've started wiggling the wire and
// schedule an event that will be executed when it's time to tell the
// channel that we're done wiggling the wire.
//
NS_ASSERT(m_txMachineState == READY && "Must be READY to transmit");
m_txMachineState = BUSY;
Time tEvent = Seconds (m_bps.CalculateTxTime(p.GetSize()));
NS_DEBUG ("PointToPointNetDevice::TransmitStart (): " <<
"Schedule TransmitCompleteEvent in " <<
tEvent.GetSeconds () << "sec");
Simulator::Schedule (tEvent,
&PointToPointNetDevice::TransmitCompleteEvent,
this);
return m_channel->TransmitStart (p, this);
}
void
PointToPointNetDevice::TransmitCompleteEvent (void)
{
NS_DEBUG ("PointToPointNetDevice::TransmitCompleteEvent ()");
//
// This function is called to finish the process of transmitting a packet.
// We need to tell the channel that we've stopped wiggling the wire and
// schedule an event that will be executed when it's time to re-enable
// the transmitter after the interframe gap.
//
NS_ASSERT(m_txMachineState == BUSY && "Must be BUSY if transmitting");
m_txMachineState = GAP;
Packet p;
bool found = m_queue->Dequeue (p);
NS_ASSERT(found && "Packet must be on queue if transmitted");
NS_DEBUG ("PointToPointNetDevice::TransmitCompleteEvent (): Pkt UID is " <<
p.GetUid () << ")");
m_channel->TransmitEnd (p, this);
NS_DEBUG (
"PointToPointNetDevice::TransmitCompleteEvent (): " <<
"Schedule TransmitReadyEvent in "
<< m_tInterframeGap.GetSeconds () << "sec");
Simulator::Schedule (m_tInterframeGap,
&PointToPointNetDevice::TransmitReadyEvent,
this);
}
void
PointToPointNetDevice::TransmitReadyEvent (void)
{
NS_DEBUG ("PointToPointNetDevice::TransmitReadyEvent ()");
//
// This function is called to enable the transmitter after the interframe
// gap has passed. If there are pending transmissions, we use this opportunity
// to start the next transmit.
//
NS_ASSERT(m_txMachineState == GAP && "Must be in interframe gap");
m_txMachineState = READY;
if (m_queue->IsEmpty())
{
return;
}
else
{
Packet p;
bool found = m_queue->Peek (p);
NS_ASSERT(found && "IsEmpty false but no Packet on queue?");
TransmitStart (p);
}
}
TraceResolver *
@@ -95,7 +237,11 @@ PointToPointNetDevice::Attach (PointToPointChannel* ch)
NS_DEBUG ("PointToPointNetDevice::Attach (" << &ch << ")");
m_channel = ch;
m_phy->Attach (m_channel);
m_channel->Attach(this);
m_bps = m_channel->GetDataRate ();
m_tInterframeGap = m_channel->GetDelay ();
/*
* For now, this device is up whenever a channel is attached to it.
* In fact, it should become up only when the second device
@@ -126,25 +272,6 @@ PointToPointNetDevice::Receive (Packet& p)
ForwardUp (p);
}
void
PointToPointNetDevice::NotifyDataAvailable(void)
{
NS_DEBUG ("PointToPointNetDevice::NotifyDataAvailable ()");
Packet p;
bool found = GetQueue ()->Dequeue (p);
if (found)
{
#ifdef NOTYET
struct NetDevicePacketDestAddress tag;
p.PeekTag (tag);
// send packet to address tag.address
#endif
NS_DEBUG ("PointToPointNetDevice::NotifyDataAvailable (): Dequeued");
m_phy->Send(p);
}
}
Queue*
PointToPointNetDevice::GetQueue(void) const
{

View File

@@ -28,11 +28,12 @@
#include "ns3/callback.h"
#include "ns3/packet.h"
#include "ns3/callback-trace-source.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
namespace ns3 {
class PointToPointChannel;
class PointToPointPhy;
class Queue;
class PointToPointNetDevice : public NetDevice {
@@ -41,9 +42,13 @@ public:
QUEUE,
RX,
};
PointToPointNetDevice(Node* node);
virtual ~PointToPointNetDevice();
void SetDataRate(DataRate bps);
void SetInterframeGap(Time t);
private:
// Don't let the compiler slip in copy and assignment construction
PointToPointNetDevice(const PointToPointNetDevice&);
@@ -52,7 +57,6 @@ private:
public:
bool Attach(PointToPointChannel* ch);
void AddQueue(Queue*);
// called by PointToPointPhy
void Receive (Packet& p);
protected:
@@ -60,11 +64,25 @@ protected:
PointToPointChannel* GetChannel(void) const;
private:
virtual void NotifyDataAvailable (void);
virtual bool SendTo (Packet& p, const MacAddress& dest);
bool TransmitStart (Packet &p);
void TransmitCompleteEvent (void);
void TransmitReadyEvent (void);
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
PointToPointPhy* m_phy;
enum TxMachineState
{
READY,
BUSY,
GAP
};
TxMachineState m_txMachineState;
DataRate m_bps;
Time m_tInterframeGap;
PointToPointChannel* m_channel;
Queue* m_queue;
CallbackTraceSource<Packet &> m_rxTrace;

View File

@@ -1,71 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ns3/debug.h"
#include "ns3/queue.h"
#include "p2p-phy.h"
#include "p2p-net-device.h"
#include "p2p-channel.h"
NS_DEBUG_COMPONENT_DEFINE ("PointToPointPhy");
namespace ns3 {
PointToPointPhy::PointToPointPhy(Node* node, PointToPointNetDevice* netdevice) :
m_node(node), m_netdevice(netdevice)
{
NS_DEBUG ("PointToPointPhy::PointToPointPhy (" << node << ", " <<
netdevice << ")");
}
PointToPointPhy::~PointToPointPhy()
{
NS_DEBUG ("PointToPointPhy::~PointToPointPhy ()");
}
void
PointToPointPhy::Send (Packet &p)
{
m_channel->Propagate (p, this);
}
void
PointToPointPhy::Attach (PointToPointChannel *channel)
{
m_channel = channel;
m_channel->Attach (this);
}
PointToPointNetDevice *
PointToPointPhy::GetDevice (void)
{
return m_netdevice;
}
void
PointToPointPhy::Receive (Packet& p)
{
NS_DEBUG ("PointToPointPhy::Receive (" << &p << ")");
m_netdevice->Receive (p);
}
} // namespace ns3

View File

@@ -1,50 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Craig Dowell <craigdo@ee.washington.edu>
*/
#ifndef POINT_TO_POINT_PHY_H
#define POINT_TO_POINT_PHY_H
namespace ns3 {
class PointToPointNetDevice;
class PointToPointChannel;
class Node;
class Packet;
class PointToPointPhy {
public:
PointToPointPhy(Node* node, PointToPointNetDevice* netdevice);
virtual ~PointToPointPhy();
void Send (Packet &p);
void Receive (Packet& p);
void Attach (PointToPointChannel *channel);
PointToPointNetDevice *GetDevice (void);
private:
Node* m_node;
PointToPointChannel *m_channel;
PointToPointNetDevice* m_netdevice;
};
} // namespace ns3
#endif // POINT_TO_POINT_PHY_H

View File

@@ -1,49 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 University of Washington
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Craig Dowell <craigdo@ee.washingon.edu>
*
* Thu Feb 15 15:06:15 PST 2007 craigdo: Created
*/
#ifndef PROPAGATOR_H
#define PROPAGATOR_H
#include "ns3/packet.h"
namespace ns3 {
class Propagator
{
public:
Propagator () : m_packet(0) {}
virtual ~Propagator () {}
void SetPacket (Packet &p) {DoSetPacket(p);}
protected:
virtual void DoSetPacket (Packet &p) {m_packet = static_cast<Packet *>(&p);}
Packet *m_packet;
private:
};
}; // namespace ns3
#endif /* SERIAL_PHY_H */

View File

@@ -101,4 +101,20 @@ DropTailQueue::DoDequeue (Packet& p)
return true;
}
bool
DropTailQueue::DoPeek (Packet& p)
{
NS_DEBUG("DropTailQueue::DoPeek (" << &p << ")");
if (m_packets.empty())
{
NS_DEBUG("DropTailQueue::DoPeek (): Queue empty");
return false;
}
p = m_packets.front ();
return true;
}
}; // namespace ns3

View File

@@ -43,6 +43,7 @@ public:
private:
virtual bool DoEnqueue (const Packet& p);
virtual bool DoDequeue (Packet &p);
virtual bool DoPeek (Packet &p);
private:
std::queue<Packet> m_packets;

View File

@@ -50,7 +50,7 @@ class TraceContext;
* constructed with destination MAC address already selected).
*
* If you want to write a new MAC layer, you need to subclass
* this base class and implement your own version of the
* this base class and implement your own version of the
* NetDevice::SendTo method.
*/
class NetDevice {
@@ -190,7 +190,7 @@ class NetDevice {
* \returns true if the packet was forwarded successfully,
* false otherwise.
*
* When a subclass gets a packet from the PHY layer, it
* When a subclass gets a packet from the channel, it
* forwards it to the higher layers by calling this method
* which is responsible for passing it up to the Rx callback.
*/
@@ -205,10 +205,10 @@ class NetDevice {
*
* This is the private virtual target function of the public Send()
* method. When the link is Up, this method is invoked to ask
* subclasses to forward packets down to the PHY layer. Subclasses
* MUST override this method.
* subclasses to forward packets. Subclasses MUST override this method.
*/
virtual bool SendTo (Packet& p, const MacAddress& dest) = 0;
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
Node* m_node;
std::string m_name;

View File

@@ -103,6 +103,15 @@ Queue::DequeueAll (void)
NS_ASSERT (!"Don't know what to do with dequeued packets!");
}
bool
Queue::Peek (Packet &p)
{
NS_DEBUG("Queue::Peek (" << &p << ")");
return DoPeek (p);
}
uint32_t
Queue::GetNPackets (void)
{

View File

@@ -50,6 +50,7 @@ public:
bool IsEmpty (void);
bool Enqueue (const Packet& p);
bool Dequeue (Packet &p);
bool Peek (Packet &p);
void DequeueAll (void);
uint32_t GetNPackets (void);
@@ -89,6 +90,7 @@ public:
private:
virtual bool DoEnqueue (const Packet& p) = 0;
virtual bool DoDequeue (Packet &p) = 0;
virtual bool DoPeek (Packet &p) = 0;
protected:
// called by subclasses to notify parent of packet drops.