remove unused files, remove notion of PHY, make more realistic p2p-net-device and p2p-channel
This commit is contained in:
@@ -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',
|
||||
])
|
||||
|
||||
|
||||
|
||||
@@ -207,7 +207,6 @@ int main (int argc, char *argv[])
|
||||
DebugComponentEnable("Channel");
|
||||
DebugComponentEnable("PointToPointChannel");
|
||||
DebugComponentEnable("PointToPointNetDevice");
|
||||
DebugComponentEnable("PointToPointPhy");
|
||||
#endif
|
||||
ObjectContainer container;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user