diff --git a/SConstruct b/SConstruct index 13f65b788..7161fe8a2 100644 --- a/SConstruct +++ b/SConstruct @@ -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', ]) diff --git a/examples/simple-p2p.cc b/examples/simple-p2p.cc index 5410c7606..ea68b6b8c 100644 --- a/examples/simple-p2p.cc +++ b/examples/simple-p2p.cc @@ -207,7 +207,6 @@ int main (int argc, char *argv[]) DebugComponentEnable("Channel"); DebugComponentEnable("PointToPointChannel"); DebugComponentEnable("PointToPointNetDevice"); - DebugComponentEnable("PointToPointPhy"); #endif ObjectContainer container; diff --git a/src/devices/p2p/layer-connector.cc b/src/devices/p2p/layer-connector.cc deleted file mode 100644 index 9134e9b1c..000000000 --- a/src/devices/p2p/layer-connector.cc +++ /dev/null @@ -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 - * - * 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 diff --git a/src/devices/p2p/layer-connector.h b/src/devices/p2p/layer-connector.h deleted file mode 100644 index 0c3f37626..000000000 --- a/src/devices/p2p/layer-connector.h +++ /dev/null @@ -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 - * - * 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 */ diff --git a/src/devices/p2p/p2p-channel.cc b/src/devices/p2p/p2p-channel.cc index 92d8e7d76..c0a8342b7 100644 --- a/src/devices/p2p/p2p-channel.cc +++ b/src/devices/p2p/p2p-channel.cc @@ -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; } diff --git a/src/devices/p2p/p2p-channel.h b/src/devices/p2p/p2p-channel.h index 445fa61e4..13256a2d7 100644 --- a/src/devices/p2p/p2p-channel.h +++ b/src/devices/p2p/p2p-channel.h @@ -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]; diff --git a/src/devices/p2p/p2p-net-device.cc b/src/devices/p2p/p2p-net-device.cc index 3dcf57553..cd6d7f235 100644 --- a/src/devices/p2p/p2p-net-device.cc +++ b/src/devices/p2p/p2p-net-device.cc @@ -23,18 +23,21 @@ #include #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 { diff --git a/src/devices/p2p/p2p-net-device.h b/src/devices/p2p/p2p-net-device.h index d3310a8ac..a42ba3946 100644 --- a/src/devices/p2p/p2p-net-device.h +++ b/src/devices/p2p/p2p-net-device.h @@ -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 m_rxTrace; diff --git a/src/devices/p2p/p2p-phy.cc b/src/devices/p2p/p2p-phy.cc deleted file mode 100644 index 86387fee5..000000000 --- a/src/devices/p2p/p2p-phy.cc +++ /dev/null @@ -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 - */ - -#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 diff --git a/src/devices/p2p/p2p-phy.h b/src/devices/p2p/p2p-phy.h deleted file mode 100644 index 929a6543d..000000000 --- a/src/devices/p2p/p2p-phy.h +++ /dev/null @@ -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 - */ - -#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 diff --git a/src/devices/p2p/propagator.h b/src/devices/p2p/propagator.h deleted file mode 100644 index e7ae002bb..000000000 --- a/src/devices/p2p/propagator.h +++ /dev/null @@ -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 - * - * 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(&p);} - - Packet *m_packet; -private: -}; - - -}; // namespace ns3 - -#endif /* SERIAL_PHY_H */ diff --git a/src/node/drop-tail.cc b/src/node/drop-tail.cc index b65c4d828..6585db6f2 100644 --- a/src/node/drop-tail.cc +++ b/src/node/drop-tail.cc @@ -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 diff --git a/src/node/drop-tail.h b/src/node/drop-tail.h index da3749833..99e52e4f9 100644 --- a/src/node/drop-tail.h +++ b/src/node/drop-tail.h @@ -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 m_packets; diff --git a/src/node/net-device.h b/src/node/net-device.h index f2ebb66b6..4b30ebf75 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -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; diff --git a/src/node/queue.cc b/src/node/queue.cc index 5567f9041..dbea2d964 100644 --- a/src/node/queue.cc +++ b/src/node/queue.cc @@ -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) { diff --git a/src/node/queue.h b/src/node/queue.h index ba7cd6e62..ac7736ff4 100644 --- a/src/node/queue.h +++ b/src/node/queue.h @@ -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.