diff --git a/doc/modules b/doc/modules index d16f351fb..7c6a7b347 100644 --- a/doc/modules +++ b/doc/modules @@ -42,13 +42,12 @@ * * @defgroup devices Devices * - * @defgroup internetNode InternetNode + * @defgroup internetStack InternetStack * - * The "internet-node" module contains a set of classes which implement the - * APIs defined in the "node" module: - * - an Ipv4/Udp stack with socket support + * The "internet-stack" module contains: + * - an Ipv4 stack * - an ARP module - * - an InternetNode class which is a Node subclass. + * - a UDP and a TCP implementation * * @defgroup helper Helpers * diff --git a/doc/tutorial/introduction.texi b/doc/tutorial/introduction.texi index 7d654a2c5..248120e3f 100644 --- a/doc/tutorial/introduction.texi +++ b/doc/tutorial/introduction.texi @@ -1272,14 +1272,14 @@ files. Put the following code after the include statement in @code{simple.cc}. @verbatim #include "ns3/ptr.h" - #include "ns3/internet-node.h" + #include "ns3/internet-stack.h" @end verbatim @cindex include files The ns-3 build system places the core include files it needs into a directory called @code{ns-3} and so whenever you need to include one of the core files you need to explicitly code this. The file @code{ptr.h} defines -the generic smart pointer that we use. The file @code{internet-node.h} +the generic smart pointer that we use. The file @code{internet-stack.h} defines the class InternetNode which, as described above, represents an IP version 4-based computing element in the simulator. @@ -1455,7 +1455,7 @@ something like the following, @verbatim #include "ns3/log.h" #include "ns3/ptr.h" - #include "ns3/internet-node.h" + #include "ns3/internet-stack.h" #include "ns3/csma-channel.h" #include "ns3/mac48-address.h" #include "ns3/csma-net-device.h" @@ -1632,7 +1632,7 @@ following (let's change the log component name and program banner from @verbatim #include "ns3/log.h" #include "ns3/ptr.h" - #include "ns3/internet-node.h" + #include "ns3/internet-stack.h" #include "ns3/csma-channel.h" #include "ns3/mac48-address.h" #include "ns3/csma-net-device.h" @@ -1883,7 +1883,7 @@ source code for the script should look like the following: @verbatim #include "ns3/log.h" #include "ns3/ptr.h" - #include "ns3/internet-node.h" + #include "ns3/internet-stack.h" #include "ns3/csma-channel.h" #include "ns3/mac48-address.h" #include "ns3/csma-net-device.h" diff --git a/doc/tutorial/other.texi b/doc/tutorial/other.texi index 3e4a63a7b..7b24e7809 100644 --- a/doc/tutorial/other.texi +++ b/doc/tutorial/other.texi @@ -103,7 +103,7 @@ convenience: #include "ns3/log.h" #include "ns3/ptr.h" -#include "ns3/internet-node.h" +#include "ns3/internet-stack.h" #include "ns3/point-to-point-channel.h" #include "ns3/mac48-address.h" #include "ns3/point-to-point-net-device.h" @@ -313,7 +313,7 @@ The file @code{tutorial-star.cc} is reproduced here for your convenience: #include "ns3/log.h" #include "ns3/ptr.h" -#include "ns3/internet-node.h" +#include "ns3/internet-stack.h" #include "ns3/point-to-point-channel.h" #include "ns3/mac48-address.h" #include "ns3/point-to-point-net-device.h" @@ -1846,7 +1846,7 @@ provided to the template function @code{CreateObject} means that call @code{GetObject} on the resulting smart pointer. Well, I'm afraid that's not entirely true. It's slightly more complicated. -Take a look at @code{src/internet-node/internet-node.h} and find the class +Take a look at @code{src/internet-stack/internet-stack.h} and find the class declaration for @code{InternetNode}. @verbatim @@ -1956,7 +1956,7 @@ immediately cast to an @code{Ipv4} pointer. Clients will then use the methods specified in the @code{Ipv4} class to access the @code{Ipv4 Object} methods which are, in turn, implemented in the @code{Ipv4Impl} object. -If you now look in the file, @code{src/internet-node/internet-node.cc} you +If you now look in the file, @code{src/internet-stack/internet-stack.cc} you will see the following code in @code{InternetNode::Construct} that creates the @code{Ipv4} Interface and aggregates it. @@ -2013,7 +2013,7 @@ of course). In the case of @code{Ipv4Impl}, you know that the class inherits somehow from @code{Object} since there is a call to @code{AggregateObject} that refers to an instance of an @code{Ipv4Impl}. You will have to go to -the header file @code{src/internet-node/ipv4-impl.h} and find that +the header file @code{src/internet-stack/ipv4-impl.h} and find that @code{Ipv4Impl} inherits from class @code{Ipv4}. You will then have go to the file @code{src/node/ipv4.h} and see that it inherits from @code{Object} and defines a @code{GetTypeId}. Thus the @code{Object} for which you can diff --git a/doc/tutorial/routing.texi b/doc/tutorial/routing.texi index 1c1afb1d7..d8250ee24 100644 --- a/doc/tutorial/routing.texi +++ b/doc/tutorial/routing.texi @@ -2,7 +2,7 @@ @chapter ns-3 routing overview This chapter describes the overall design of routing in the -@code{src/internet-node} +@code{src/internet-stack} module, and some details about the routing approachs currently implemented. @@ -97,7 +97,7 @@ method that allows one to add a routing protocol: void AddRoutingProtocol (Ptr routingProtocol, int16_t priority); @end verbatim -This method is implemented by class Ipv4L3Protocol in the internet-node +This method is implemented by class Ipv4L3Protocol in the internet-stack module. The priority variable above governs the priority in which the routing @@ -174,7 +174,7 @@ There are presently no roadmap plans for IPv6. @node Static routing @section Static routing -The internet-node module provides one routing protocol (Ipv4StaticRouting) +The internet-stack module provides one routing protocol (Ipv4StaticRouting) by default. This routing protocol allows one to add unicast or multicast static routes to a node. @@ -193,7 +193,7 @@ Ipv4Route Ipv4::GetRoute () @uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation provides full documentation of these methods. These methods are forwarding functions to the actual implementation in Ipv4StaticRouting, when using -the internet-node module. +the internet-stack module. @node Multicast routing @section Multicast routing diff --git a/examples/csma-broadcast.cc b/examples/csma-broadcast.cc index 0e5c2f5fb..963be3ff5 100644 --- a/examples/csma-broadcast.cc +++ b/examples/csma-broadcast.cc @@ -69,7 +69,7 @@ main (int argc, char *argv[]) NS_LOG_INFO ("Build Topology."); CsmaHelper csma; - csma.SetChannelParameter ("BitRate", DataRateValue (DataRate(5000000))); + csma.SetChannelParameter ("DataRate", DataRateValue (DataRate(5000000))); csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds(2))); NetDeviceContainer n0 = csma.Install (c0); diff --git a/examples/csma-multicast.cc b/examples/csma-multicast.cc index 6a07a3c6b..a7775c7b8 100644 --- a/examples/csma-multicast.cc +++ b/examples/csma-multicast.cc @@ -75,7 +75,7 @@ main (int argc, char *argv[]) NS_LOG_INFO ("Build Topology."); CsmaHelper csma; - csma.SetChannelParameter ("BitRate", DataRateValue (DataRate (5000000))); + csma.SetChannelParameter ("DataRate", DataRateValue (DataRate (5000000))); csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); // We will use these NetDevice containers later, for IP addressing diff --git a/examples/csma-one-subnet.cc b/examples/csma-one-subnet.cc index f90a6ad43..bd827b904 100644 --- a/examples/csma-one-subnet.cc +++ b/examples/csma-one-subnet.cc @@ -66,7 +66,7 @@ main (int argc, char *argv[]) NS_LOG_INFO ("Build Topology"); CsmaHelper csma; - csma.SetChannelParameter ("BitRate", DataRateValue (5000000)); + csma.SetChannelParameter ("DataRate", DataRateValue (5000000)); csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); // // Now fill out the topology by creating the net devices required to connect diff --git a/examples/csma-packet-socket.cc b/examples/csma-packet-socket.cc index 42dfb2e17..f35fc77c5 100644 --- a/examples/csma-packet-socket.cc +++ b/examples/csma-packet-socket.cc @@ -67,8 +67,9 @@ main (int argc, char *argv[]) // create the shared medium used by all csma devices. NS_LOG_INFO ("Create channels."); - Ptr channel = CreateObject ("BitRate", DataRateValue (DataRate(5000000)), - "Delay", TimeValue (MilliSeconds(2))); + Ptr channel = CreateObject ( + "DataRate", DataRateValue (DataRate(5000000)), + "Delay", TimeValue (MilliSeconds(2))); // use a helper function to connect our nodes to the shared channel. NS_LOG_INFO ("Build Topology."); diff --git a/examples/mixed-global-routing.cc b/examples/mixed-global-routing.cc index 361b0ef34..dfa262414 100644 --- a/examples/mixed-global-routing.cc +++ b/examples/mixed-global-routing.cc @@ -83,7 +83,7 @@ main (int argc, char *argv[]) // We create the channels first without any IP addressing information CsmaHelper csma; - csma.SetChannelParameter ("BitRate", StringValue ("5Mbps")); + csma.SetChannelParameter ("DataRate", StringValue ("5Mbps")); csma.SetChannelParameter ("Delay", StringValue ("2ms")); NetDeviceContainer d2345 = csma.Install (n2345); diff --git a/examples/mixed-wireless.cc b/examples/mixed-wireless.cc index 923def716..ae7b89dd5 100644 --- a/examples/mixed-wireless.cc +++ b/examples/mixed-wireless.cc @@ -199,7 +199,8 @@ main (int argc, char *argv[]) // collection. // CsmaHelper csma; - csma.SetChannelParameter ("BitRate", DataRateValue (DataRate (5000000))); + csma.SetChannelParameter ("DataRate", + DataRateValue (DataRate (5000000))); csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); NetDeviceContainer lanDevices = csma.Install (lan); // diff --git a/examples/tcp-large-transfer.cc b/examples/tcp-large-transfer.cc index 16110a7e0..c715e348a 100644 --- a/examples/tcp-large-transfer.cc +++ b/examples/tcp-large-transfer.cc @@ -28,6 +28,10 @@ // "tcp-large-transfer.pcap-$n-$i" where n and i represent node and interface numbers respectively // Usage (e.g.): ./waf --run tcp-large-transfer +//XXX this isn't working as described right now +//it is just blasting away for 10 seconds, with no fixed amount of data +//being sent + #include #include #include @@ -73,39 +77,9 @@ ApplicationTraceSink (Ptr packet, #endif } -void CloseConnection (Ptr localSocket) -{ - localSocket->Close (); -} - -void StartFlow(Ptr localSocket, uint32_t nBytes, - Ipv4Address servAddress, - uint16_t servPort) -{ - // NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ()); - localSocket->Connect (InetSocketAddress (servAddress, servPort));//connect - localSocket->SetConnectCallback (MakeCallback (&CloseConnection), - Callback > (), - Callback > ()); - //we want to close as soon as the connection is established - //the tcp state machine and outgoing buffer will assure that - //all of the data is delivered - - // Perform series of 1040 byte writes (this is a multiple of 26 since - // we want to detect data splicing in the output stream) - uint32_t writeSize = 1040; - uint8_t data[writeSize]; - while (nBytes > 0) { - uint32_t curSize= nBytes > writeSize ? writeSize : nBytes; - for(uint32_t i = 0; i < curSize; ++i) - { - char m = toascii (97 + i % 26); - data[i] = m; - } - localSocket->Send (data, curSize); - nBytes -= curSize; - } -} +void CloseConnection (Ptr localSocket); +void StartFlow(Ptr, uint32_t, Ipv4Address, uint16_t); +void WriteUntilBufferFull (Ptr, uint32_t); int main (int argc, char *argv[]) { @@ -195,3 +169,47 @@ int main (int argc, char *argv[]) Simulator::Run (); Simulator::Destroy (); } + +void CloseConnection (Ptr localSocket) +{ + localSocket->Close (); +} + +void StartFlow(Ptr localSocket, uint32_t nBytes, + Ipv4Address servAddress, + uint16_t servPort) +{ + // NS_LOG_LOGIC("Starting flow at time " << Simulator::Now ().GetSeconds ()); + localSocket->Connect (InetSocketAddress (servAddress, servPort));//connect + localSocket->SetConnectCallback (MakeCallback (&CloseConnection), + Callback > (), + Callback > ()); + //we want to close as soon as the connection is established + //the tcp state machine and outgoing buffer will assure that + //all of the data is delivered + localSocket->SetSendCallback (MakeCallback (&WriteUntilBufferFull)); + WriteUntilBufferFull (localSocket, nBytes); +} + +void WriteUntilBufferFull (Ptr localSocket, uint32_t nBytes) +{ + // Perform series of 1040 byte writes (this is a multiple of 26 since + // we want to detect data splicing in the output stream) + uint32_t writeSize = 1040; + uint8_t data[writeSize]; + while (nBytes > 0) { + uint32_t curSize= nBytes > writeSize ? writeSize : nBytes; + for(uint32_t i = 0; i < curSize; ++i) + { + char m = toascii (97 + i % 26); + data[i] = m; + } + uint32_t amountSent = localSocket->Send (data, curSize); + if(amountSent < curSize) + { + std::cout << "Socket blocking, returning" << std::endl; + return; + } + nBytes -= curSize; + } +} diff --git a/examples/udp-echo.cc b/examples/udp-echo.cc index 001e2a621..edf59ac41 100644 --- a/examples/udp-echo.cc +++ b/examples/udp-echo.cc @@ -87,7 +87,7 @@ main (int argc, char *argv[]) // Explicitly create the channels required by the topology (shown above). // CsmaHelper csma; - csma.SetChannelParameter ("BitRate", DataRateValue (DataRate(5000000))); + csma.SetChannelParameter ("DataRate", DataRateValue (DataRate(5000000))); csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2))); NetDeviceContainer d = csma.Install (n); diff --git a/examples/wscript b/examples/wscript index 53810073c..eb668e130 100644 --- a/examples/wscript +++ b/examples/wscript @@ -3,51 +3,51 @@ def build(bld): obj = bld.create_ns3_program('mixed-wireless', - ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-node']) + ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack']) obj.source = 'mixed-wireless.cc' obj = bld.create_ns3_program('simple-global-routing', - ['point-to-point', 'internet-node', 'global-routing']) + ['point-to-point', 'internet-stack', 'global-routing']) obj.source = 'simple-global-routing.cc' obj = bld.create_ns3_program('simple-alternate-routing', - ['point-to-point', 'internet-node', 'global-routing']) + ['point-to-point', 'internet-stack', 'global-routing']) obj.source = 'simple-alternate-routing.cc' obj = bld.create_ns3_program('simple-error-model', - ['point-to-point', 'internet-node']) + ['point-to-point', 'internet-stack']) obj.source = 'simple-error-model.cc' obj = bld.create_ns3_program('csma-one-subnet', - ['csma', 'internet-node']) + ['csma', 'internet-stack']) obj.source = 'csma-one-subnet.cc' obj = bld.create_ns3_program('udp-echo', - ['csma', 'internet-node']) + ['csma', 'internet-stack']) obj.source = 'udp-echo.cc' obj = bld.create_ns3_program('csma-broadcast', - ['csma', 'internet-node']) + ['csma', 'internet-stack']) obj.source = 'csma-broadcast.cc' obj = bld.create_ns3_program('csma-packet-socket', - ['csma', 'internet-node']) + ['csma', 'internet-stack']) obj.source = 'csma-packet-socket.cc' obj = bld.create_ns3_program('csma-multicast', - ['csma', 'internet-node']) + ['csma', 'internet-stack']) obj.source = 'csma-multicast.cc' obj = bld.create_ns3_program( 'mixed-global-routing', - ['point-to-point', 'internet-node', 'global-routing' , 'csma-cd']) + ['point-to-point', 'internet-stack', 'global-routing' , 'csma-cd']) obj.source = 'mixed-global-routing.cc' obj = bld.create_ns3_program('simple-point-to-point-olsr', - ['point-to-point', 'internet-node', 'olsr']) + ['point-to-point', 'internet-stack', 'olsr']) obj.source = 'simple-point-to-point-olsr.cc' obj = bld.create_ns3_program('tcp-large-transfer', - ['point-to-point', 'internet-node']) + ['point-to-point', 'internet-stack']) obj.source = 'tcp-large-transfer.cc' obj = bld.create_ns3_program('wifi-adhoc', diff --git a/samples/wscript b/samples/wscript index 1cb067662..8215128a9 100644 --- a/samples/wscript +++ b/samples/wscript @@ -20,11 +20,11 @@ def build(bld): obj.source = 'main-test.cc' obj = bld.create_ns3_program('main-simple', - ['node', 'internet-node', 'onoff']) + ['node', 'internet-stack', 'onoff']) obj.source = 'main-simple.cc' obj = bld.create_ns3_program('main-grid-topology', - ['core', 'simulator', 'mobility', 'internet-node']) + ['core', 'simulator', 'mobility', 'internet-stack']) obj.source = 'main-grid-topology.cc' obj = bld.create_ns3_program('main-random-topology', diff --git a/src/applications/udp-echo/udp-echo-client.cc b/src/applications/udp-echo/udp-echo-client.cc index 7dd68701c..55f5bda6d 100644 --- a/src/applications/udp-echo/udp-echo-client.cc +++ b/src/applications/udp-echo/udp-echo-client.cc @@ -37,19 +37,23 @@ UdpEchoClient::GetTypeId (void) static TypeId tid = TypeId ("ns3::UdpEchoClient") .SetParent () .AddConstructor () - .AddAttribute ("MaxPackets", "XXX", + .AddAttribute ("MaxPackets", + "The maximum number of packets the application will send", UintegerValue (100), MakeUintegerAccessor (&UdpEchoClient::m_count), MakeUintegerChecker ()) - .AddAttribute ("Interval", "XXX", + .AddAttribute ("Interval", + "The time to wait between packets", TimeValue (Seconds (1.0)), MakeTimeAccessor (&UdpEchoClient::m_interval), MakeTimeChecker ()) - .AddAttribute ("RemoteIpv4", "XXX", + .AddAttribute ("RemoteIpv4", + "The Ipv4Address of the outbound packets", Ipv4AddressValue (), MakeIpv4AddressAccessor (&UdpEchoClient::m_peerAddress), MakeIpv4AddressChecker ()) - .AddAttribute ("RemotePort", "XXX", + .AddAttribute ("RemotePort", + "The destination port of the outbound packets", UintegerValue (0), MakeUintegerAccessor (&UdpEchoClient::m_peerPort), MakeUintegerChecker ()) diff --git a/src/applications/udp-echo/wscript b/src/applications/udp-echo/wscript index fa25a5c53..762e59ec9 100644 --- a/src/applications/udp-echo/wscript +++ b/src/applications/udp-echo/wscript @@ -1,7 +1,7 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def build(bld): - module = bld.create_ns3_module('udp-echo', ['internet-node']) + module = bld.create_ns3_module('udp-echo', ['internet-stack']) module.source = [ 'udp-echo-client.cc', 'udp-echo-server.cc', diff --git a/src/core/random-variable.cc b/src/core/random-variable.cc index dfa369564..336a2a119 100644 --- a/src/core/random-variable.cc +++ b/src/core/random-variable.cc @@ -156,9 +156,8 @@ void RandomVariableBase::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2, { if (RandomVariableBase::globalSeedSet) { - cerr << "Random number generator already initialized!" << endl; - cerr << "Call to RandomVariableBase::UseGlobalSeed() ignored" << endl; - return; + NS_FATAL_ERROR ("Random number generator already initialized! " + "Call to RandomVariableBase::UseGlobalSeed() ignored"); } RandomVariableBase::globalSeed[0] = s0; RandomVariableBase::globalSeed[1] = s1; diff --git a/src/devices/csma/csma-channel.cc b/src/devices/csma/csma-channel.cc index a17c9db1d..9809daa4e 100644 --- a/src/devices/csma/csma-channel.cc +++ b/src/devices/csma/csma-channel.cc @@ -30,29 +30,15 @@ namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (CsmaChannel); -CsmaDeviceRec::CsmaDeviceRec() -{ - active = false; -} - -CsmaDeviceRec::CsmaDeviceRec(Ptr device) -{ - devicePtr = device; - active = true; -} - -bool -CsmaDeviceRec::IsActive() { - return active; -} - -TypeId + TypeId CsmaChannel::GetTypeId (void) { static TypeId tid = TypeId ("ns3::CsmaChannel") .SetParent () .AddConstructor () - .AddAttribute ("BitRate", "The maximum bitrate of the channel", + .AddAttribute ("DataRate", + "The transmission data rate to be provided to devices " + "connected to the channel", DataRateValue (DataRate (0xffffffff)), MakeDataRateAccessor (&CsmaChannel::m_bps), MakeDataRateChecker ()) @@ -64,10 +50,7 @@ CsmaChannel::GetTypeId (void) return tid; } -// -// By default, you get a channel with the name "Csma Channel" that -// has an "infitely" fast transmission speed and zero delay. -CsmaChannel::CsmaChannel() +CsmaChannel::CsmaChannel () : Channel ("Csma Channel") { @@ -76,26 +59,26 @@ CsmaChannel::CsmaChannel() m_deviceList.clear(); } -int32_t -CsmaChannel::Attach(Ptr device) + int32_t +CsmaChannel::Attach (Ptr device) { NS_LOG_FUNCTION (this << device); - NS_ASSERT(device != 0); + NS_ASSERT (device != 0); - CsmaDeviceRec rec(device); + CsmaDeviceRec rec (device); - m_deviceList.push_back(rec); - return (m_deviceList.size() - 1); + m_deviceList.push_back (rec); + return (m_deviceList.size () - 1); } -bool -CsmaChannel::Reattach(Ptr device) + bool +CsmaChannel::Reattach (Ptr device) { NS_LOG_FUNCTION (this << device); - NS_ASSERT(device != 0); + NS_ASSERT (device != 0); std::vector::iterator it; - for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + for (it = m_deviceList.begin (); it < m_deviceList.end( ); it++) { if (it->devicePtr == device) { @@ -113,12 +96,12 @@ CsmaChannel::Reattach(Ptr device) return false; } -bool -CsmaChannel::Reattach(uint32_t deviceId) + bool +CsmaChannel::Reattach (uint32_t deviceId) { NS_LOG_FUNCTION (this << deviceId); - if (deviceId < m_deviceList.size()) + if (deviceId < m_deviceList.size ()) { return false; } @@ -134,26 +117,25 @@ CsmaChannel::Reattach(uint32_t deviceId) } } -bool -CsmaChannel::Detach(uint32_t deviceId) + bool +CsmaChannel::Detach (uint32_t deviceId) { NS_LOG_FUNCTION (this << deviceId); - if (deviceId < m_deviceList.size()) + if (deviceId < m_deviceList.size ()) { if (!m_deviceList[deviceId].active) { - NS_LOG_WARN ("CsmaChannel::Detach Device is already detached (" << - deviceId << ")"); + NS_LOG_WARN ("CsmaChannel::Detach(): " + "Device is already detached (" << deviceId << ")"); return false; } m_deviceList[deviceId].active = false; if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId)) { - NS_LOG_WARN ("CsmaChannel::Detach Device is currently" << + NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << "transmitting (" << deviceId << ")"); - // Here we will need to place a warning in the packet } return true; @@ -164,14 +146,14 @@ CsmaChannel::Detach(uint32_t deviceId) } } -bool -CsmaChannel::Detach(Ptr device) + bool +CsmaChannel::Detach (Ptr device) { NS_LOG_FUNCTION (this << device); - NS_ASSERT(device != 0); + NS_ASSERT (device != 0); std::vector::iterator it; - for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + for (it = m_deviceList.begin (); it < m_deviceList.end (); it++) { if ((it->devicePtr == device) && (it->active)) { @@ -182,21 +164,22 @@ CsmaChannel::Detach(Ptr device) return false; } -bool -CsmaChannel::TransmitStart(Ptr p, uint32_t srcId) + bool +CsmaChannel::TransmitStart (Ptr p, uint32_t srcId) { NS_LOG_FUNCTION (this << p << srcId); NS_LOG_INFO ("UID is " << p->GetUid () << ")"); if (m_state != IDLE) { - NS_LOG_WARN ("state is not IDLE"); + NS_LOG_WARN ("CsmaChannel::TransmitStart(): State is not IDLE"); return false; } if (!IsActive(srcId)) { - NS_LOG_ERROR ("Seclected source is not currently attached to network"); + NS_LOG_ERROR ("CsmaChannel::TransmitStart(): " + "Seclected source is not currently attached to network"); return false; } @@ -207,51 +190,51 @@ CsmaChannel::TransmitStart(Ptr p, uint32_t srcId) return true; } -bool + bool CsmaChannel::IsActive(uint32_t deviceId) { - return (m_deviceList[deviceId].active); + return (m_deviceList[deviceId].active); } -bool + bool CsmaChannel::TransmitEnd() { NS_LOG_FUNCTION (this << m_currentPkt << m_currentSrc); NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")"); - NS_ASSERT(m_state == TRANSMITTING); + NS_ASSERT (m_state == TRANSMITTING); m_state = PROPAGATING; bool retVal = true; - if (!IsActive(m_currentSrc)) { - NS_LOG_ERROR ("Seclected source was detached before the end of the" - "transmission"); - retVal = false; - } + if (!IsActive (m_currentSrc)) + { + NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): " + "Seclected source was detached before the end of the transmission"); + retVal = false; + } NS_LOG_LOGIC ("Schedule event in " << m_delay.GetSeconds () << " sec"); - Simulator::Schedule (m_delay, - &CsmaChannel::PropagationCompleteEvent, - this); + Simulator::Schedule (m_delay, &CsmaChannel::PropagationCompleteEvent, + this); return retVal; } -void + void CsmaChannel::PropagationCompleteEvent() { NS_LOG_FUNCTION (this << m_currentPkt); NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")"); - NS_ASSERT(m_state == PROPAGATING); + NS_ASSERT (m_state == PROPAGATING); NS_LOG_LOGIC ("Receive"); std::vector::iterator it; - for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + for (it = m_deviceList.begin (); it < m_deviceList.end(); it++) { - if (it->IsActive()) + if (it->IsActive ()) { it->devicePtr->Receive (m_currentPkt->Copy ()); } @@ -259,13 +242,12 @@ CsmaChannel::PropagationCompleteEvent() m_state = IDLE; } - -uint32_t + uint32_t CsmaChannel::GetNumActDevices (void) { int numActDevices = 0; std::vector::iterator it; - for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + for (it = m_deviceList.begin (); it < m_deviceList.end (); it++) { if (it->active) { @@ -275,29 +257,29 @@ CsmaChannel::GetNumActDevices (void) return numActDevices; } +// // This is not the number of active devices. This is the total number // of devices even if some were detached after. -uint32_t +// + uint32_t CsmaChannel::GetNDevices (void) const { - return (m_deviceList.size()); + return (m_deviceList.size ()); } -Ptr + Ptr CsmaChannel::GetCsmaDevice (uint32_t i) const { - Ptr< CsmaNetDevice > netDevice; - - netDevice = m_deviceList[i].devicePtr; + Ptr netDevice = m_deviceList[i].devicePtr; return netDevice; } -int32_t + int32_t CsmaChannel::GetDeviceNum (Ptr device) { std::vector::iterator it; int i = 0; - for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + for (it = m_deviceList.begin (); it < m_deviceList.end (); it++) { if (it->devicePtr == device) { @@ -315,7 +297,7 @@ CsmaChannel::GetDeviceNum (Ptr device) return -1; } -bool + bool CsmaChannel::IsBusy (void) { if (m_state == IDLE) @@ -328,28 +310,45 @@ CsmaChannel::IsBusy (void) } } -DataRate + DataRate CsmaChannel::GetDataRate (void) { return m_bps; } -Time + Time CsmaChannel::GetDelay (void) { return m_delay; } -WireState -CsmaChannel::GetState(void) + WireState +CsmaChannel::GetState (void) { return m_state; } -Ptr + Ptr CsmaChannel::GetDevice (uint32_t i) const { return GetCsmaDevice (i); } +CsmaDeviceRec::CsmaDeviceRec () +{ + active = false; +} + +CsmaDeviceRec::CsmaDeviceRec (Ptr device) +{ + devicePtr = device; + active = true; +} + + bool +CsmaDeviceRec::IsActive () +{ + return active; +} + } // namespace ns3 diff --git a/src/devices/csma/csma-channel.h b/src/devices/csma/csma-channel.h index 43bd3dd57..f2771ccb9 100644 --- a/src/devices/csma/csma-channel.h +++ b/src/devices/csma/csma-channel.h @@ -73,27 +73,14 @@ class CsmaNetDevice; * flag to indicate if the channel is currently in use. It does not * take into account the distances between stations or the speed of * light to determine collisions. - * - * Each net device must query the state of the channel and make sure - * that it is IDLE before writing a packet to the channel. - * - * When the channel is instaniated, the constructor takes parameters - * for a single speed, in bits per second, and a speed-of-light delay - * time as a Time object. When a net device is attached to a channel, - * it is assigned a device ID, this is in order to facilitate the - * check that makes sure that a net device that is trying to send a - * packet to the channel is really connected to this channel - * */ class CsmaChannel : public Channel { public: static TypeId GetTypeId (void); + /** * \brief Create a CsmaChannel - * - * By default, you get a channel with the name "Csma Channel" that - * has an "infitely" fast transmission speed and zero delay. */ CsmaChannel (); @@ -104,6 +91,7 @@ public: * \return The assigned device number */ int32_t Attach (Ptr device); + /** * \brief Detach a given netdevice from this channel * @@ -116,6 +104,7 @@ public: * can't be found. */ bool Detach (Ptr device); + /** * \brief Detach a given netdevice from this channel * @@ -129,6 +118,7 @@ public: * can't be found. */ bool Detach (uint32_t deviceId); + /** * \brief Reattach a previously detached net device to the channel * @@ -143,6 +133,7 @@ public: * channel or can't be found. */ bool Reattach(uint32_t deviceId); + /** * \brief Reattach a previously detached net device to the channel * @@ -156,6 +147,7 @@ public: * channel or can't be found. */ bool Reattach(Ptr device); + /** * \brief Start transmitting a packet over the channel * @@ -171,6 +163,7 @@ public: * device is currently active. */ bool TransmitStart (Ptr p, uint32_t srcId); + /** * \brief Indicates that the net device has finished transmitting * the packet over the channel @@ -186,6 +179,7 @@ public: * completed its transmission. */ bool TransmitEnd (); + /** * \brief Indicates that the channel has finished propagating the * current packet. The channel is released and becomes free. @@ -193,7 +187,8 @@ public: * Calls the receive function of every active net device that is * attached to the channel. */ - void PropagationCompleteEvent(); + void PropagationCompleteEvent (); + /** * \return Returns the device number assigned to a net device by the * channel @@ -202,11 +197,12 @@ public: * number is needed */ int32_t GetDeviceNum (Ptr device); + /** * \return Returns the state of the channel (IDLE -- free, * TRANSMITTING -- busy, PROPAGATING - busy ) */ - WireState GetState(); + WireState GetState (); /** * \brief Indicates if the channel is busy. The channel will only @@ -215,7 +211,7 @@ public: * \return Returns true if the channel is busy and false if it is * free. */ - bool IsBusy(); + bool IsBusy (); /** * \brief Indicates if a net device is currently attached or @@ -226,19 +222,32 @@ public: * \return Returns true if the net device is attached to the * channel, false otherwise. */ - bool IsActive(uint32_t deviceId); + bool IsActive (uint32_t deviceId); + /** * \return Returns the number of net devices that are currently * attached to the channel. */ uint32_t GetNumActDevices (void); + /** * \return Returns the total number of devices including devices * that have been detached from the channel. */ virtual uint32_t GetNDevices (void) const; - virtual Ptr GetDevice (uint32_t i) const; + /** + * \return Get a NetDevice pointer to a connected network device. + * + * \param i The index of the net device. + * \return Returns the pointer to the net device that is associated + * with deviceId i. + */ + virtual Ptr GetDevice (uint32_t i) const; + + /** + * \return Get a CsmaNetDevice pointer to a connected network device. + * * \param i The deviceId of the net device for which we want the * pointer. * \return Returns the pointer to the net device that is associated @@ -246,13 +255,32 @@ public: */ Ptr GetCsmaDevice (uint32_t i) const; + /** + * Get the assigned data rate of the channel + * + * \return Returns the DataRate to be used by device transmitters. + * with deviceId i. + */ virtual DataRate GetDataRate (void); + + /** + * Get the assigned speed-of-light delay of the channel + * + * \return Returns the delay used by the channel. + */ virtual Time GetDelay (void); private: - DataRate m_bps; /// Data rate of the channel - Time m_delay; /// Delay of the channel. + /** + * The assigned data rate of the channel + */ + DataRate m_bps; + + /** + * The assigned speed-of-light delay of the channel + */ + Time m_delay; /** * List of the net devices that have been or are currently connected @@ -265,19 +293,22 @@ private: * whole list does not have to be searched when making sure that a * source is attached to a channel when it is transmitting data. */ - std::vector< CsmaDeviceRec > m_deviceList; + std::vector m_deviceList; + /** - * Packet that is currently being transmitted on the channel (or last + * The Packet that is currently being transmitted on the channel (or last * packet to have been transmitted on the channel if the channel is * free.) */ - Ptr m_currentPkt; + Ptr m_currentPkt; + /** * Device Id of the source that is currently transmitting on the * channel. Or last source to have transmitted a packet on the * channel, if the channel is currently not busy. */ uint32_t m_currentSrc; + /** * Current state of the channel */ diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index db43ff2f0..faaddc7d6 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -32,7 +32,6 @@ #include "csma-net-device.h" #include "csma-channel.h" - NS_LOG_COMPONENT_DEFINE ("CsmaNetDevice"); namespace ns3 { @@ -45,40 +44,44 @@ CsmaNetDevice::GetTypeId (void) static TypeId tid = TypeId ("ns3::CsmaNetDevice") .SetParent () .AddConstructor () - .AddAttribute ("Address", "The address of this device.", + .AddAttribute ("Address", + "The address of this device.", Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")), MakeMac48AddressAccessor (&CsmaNetDevice::m_address), MakeMac48AddressChecker ()) - .AddAttribute ("EncapsulationMode", "The mode of link-layer encapsulation to use.", + .AddAttribute ("EncapsulationMode", + "The link-layer encapsulation type to use.", EnumValue (LLC), MakeEnumAccessor (&CsmaNetDevice::m_encapMode), MakeEnumChecker (ETHERNET_V1, "EthernetV1", IP_ARP, "IpArp", RAW, "Raw", LLC, "Llc")) - .AddAttribute ("SendEnable", "should tx be enabled ?", + .AddAttribute ("SendEnable", + "Enable or disable the transmitter section of the device.", BooleanValue (true), MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable), MakeBooleanChecker ()) - .AddAttribute ("ReceiveEnable", "should rx be enabled ?", + .AddAttribute ("ReceiveEnable", + "Enable or disable the receiver section of the device.", BooleanValue (true), MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable), MakeBooleanChecker ()) - .AddAttribute ("DataRate", "XXX", - DataRateValue (DataRate (0xffffffff)), - MakeDataRateAccessor (&CsmaNetDevice::m_bps), - MakeDataRateChecker ()) - .AddAttribute ("RxErrorModel", "XXX", + .AddAttribute ("RxErrorModel", + "The receiver error model used to simulate packet loss", PointerValue (), MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel), MakePointerChecker ()) - .AddAttribute ("TxQueue", "XXX", + .AddAttribute ("TxQueue", + "A queue to use as the transmit queue in the device.", PointerValue (), MakePointerAccessor (&CsmaNetDevice::m_queue), MakePointerChecker ()) - .AddTraceSource ("Rx", "Receive MAC packet.", + .AddTraceSource ("Rx", + "Trace source to fire on reception of a MAC packet.", MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace)) - .AddTraceSource ("Drop", "Drop MAC packet.", + .AddTraceSource ("Drop", + "Trace source to fire on when a MAC packet is dropped.", MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace)) ; return tid; @@ -91,7 +94,7 @@ CsmaNetDevice::CsmaNetDevice () { NS_LOG_FUNCTION (this); m_txMachineState = READY; - m_tInterframeGap = Seconds(0); + m_tInterframeGap = Seconds (0); m_channel = 0; } @@ -101,7 +104,7 @@ CsmaNetDevice::~CsmaNetDevice() m_queue = 0; } -void + void CsmaNetDevice::DoDispose () { NS_LOG_FUNCTION_NOARGS (); @@ -110,61 +113,54 @@ CsmaNetDevice::DoDispose () NetDevice::DoDispose (); } -void + void CsmaNetDevice::SetAddress (Mac48Address self) { m_address = self; } -void + void CsmaNetDevice::SetSendEnable (bool sendEnable) { NS_LOG_FUNCTION_NOARGS (); m_sendEnable = sendEnable; } -void + void CsmaNetDevice::SetReceiveEnable (bool receiveEnable) { NS_LOG_FUNCTION_NOARGS (); m_receiveEnable = receiveEnable; } -bool + bool CsmaNetDevice::IsSendEnabled (void) { NS_LOG_FUNCTION_NOARGS (); return (m_sendEnable); } -bool + bool CsmaNetDevice::IsReceiveEnabled (void) { NS_LOG_FUNCTION_NOARGS (); return (m_receiveEnable); } -void -CsmaNetDevice::SetDataRate (DataRate bps) -{ - NS_LOG_FUNCTION_NOARGS (); - if (!m_channel || bps <= m_channel->GetDataRate ()) - { - m_bps = bps; - } -} - -void + void CsmaNetDevice::SetInterframeGap (Time t) { NS_LOG_FUNCTION_NOARGS (); m_tInterframeGap = t; } -void -CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, - uint32_t maxSlots, uint32_t ceiling, - uint32_t maxRetries) + void +CsmaNetDevice::SetBackoffParams ( + Time slotTime, + uint32_t minSlots, + uint32_t maxSlots, + uint32_t ceiling, + uint32_t maxRetries) { NS_LOG_FUNCTION_NOARGS (); m_backoff.m_slotTime = slotTime; @@ -174,32 +170,39 @@ CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, m_backoff.m_maxRetries = maxRetries; } -void -CsmaNetDevice::AddHeader (Ptr p, Mac48Address dest, - uint16_t protocolNumber) + void +CsmaNetDevice::AddHeader ( + Ptr p, + Mac48Address dest, + uint16_t protocolNumber) { NS_LOG_FUNCTION_NOARGS (); + if (m_encapMode == RAW) { return; } - EthernetHeader header (false); - EthernetTrailer trailer; + Mac48Address source = Mac48Address::ConvertFrom (GetAddress ()); - header.SetSource(source); - header.SetDestination(dest); + EthernetHeader header (false); + header.SetSource (source); + header.SetDestination (dest); + + EthernetTrailer trailer; uint16_t lengthType = 0; switch (m_encapMode) { case ETHERNET_V1: - lengthType = p->GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize(); + lengthType = p->GetSize () + header.GetSerializedSize () + + trailer.GetSerializedSize (); break; case IP_ARP: lengthType = protocolNumber; break; case LLC: { - lengthType = p->GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize(); + lengthType = p->GetSize () + header.GetSerializedSize () + + trailer.GetSerializedSize (); LlcSnapHeader llc; llc.SetType (protocolNumber); p->AddHeader (llc); @@ -208,13 +211,15 @@ CsmaNetDevice::AddHeader (Ptr p, Mac48Address dest, NS_ASSERT (false); break; } + header.SetLengthType (lengthType); - p->AddHeader(header); - trailer.CalcFcs(p); - p->AddTrailer(trailer); + p->AddHeader (header); + + trailer.CalcFcs (p); + p->AddTrailer (trailer); } -bool + bool CsmaNetDevice::ProcessHeader (Ptr p, uint16_t & param) { NS_LOG_FUNCTION_NOARGS (); @@ -222,15 +227,17 @@ CsmaNetDevice::ProcessHeader (Ptr p, uint16_t & param) { return true; } - EthernetHeader header (false); + EthernetTrailer trailer; - p->RemoveTrailer(trailer); - trailer.CheckFcs(p); - p->RemoveHeader(header); + p->RemoveTrailer (trailer); + trailer.CheckFcs (p); - if ((header.GetDestination() != GetBroadcast ()) && - (header.GetDestination() != GetAddress ())) + EthernetHeader header (false); + p->RemoveHeader (header); + + if ((header.GetDestination () != GetBroadcast ()) && + (header.GetDestination () != GetAddress ())) { return false; } @@ -239,7 +246,7 @@ CsmaNetDevice::ProcessHeader (Ptr p, uint16_t & param) { case ETHERNET_V1: case IP_ARP: - param = header.GetLengthType(); + param = header.GetLengthType (); break; case LLC: { LlcSnapHeader llc; @@ -253,7 +260,7 @@ CsmaNetDevice::ProcessHeader (Ptr p, uint16_t & param) return true; } -void + void CsmaNetDevice::TransmitStart () { NS_LOG_FUNCTION_NOARGS (); @@ -265,47 +272,58 @@ CsmaNetDevice::TransmitStart () // schedule an event that will be executed when it's time to tell the // channel that we're done wiggling the wire. // - NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF), - "Must be READY to transmit. Tx state is: " - << m_txMachineState); + NS_ASSERT_MSG ((m_txMachineState == READY) || (m_txMachineState == BACKOFF), + "Must be READY to transmit. Tx state is: " << m_txMachineState); - // Only transmit if send side of net device is enabled - if (!IsSendEnabled()) - return; +// +// Only transmit if send side of net device is enabled +// + if (IsSendEnabled () == false) + { + return; + } - if (m_channel->GetState() != IDLE) - { // Channel busy, backoff and rechedule TransmitStart() + if (m_channel->GetState () != IDLE) + { +// +// The channel is busy -- backoff and rechedule TransmitStart () +// m_txMachineState = BACKOFF; - if (m_backoff.MaxRetriesReached()) - { // Too many retries reached, abort transmission of packet - TransmitAbort(); + + if (m_backoff.MaxRetriesReached ()) + { +// +// Too many retries, abort transmission of packet +// + TransmitAbort (); } else { - m_backoff.IncrNumRetries(); - Time backoffTime = m_backoff.GetBackoffTime(); + m_backoff.IncrNumRetries (); + Time backoffTime = m_backoff.GetBackoffTime (); NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec"); - Simulator::Schedule (backoffTime, - &CsmaNetDevice::TransmitStart, - this); + Simulator::Schedule (backoffTime, &CsmaNetDevice::TransmitStart, + this); } } else { - // Channel is free, transmit packet +// +// The channel is free, transmit the packet +// m_txMachineState = BUSY; - Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt->GetSize())); + Time tEvent = Seconds (m_bps.CalculateTxTime (m_currentPkt->GetSize ())); NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec"); - Simulator::Schedule (tEvent, - &CsmaNetDevice::TransmitCompleteEvent, - this); - if (!m_channel->TransmitStart (m_currentPkt, m_deviceId)) + Simulator::Schedule (tEvent, &CsmaNetDevice::TransmitCompleteEvent, + this); + + if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false) { NS_LOG_WARN ("Channel transmit start did not work at " << tEvent.GetSeconds () << "sec"); @@ -313,28 +331,38 @@ CsmaNetDevice::TransmitStart () } else { - // Transmission success, reset backoff time parameters. - m_backoff.ResetBackoffTime(); +// +// Transmission succeeded, reset the backoff time parameters. +// + m_backoff.ResetBackoffTime (); } } } -void + void CsmaNetDevice::TransmitAbort (void) { NS_LOG_FUNCTION_NOARGS (); NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")"); - // Try to transmit a new packet +// +// Since we were transmitting a packet, that packet had better be on the +// transmit queue. +// m_currentPkt = m_queue->Dequeue (); - NS_ASSERT_MSG(m_currentPkt != 0, "IsEmpty false but no Packet on queue?"); - m_backoff.ResetBackoffTime(); + NS_ASSERT_MSG (m_currentPkt != 0, "No Packet on queue during" + "CsmaNetDevice::TransmitAbort()"); + +// +// The last one failed. Let's try to transmit the next one (if there) +// + m_backoff.ResetBackoffTime (); m_txMachineState = READY; TransmitStart (); } -void + void CsmaNetDevice::TransmitCompleteEvent (void) { NS_LOG_FUNCTION_NOARGS (); @@ -344,9 +372,8 @@ CsmaNetDevice::TransmitCompleteEvent (void) // schedule an event that will be executed when it's time to re-enable // the transmitter after the interframe gap. // - NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting"); - // Channel should be transmitting - NS_ASSERT(m_channel->GetState() == TRANSMITTING); + NS_ASSERT_MSG (m_txMachineState == BUSY, "Must be BUSY if transmitting"); + NS_ASSERT (m_channel->GetState () == TRANSMITTING); m_txMachineState = GAP; NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")"); @@ -355,12 +382,11 @@ CsmaNetDevice::TransmitCompleteEvent (void) NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec"); - Simulator::Schedule (m_tInterframeGap, - &CsmaNetDevice::TransmitReadyEvent, - this); + Simulator::Schedule (m_tInterframeGap, &CsmaNetDevice::TransmitReadyEvent, + this); } -void + void CsmaNetDevice::TransmitReadyEvent (void) { NS_LOG_FUNCTION_NOARGS (); @@ -369,18 +395,19 @@ CsmaNetDevice::TransmitReadyEvent (void) // gap has passed. If there are pending transmissions, we use this opportunity // to start the next transmit. // - NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap"); + NS_ASSERT_MSG (m_txMachineState == GAP, "Must be in interframe gap"); m_txMachineState = READY; // Get the next packet from the queue for transmitting - if (m_queue->IsEmpty()) + if (m_queue->IsEmpty ()) { return; } else { m_currentPkt = m_queue->Dequeue (); - NS_ASSERT_MSG(m_currentPkt != 0, "IsEmpty false but no Packet on queue?"); + NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitReadyEvent():" + " IsEmpty false but no Packet on queue?"); TransmitStart (); } } @@ -392,47 +419,49 @@ CsmaNetDevice::Attach (Ptr ch) m_channel = ch; - m_deviceId = m_channel->Attach(this); - m_bps = m_channel->GetDataRate (); - m_tInterframeGap = m_channel->GetDelay (); + m_deviceId = m_channel->Attach (this); - /* - * For now, this device is up whenever a channel is attached to it. - */ +// +// The channel provides us with the transmitter data rate. +// + m_bps = m_channel->GetDataRate (); + +// +// We use the Ethernet interframe gap of 96 bit times. +// + m_tInterframeGap = Seconds (m_bps.CalculateTxTime (96/8)); + +// +// This device is up whenever a channel is attached to it. +// NotifyLinkUp (); return true; } -void + void CsmaNetDevice::SetQueue (Ptr q) { NS_LOG_FUNCTION (this << q); - m_queue = q; } -void CsmaNetDevice::SetReceiveErrorModel (Ptr em) + void +CsmaNetDevice::SetReceiveErrorModel (Ptr em) { NS_LOG_FUNCTION (em); - m_receiveErrorModel = em; } -void + void CsmaNetDevice::Receive (Ptr packet) { NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC ("UID is " << packet->GetUid ()); - EthernetHeader header (false); - EthernetTrailer trailer; - Mac48Address broadcast; - Mac48Address multicast; - Mac48Address destination; - - NS_LOG_LOGIC ("UID is " << packet->GetUid()); - - // Only receive if send side of net device is enabled - if (!IsReceiveEnabled()) +// +// Only receive if the send side of net device is enabled +// + if (IsReceiveEnabled () == false) { m_dropTrace (packet); return; @@ -443,14 +472,30 @@ CsmaNetDevice::Receive (Ptr packet) if (m_encapMode == RAW) { m_rxCallback (this, packet, 0, GetBroadcast ()); - m_dropTrace (packet); return; } - packet->RemoveTrailer(trailer); - trailer.CheckFcs(packet); - packet->RemoveHeader(header); + EthernetTrailer trailer; + packet->RemoveTrailer (trailer); + trailer.CheckFcs (packet); + + EthernetHeader header (false); + packet->RemoveHeader (header); + + NS_LOG_LOGIC ("Pkt source is " << header.GetSource ()); NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ()); + +// +// We never forward up packets that we sent. Real devices don't do this since +// their receivers are disabled during send, so we don't. Drop the packet +// silently (no tracing) since it would really never get here in a real device. +// + if (header.GetSource () == GetAddress ()) + { + NS_LOG_LOGIC ("Dropping packet sourced by this device"); + return; + } + // // An IP host group address is mapped to an Ethernet multicast address // by placing the low-order 23-bits of the IP address into the low-order @@ -468,9 +513,9 @@ CsmaNetDevice::Receive (Ptr packet) mcBuf[5] = 0; mcDest.CopyFrom (mcBuf); - multicast = Mac48Address::ConvertFrom (GetMulticast ()); - broadcast = Mac48Address::ConvertFrom (GetBroadcast ()); - destination = Mac48Address::ConvertFrom (GetAddress ()); + Mac48Address multicast = Mac48Address::ConvertFrom (GetMulticast ()); + Mac48Address broadcast = Mac48Address::ConvertFrom (GetBroadcast ()); + Mac48Address destination = Mac48Address::ConvertFrom (GetAddress ()); if ((header.GetDestination () != broadcast) && (mcDest != multicast) && @@ -485,13 +530,12 @@ CsmaNetDevice::Receive (Ptr packet) { NS_LOG_LOGIC ("Dropping pkt due to error model "); m_dropTrace (packet); - // Do not forward up; let this packet go } else { // -// protocol must be initialized to avoid a compiler warning in the RAW -// case that breaks the optimized build. +// variable must be initialized to avoid a compiler warning in the +// RAW case that breaks the optimized build. // uint16_t protocol = 0; @@ -499,7 +543,7 @@ CsmaNetDevice::Receive (Ptr packet) { case ETHERNET_V1: case IP_ARP: - protocol = header.GetLengthType(); + protocol = header.GetLengthType (); break; case LLC: { @@ -516,95 +560,109 @@ CsmaNetDevice::Receive (Ptr packet) } } -Ptr -CsmaNetDevice::GetQueue(void) const + Ptr +CsmaNetDevice::GetQueue (void) const { NS_LOG_FUNCTION_NOARGS (); return m_queue; } -void + void CsmaNetDevice::NotifyLinkUp (void) { m_linkUp = true; - if (!m_linkChangeCallback.IsNull ()) + if (m_linkChangeCallback.IsNull () == false) { m_linkChangeCallback (); } } -void -CsmaNetDevice::SetName(const std::string name) + void +CsmaNetDevice::SetName (const std::string name) { m_name = name; } -std::string -CsmaNetDevice::GetName(void) const + + std::string +CsmaNetDevice::GetName (void) const { return m_name; } -void -CsmaNetDevice::SetIfIndex(const uint32_t index) + + void +CsmaNetDevice::SetIfIndex (const uint32_t index) { m_ifIndex = index; } -uint32_t -CsmaNetDevice::GetIfIndex(void) const + + uint32_t +CsmaNetDevice::GetIfIndex (void) const { return m_ifIndex; } -Ptr + + Ptr CsmaNetDevice::GetChannel (void) const { return m_channel; } -Address + + Address CsmaNetDevice::GetAddress (void) const { return m_address; } -bool + + bool CsmaNetDevice::SetMtu (const uint16_t mtu) { m_mtu = mtu; return true; } -uint16_t + + uint16_t CsmaNetDevice::GetMtu (void) const { return m_mtu; } -bool + + bool CsmaNetDevice::IsLinkUp (void) const { return m_linkUp; } -void + + void CsmaNetDevice::SetLinkChangeCallback (Callback callback) { m_linkChangeCallback = callback; } -bool + + bool CsmaNetDevice::IsBroadcast (void) const { return true; } -Address + + Address CsmaNetDevice::GetBroadcast (void) const { return Mac48Address ("ff:ff:ff:ff:ff:ff"); } -bool + + bool CsmaNetDevice::IsMulticast (void) const { return true; } -Address + + Address CsmaNetDevice::GetMulticast (void) const { return Mac48Address ("01:00:5e:00:00:00"); } -Address + + Address CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const { NS_LOG_FUNCTION (this << multicastGroup); @@ -655,13 +713,18 @@ CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const return etherAddr; } -bool + + bool CsmaNetDevice::IsPointToPoint (void) const { return false; } -bool -CsmaNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNumber) + + bool +CsmaNetDevice::Send( + Ptr packet, + const Address& dest, + uint16_t protocolNumber) { NS_LOG_FUNCTION_NOARGS (); NS_LOG_LOGIC ("p=" << packet); @@ -669,43 +732,56 @@ CsmaNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNu NS_ASSERT (IsLinkUp ()); - // Only transmit if send side of net device is enabled - if (!IsSendEnabled()) - return false; - - Mac48Address destination = Mac48Address::ConvertFrom (dest); - AddHeader(packet, destination, protocolNumber); - - // Place the packet to be sent on the send queue - if (m_queue->Enqueue(packet) == false ) +// +// Only transmit if send side of net device is enabled +// + if (IsSendEnabled () == false) { return false; } - // If the device is idle, we need to start a transmission. Otherwise, - // the transmission will be started when the current packet finished - // transmission (see TransmitCompleteEvent) + + Mac48Address destination = Mac48Address::ConvertFrom (dest); + AddHeader (packet, destination, protocolNumber); + +// +// Place the packet to be sent on the send queue +// + if (m_queue->Enqueue(packet) == false) + { + return false; + } +// +// If the device is idle, we need to start a transmission. Otherwise, +// the transmission will be started when the current packet finished +// transmission (see TransmitCompleteEvent) +// if (m_txMachineState == READY) { - // Store the next packet to be transmitted +// +// The next packet to be transmitted goes in m_currentPkt +// m_currentPkt = m_queue->Dequeue (); if (m_currentPkt != 0) { - TransmitStart(); + TransmitStart (); } } return true; } -Ptr + + Ptr CsmaNetDevice::GetNode (void) const { return m_node; } -void + + void CsmaNetDevice::SetNode (Ptr node) { m_node = node; } -bool + + bool CsmaNetDevice::NeedsArp (void) const { if ((m_encapMode == IP_ARP) || (m_encapMode == LLC)) @@ -717,7 +793,8 @@ CsmaNetDevice::NeedsArp (void) const return false; } } -void + + void CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) { m_rxCallback = cb; diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index ac149bf66..440206d23 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Emmanuelle Laprise ch); + /** * Attach a queue to the CsmaNetDevice. * - * The CsmaNetDevice "owns" a queue. This queue is created by the - * CsmaTopology object and implements a queueing method such as - * DropTail or RED. The CsmaNetDevice assumes ownership of this - * queue and must delete it when the device is destroyed. + * The CsmaNetDevice "owns" a queue. This queue may be set by higher + * level topology objects to implement a particular queueing method such as + * DropTail or RED. * - * @see CsmaTopology::AddCsmaLink () * @see Queue * @see DropTailQueue - * \param queue a pointer to the queue for which object is assuming - * ownership. + * \param queue a Ptr to the queue for being assigned to the device. */ void SetQueue (Ptr queue); + /** * Attach a receive ErrorModel to the CsmaNetDevice. * * The CsmaNetDevice may optionally include an ErrorModel in - * the packet receive chain. + * the packet receive chain to simulate data errors in during transmission. * * @see ErrorModel * @param em a pointer to the ErrorModel */ - void SetReceiveErrorModel(Ptr em); + void SetReceiveErrorModel (Ptr em); + /** * Receive a packet from a connected CsmaChannel. * @@ -174,20 +161,48 @@ enum CsmaEncapsulationMode { */ void Receive (Ptr p); + /** + * Is the send side of the network device enabled? + * + * \returns True if the send side is enabled, otherwise false. + */ bool IsSendEnabled (void); + + /** + * Enable or disable the send side of the network device. + * + * \param enable Enable the send side if true, otherwise disable. + */ + void SetSendEnable (bool enable); + + /** + * Is the receive side of the network device enabled? + * + * \returns True if the receiver side is enabled, otherwise false. + */ bool IsReceiveEnabled (void); - void SetSendEnable (bool); - void SetReceiveEnable (bool); + /** + * Enable or disable the receive side of the network device. + * + * \param enable Enable the receive side if true, otherwise disable. + */ + void SetReceiveEnable (bool enable); - void SetAddress (Mac48Address self); + /** + * Set the MAC address of the the network device. + * + * \param addr The Mac48Address to use as the address of the device. + */ + void SetAddress (Mac48Address addr); - - // inherited from NetDevice base class. - virtual void SetName(const std::string name); - virtual std::string GetName(void) const; - virtual void SetIfIndex(const uint32_t index); - virtual uint32_t GetIfIndex(void) const; +// +// The following methods are inherited from NetDevice base class. +// + virtual void SetName (const std::string name); + virtual std::string GetName (void) const; + virtual void SetIfIndex (const uint32_t index); + virtual uint32_t GetIfIndex (void) const; virtual Ptr GetChannel (void) const; virtual Address GetAddress (void) const; virtual bool SetMtu (const uint16_t mtu); @@ -198,6 +213,7 @@ enum CsmaEncapsulationMode { virtual Address GetBroadcast (void) const; virtual bool IsMulticast (void) const; virtual Address GetMulticast (void) const; + /** * @brief Make and return a MAC multicast address using the provided * multicast group @@ -221,14 +237,54 @@ enum CsmaEncapsulationMode { * @see Address */ virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; + + /** + * Is this a point to point link? + * \returns false. + */ virtual bool IsPointToPoint (void) const; - virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + + /** + * Start sending a packet down the channel. + */ + virtual bool Send (Ptr packet, const Address& dest, + uint16_t protocolNumber); + + /** + * Get the node to which this device is attached. + * + * \returns Ptr to the Node to which the device is attached. + */ virtual Ptr GetNode (void) const; + + /** + * Set the node to which this device is being attached. + * + * \param node Ptr to the Node to which the device is being attached. + */ virtual void SetNode (Ptr node); + + /** + * Does this device need to use the address resolution protocol? + * + * \returns True if the encapsulation mode is set to a value that requires + * ARP (IP_ARP or LLC). + */ virtual bool NeedsArp (void) const; + + /** + * Set the callback to be used to notify higher layers when a packet has been + * received. + * + * \param cb The callback. + */ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); protected: + /** + * Perform any object release functionality required to break reference + * cycles in reference counted objects held by the device. + */ virtual void DoDispose (void); /** @@ -240,6 +296,7 @@ protected: * \return a pointer to the queue. */ Ptr GetQueue (void) const; + /** * Adds the necessary headers and trailers to a packet of data in order to * respect the packet type @@ -249,8 +306,8 @@ protected: * \param protocolNumber In some protocols, identifies the type of * payload contained in this packet. */ - void AddHeader (Ptr p, Mac48Address dest, - uint16_t protocolNumber); + void AddHeader (Ptr p, Mac48Address dest, uint16_t protocolNumber); + /** * Removes, from a packet of data, all headers and trailers that * relate to the packet type @@ -264,11 +321,21 @@ protected: bool ProcessHeader (Ptr p, uint16_t & param); private: - // disable copy constructor and operator = - CsmaNetDevice &operator = (const CsmaNetDevice &o); - CsmaNetDevice (const CsmaNetDevice &o); /** - * Initializes variablea when construction object. + * Operator = is declared but not implemented. This disables the assigment + * operator for CsmaNetDevice objects. + + */ + CsmaNetDevice &operator = (const CsmaNetDevice &o); + + /** + * Copy constructor is declared but not implemented. This disables the + * copy constructor for CsmaNetDevice objects. + */ + CsmaNetDevice (const CsmaNetDevice &o); + + /** + * Initialization function used during object construction. */ void Init (bool sendEnable, bool receiveEnable); @@ -277,35 +344,38 @@ private: * * The TransmitStart method is the method that is used internally in * the CsmaNetDevice to begin the process of sending a packet - * out on the channel. The corresponding method is called on the + * out on the channel. A corresponding method is called on the * channel to let it know that the physical device this class - * represents has virually started sending signals, this causes the - * channel to become busy. An event is scheduled for the time at - * which the bits have been completely transmitted. If the channel - * is busy, the method reschedules itself for a later time (within - * the backoff period) + * represents has actually started sending signals, this causes the + * channel to enter the BUSY state. An event is scheduled for the time at + * which the bits have been completely transmitted. + * + * If the channel is found to be BUSY, this method reschedules itself for + * execution at a later time (within the backoff period). * * @see CsmaChannel::TransmitStart () * @see TransmitCompleteEvent () */ void TransmitStart (); + /** * Stop Sending a Packet Down the Wire and Begin the Interframe Gap. * * The TransmitCompleteEvent method is used internally to finish the process * of sending a packet out on the channel. During execution of this method * the TransmitEnd method is called on the channel to let it know that the - * physical device this class represents has virually finished sending + * physical device this class represents has finished sending simulated * signals. The channel uses this event to begin its speed of light delay - * timer after which it notifies the Net Device at the other end of the - * link that the bits have arrived. During this method, the net device - * also schedules the TransmitReadyEvent at which time the transmitter - * becomes ready to send the next packet. + * timer after which it notifies the Net Device(s) at the other end of the + * link that new bits have arrived (it delivers the Packet). During this + * method, the net device also schedules the TransmitReadyEvent at which + * time the transmitter becomes ready to send the next packet. * * @see CsmaChannel::TransmitEnd () * @see TransmitReadyEvent () */ void TransmitCompleteEvent (void); + /** * Cause the Transmitter to Become Ready to Send Another Packet. * @@ -328,9 +398,12 @@ private: * If the net device has tried to transmit a packet for more times * than the maximum allowed number of retries (channel always busy) * then the packet is dropped. - * */ void TransmitAbort (void); + + /** + * Notify any interested parties that the link has come up. + */ void NotifyLinkUp (void); /** @@ -344,10 +417,12 @@ private: * Enable net device to send packets. True by default */ bool m_sendEnable; + /** * Enable net device to receive packets. True by default */ bool m_receiveEnable; + /** * Enumeration of the states of the transmit machine of the net device. */ @@ -358,6 +433,7 @@ private: GAP, /**< The transmitter is in the interframe gap time */ BACKOFF /**< The transmitter is waiting for the channel to be free */ }; + /** * The state of the Net Device transmit state machine. * @see TxMachineState @@ -370,36 +446,42 @@ private: * function. */ CsmaEncapsulationMode m_encapMode; + /** * The data rate that the Net Device uses to simulate packet transmission * timing. * @see class DataRate */ DataRate m_bps; + /** - * The interframe gap that the Net Device uses to throttle packet + * The interframe gap that the Net Device uses insert time between packet * transmission * @see class Time */ Time m_tInterframeGap; + /** * Holds the backoff parameters and is used to calculate the next * backoff time to use when the channel is busy and the net device * is ready to transmit */ Backoff m_backoff; + /** * Next packet that will be transmitted (if transmitter is not * currently transmitting) or packet that is currently being * transmitted. */ Ptr m_currentPkt; + /** * The CsmaChannel to which this CsmaNetDevice has been * attached. * @see class CsmaChannel */ Ptr m_channel; + /** * The Queue which this CsmaNetDevice uses as a packet source. * Management of this Queue has been delegated to the CsmaNetDevice @@ -415,26 +497,65 @@ private: Ptr m_receiveErrorModel; /** - * NOT TESTED * The trace source for the packet reception events that the device can * fire. * * @see class CallBackTraceSource */ TracedCallback > m_rxTrace; + + /** + * The trace source for the packet drop events that the device can + * fire. + * + * @see class CallBackTraceSource + */ TracedCallback > m_dropTrace; + /** + * The Node to which this device is attached. + */ Ptr m_node; + + /** + * The MAC address which has been assigned to this device. + */ Mac48Address m_address; + + /** + * The callback used to notify higher layers that a packet has been received. + */ NetDevice::ReceiveCallback m_rxCallback; + + /** + * The interface index (really net evice index) that has been assigned to + * this network device. + */ uint32_t m_ifIndex; + + /** + * The human readable name of this device. + */ std::string m_name; + + /** + * Flag indicating whether or not the link is up. In this case, + * whether or not the device is connected to a channel. + */ bool m_linkUp; + + /** + * Callback to fire if the link changes state (up or down). + */ Callback m_linkChangeCallback; + + /** + * The maximum transmission unit (biggest packet) allowed to be sent or + * received by this network device. + */ uint16_t m_mtu; }; }; // namespace ns3 #endif // CSMA_NET_DEVICE_H - diff --git a/src/devices/csma/csma.h b/src/devices/csma/csma.h index d8d793201..3aa899198 100644 --- a/src/devices/csma/csma.h +++ b/src/devices/csma/csma.h @@ -22,8 +22,14 @@ * * The class ns3::CsmaChannel models the actual transmission medium. * There is no fixed limit for the number of devices connected to the channel. - * The ns3::CsmaChannel models a bitrate and a speed-of-light delay which can - * be accessed via the attributes "BitRate" and "Delay" respectively. + * The ns3::CsmaChannel models a data rate and a speed-of-light delay which can + * be accessed via the attributes "DataRate" and "Delay" respectively. + * The data rate provided to the channel is used to set the data rates + * used by the transmitter sections of the CSMA devices connected to the + * channel. There is no way to independently set data rates in the + * devices. Since the data rate is only used to calculate a delay time, there + * is no limitation (other than by the data type holding the value) on the + * speed at which CSMA channels and devices can operate. * * The ns3::CsmaChannel has three states, IDLE, TRANSMITTING and PROPAGATING. * These three states are "seen" instantaneously by all devices on the channel. @@ -62,7 +68,13 @@ * * The ns3::CsmaChannel models a broadcast medium so the packet is delivered * to all of the devices on the channel (including the source) at the end of - * the propagation time. + * the propagation time. It is the responsibility of the sending device to + * determine whether or not it receives a packet broadcast over the channel. + * + * The ns3::CsmaChannel provides following Attributes: + * + * - DataRate: The bitrate for packet transmission on connected devices; + * - Delay: The speed of light transmission delay for the channel. * * \subsection CSMA Net Device Model * @@ -70,7 +82,6 @@ * ns3::CsmaNetDevice provides following Attributes: * * - Address: The ns3::Mac48Address of the device; - * - DataRate: The data rate of the device; * - SendEnable: Enable packet transmission if true; * - ReceiveEnable: Enable packet reception if true; * - EncapsulationMode: Type of link layer encapsulation to use; diff --git a/src/devices/point-to-point/point-to-point.h b/src/devices/point-to-point/point-to-point.h index 896dbda33..3f9cf4178 100644 --- a/src/devices/point-to-point/point-to-point.h +++ b/src/devices/point-to-point/point-to-point.h @@ -30,6 +30,19 @@ * - Rx: A trace source for received packets; * - Drop: A trace source for dropped packets. * + * The ns3::PointToPointNetDevice models a transmitter section that puts bits + * on a corresponding channel "wire." THe DataRate attribute specifies the + * number of bits per second that the device will simulate sending over the + * channel. In reality no bits are sent, but an event is scheduled for an + * elapsed time consistent with the number of bits in each packet and the + * specified DataRate. The implication here is that the receiving device + * models a receiver section that can receive any any data rate. Therefore + * there is no need, nor way to set a receive data rate in this model. By + * setting the DataRate on the transmitter of both devices connected to a + * given ns3::PointToPointChannel one can model a symmetric channel; or by + * setting different DataRates one can model an asymmetric channel (e.g., + * ADSL). + * * The ns3::PointToPointNetDevice supports the assignment of a "receive error * model." This is an ns3::ErrorModel object that is used to simulate data * corruption on the link. @@ -40,6 +53,7 @@ * beyond the eight bits per byte of the packet sent. That is, we do not * model Flag Sequences, Frame Check Sequences nor do we "escape" any data. * - * The ns3::PointToPointChannel does model a speed-of-light or transmission - * delay which can be set and get via the attribute "Delay." + * The ns3::PointToPointNetChannel provides following Attributes: + * + * - Delay: The speed of light transmission delay for the channel. */ diff --git a/src/helper/wscript b/src/helper/wscript index c1eb82b3f..2ebd99099 100644 --- a/src/helper/wscript +++ b/src/helper/wscript @@ -1,7 +1,7 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def build(bld): - helper = bld.create_ns3_module('helper', ['internet-node', 'wifi', 'point-to-point', 'csma', 'olsr', 'global-routing', 'onoff', 'packet-sink', 'udp-echo']) + helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'olsr', 'global-routing', 'onoff', 'packet-sink', 'udp-echo']) helper.source = [ 'node-container.cc', 'net-device-container.cc', diff --git a/src/internet-node/arp-cache.cc b/src/internet-stack/arp-cache.cc similarity index 100% rename from src/internet-node/arp-cache.cc rename to src/internet-stack/arp-cache.cc diff --git a/src/internet-node/arp-cache.h b/src/internet-stack/arp-cache.h similarity index 100% rename from src/internet-node/arp-cache.h rename to src/internet-stack/arp-cache.h diff --git a/src/internet-node/arp-header.cc b/src/internet-stack/arp-header.cc similarity index 100% rename from src/internet-node/arp-header.cc rename to src/internet-stack/arp-header.cc diff --git a/src/internet-node/arp-header.h b/src/internet-stack/arp-header.h similarity index 100% rename from src/internet-node/arp-header.h rename to src/internet-stack/arp-header.h diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-stack/arp-ipv4-interface.cc similarity index 100% rename from src/internet-node/arp-ipv4-interface.cc rename to src/internet-stack/arp-ipv4-interface.cc diff --git a/src/internet-node/arp-ipv4-interface.h b/src/internet-stack/arp-ipv4-interface.h similarity index 100% rename from src/internet-node/arp-ipv4-interface.h rename to src/internet-stack/arp-ipv4-interface.h diff --git a/src/internet-node/arp-l3-protocol.cc b/src/internet-stack/arp-l3-protocol.cc similarity index 100% rename from src/internet-node/arp-l3-protocol.cc rename to src/internet-stack/arp-l3-protocol.cc diff --git a/src/internet-node/arp-l3-protocol.h b/src/internet-stack/arp-l3-protocol.h similarity index 100% rename from src/internet-node/arp-l3-protocol.h rename to src/internet-stack/arp-l3-protocol.h diff --git a/src/internet-node/internet-stack.cc b/src/internet-stack/internet-stack.cc similarity index 100% rename from src/internet-node/internet-stack.cc rename to src/internet-stack/internet-stack.cc diff --git a/src/internet-node/internet-stack.h b/src/internet-stack/internet-stack.h similarity index 100% rename from src/internet-node/internet-stack.h rename to src/internet-stack/internet-stack.h diff --git a/src/internet-node/ipv4-checksum.cc b/src/internet-stack/ipv4-checksum.cc similarity index 100% rename from src/internet-node/ipv4-checksum.cc rename to src/internet-stack/ipv4-checksum.cc diff --git a/src/internet-node/ipv4-checksum.h b/src/internet-stack/ipv4-checksum.h similarity index 100% rename from src/internet-node/ipv4-checksum.h rename to src/internet-stack/ipv4-checksum.h diff --git a/src/internet-node/ipv4-end-point-demux.cc b/src/internet-stack/ipv4-end-point-demux.cc similarity index 100% rename from src/internet-node/ipv4-end-point-demux.cc rename to src/internet-stack/ipv4-end-point-demux.cc diff --git a/src/internet-node/ipv4-end-point-demux.h b/src/internet-stack/ipv4-end-point-demux.h similarity index 100% rename from src/internet-node/ipv4-end-point-demux.h rename to src/internet-stack/ipv4-end-point-demux.h diff --git a/src/internet-node/ipv4-end-point.cc b/src/internet-stack/ipv4-end-point.cc similarity index 100% rename from src/internet-node/ipv4-end-point.cc rename to src/internet-stack/ipv4-end-point.cc diff --git a/src/internet-node/ipv4-end-point.h b/src/internet-stack/ipv4-end-point.h similarity index 100% rename from src/internet-node/ipv4-end-point.h rename to src/internet-stack/ipv4-end-point.h diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-stack/ipv4-impl.cc similarity index 100% rename from src/internet-node/ipv4-impl.cc rename to src/internet-stack/ipv4-impl.cc diff --git a/src/internet-node/ipv4-impl.h b/src/internet-stack/ipv4-impl.h similarity index 100% rename from src/internet-node/ipv4-impl.h rename to src/internet-stack/ipv4-impl.h diff --git a/src/internet-node/ipv4-interface.cc b/src/internet-stack/ipv4-interface.cc similarity index 100% rename from src/internet-node/ipv4-interface.cc rename to src/internet-stack/ipv4-interface.cc diff --git a/src/internet-node/ipv4-interface.h b/src/internet-stack/ipv4-interface.h similarity index 100% rename from src/internet-node/ipv4-interface.h rename to src/internet-stack/ipv4-interface.h diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-stack/ipv4-l3-protocol.cc similarity index 100% rename from src/internet-node/ipv4-l3-protocol.cc rename to src/internet-stack/ipv4-l3-protocol.cc diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-stack/ipv4-l3-protocol.h similarity index 100% rename from src/internet-node/ipv4-l3-protocol.h rename to src/internet-stack/ipv4-l3-protocol.h diff --git a/src/internet-node/ipv4-l4-demux.cc b/src/internet-stack/ipv4-l4-demux.cc similarity index 100% rename from src/internet-node/ipv4-l4-demux.cc rename to src/internet-stack/ipv4-l4-demux.cc diff --git a/src/internet-node/ipv4-l4-demux.h b/src/internet-stack/ipv4-l4-demux.h similarity index 100% rename from src/internet-node/ipv4-l4-demux.h rename to src/internet-stack/ipv4-l4-demux.h diff --git a/src/internet-node/ipv4-l4-protocol.cc b/src/internet-stack/ipv4-l4-protocol.cc similarity index 100% rename from src/internet-node/ipv4-l4-protocol.cc rename to src/internet-stack/ipv4-l4-protocol.cc diff --git a/src/internet-node/ipv4-l4-protocol.h b/src/internet-stack/ipv4-l4-protocol.h similarity index 100% rename from src/internet-node/ipv4-l4-protocol.h rename to src/internet-stack/ipv4-l4-protocol.h diff --git a/src/internet-node/ipv4-loopback-interface.cc b/src/internet-stack/ipv4-loopback-interface.cc similarity index 100% rename from src/internet-node/ipv4-loopback-interface.cc rename to src/internet-stack/ipv4-loopback-interface.cc diff --git a/src/internet-node/ipv4-loopback-interface.h b/src/internet-stack/ipv4-loopback-interface.h similarity index 100% rename from src/internet-node/ipv4-loopback-interface.h rename to src/internet-stack/ipv4-loopback-interface.h diff --git a/src/internet-node/ipv4-static-routing.cc b/src/internet-stack/ipv4-static-routing.cc similarity index 100% rename from src/internet-node/ipv4-static-routing.cc rename to src/internet-stack/ipv4-static-routing.cc diff --git a/src/internet-node/ipv4-static-routing.h b/src/internet-stack/ipv4-static-routing.h similarity index 100% rename from src/internet-node/ipv4-static-routing.h rename to src/internet-stack/ipv4-static-routing.h diff --git a/src/internet-node/pending-data.cc b/src/internet-stack/pending-data.cc similarity index 59% rename from src/internet-node/pending-data.cc rename to src/internet-stack/pending-data.cc index 650c9c6c8..bbfde0d77 100644 --- a/src/internet-node/pending-data.cc +++ b/src/internet-stack/pending-data.cc @@ -29,26 +29,10 @@ #include #include "pending-data.h" -#include "ns3/packet.h" #include "ns3/fatal-error.h" namespace ns3 { -namespace Serializable -{ - uint8_t* GetSize (uint8_t* b, uint32_t& r, uint32_t& s) - { // Get the size of the next size field - if (sizeof(s) > r) - { - NS_FATAL_ERROR ("Serialization error; remaining " << r - << " thissize " << sizeof(s) << std::endl); - } - r -= sizeof (s); // Reduce remaining for next time - memcpy (&s, b, sizeof(s)); - return b + sizeof (s); - } -} - PendingData::PendingData () : size (0), data (0), msgSize (0), responseSize (0) { @@ -56,37 +40,28 @@ PendingData::PendingData () : size (0), data (0), PendingData::PendingData (uint32_t s, uint8_t* d, uint32_t msg, uint32_t resp) : size (s), data (0), msgSize (msg), responseSize (resp) -{ // Make a copy of the data +{ if (d) { - data = new uint8_t[s]; - memcpy (data, d, s); + data.push_back (Create (d, size)); } } PendingData::PendingData(const std::string& s) - : size (s.length () + 1), data ((uint8_t*)strdup(s.c_str ())), + : size (s.length () + 1), data (0), msgSize (0), responseSize (0) { + data.push_back (Create ((uint8_t*)s.c_str(), size)); } PendingData::PendingData(const PendingData& c) - : size (c.Size ()), data (0), + : size (c.Size ()), data (c.data), msgSize (c.msgSize), responseSize (c.responseSize) -{ // Copy constructor - if (c.Contents()) - { // Has data - data = new uint8_t[Size ()]; - memcpy(data, c.Contents (), Size ()); - } +{ } PendingData::~PendingData() -{ // destructor - if (data) - { - delete [] data; - } +{ } PendingData* PendingData::Copy () const @@ -106,62 +81,27 @@ PendingData* PendingData::CopySD (uint32_t s, uint8_t* d) void PendingData::Clear () { // Remove all pending data - if (data) - { - delete [] data; // Free memory if used - } - data = 0; + data.clear(); size = 0; } void PendingData::Add (uint32_t s, const uint8_t* d) { - if (data) - { // PendingData exists, realloc and copy - uint8_t* n = new uint8_t[Size () + s]; - memcpy(n, data, Size ()); - if (d) - { // New data specified - memcpy(n + Size (), d, s); // Append the new data - } - else - { - memset(n + Size (), 0, s); // Apend zeros - } - delete [] data; // Delete the old data - data = n; // Points to new one - } + if (d == 0) + { + data.push_back(Create (d,s)); + } else - { // No existing data, see if new data - if (d) - { - data = new uint8_t[s]; - memcpy (data, d, s); - } - } + { + data.push_back(Create (s)); + } size += s; } -void PendingData::Remove(uint32_t s) +void PendingData::Add (Ptr p) { - uint32_t r = s > Size () ? Size () : s; - - size -= r; // Reduce size from current - if (data) - { // data actually exists, realloc and copy - if (size) - { - uint8_t* d = new uint8_t[Size ()]; - memcpy(d, data, Size ()); - delete [] data; - data = d; - } - else - { // Zero size, so don't need the data anymore - delete [] data; - data = NULL; - } - } + data.push_back(p); + size += p->GetSize(); } uint32_t PendingData::SizeFromSeq (const SequenceNumber& f, const SequenceNumber& o) @@ -193,12 +133,61 @@ Ptr PendingData::CopyFromOffset (uint32_t s, uint32_t o) { return 0; // No data requested } - if (data) + if (data.size() != 0) { // Actual data exists, make copy and return it - return Create (data+o, s1); + uint32_t count = 0; + std::vector >::size_type begin = 0; + bool beginFound = false; + std::vector >::size_type end = 0; + Ptr outPacket; + Ptr endFragment; + for (std::vector >::size_type i=0;iGetSize(); + if (!beginFound) + { + if (count > o) + { + if (count >= o + s1) //then just copy within this packet + { + Ptr toFragment = data[i]; + uint32_t packetStart = count - toFragment->GetSize(); + uint32_t packetOffset = o - packetStart; + outPacket = toFragment->CreateFragment (packetOffset, s1); + return outPacket; + } + begin = i; + beginFound = true; + Ptr toFragment = data[begin]; + uint32_t packetStart = count - toFragment->GetSize(); + uint32_t packetOffset = o - packetStart; + uint32_t fragmentLength = count - o; + outPacket = toFragment->CreateFragment (packetOffset, fragmentLength); + } + } + else + { + if (count >= o + s1) + { + end = i; + Ptr toFragment = data[end]; + uint32_t packetStart = count - toFragment->GetSize(); + uint32_t fragmentLength = o + s1 - packetStart; + endFragment = toFragment->CreateFragment(0, fragmentLength); + break; + } + } + } + for (std::vector >::size_type i=begin+1;iAddAtEnd (data[i]); + } + outPacket->AddAtEnd(endFragment); + NS_ASSERT(outPacket->GetSize() == s1); + return outPacket; } else - { // No actual data, just return non-data pdu of correct size + { // No actual data, just return dummy-data packet of correct size return Create (s1); } } diff --git a/src/internet-node/pending-data.h b/src/internet-stack/pending-data.h similarity index 94% rename from src/internet-node/pending-data.h rename to src/internet-stack/pending-data.h index fc7ccc621..7cdbe6495 100644 --- a/src/internet-node/pending-data.h +++ b/src/internet-stack/pending-data.h @@ -24,6 +24,7 @@ #ifndef __datapdu_h__ #define __datapdu_h__ +#include "ns3/packet.h" #include "pending-data.h" #include "sequence-number.h" @@ -47,7 +48,7 @@ public: uint8_t* Construct (uint8_t*, uint32_t&); // Construct from buffer virtual void Clear ();// Remove all associated data virtual void Add (uint32_t s, const uint8_t* d = 0);// Add some data to end - virtual void Remove (uint32_t); // Remove data from head + virtual void Add (Ptr p); // Inquire available data from (f,o) sequence pair virtual uint32_t SizeFromSeq (const SequenceNumber&, const SequenceNumber&); // Inquire available data from offset @@ -60,10 +61,9 @@ public: PendingData* Copy () const; // Create a copy of this header PendingData* CopyS (uint32_t); // Copy with new size PendingData* CopySD (uint32_t, uint8_t*); // Copy with new size, new data - virtual uint8_t* Contents() const { return data;} public: uint32_t size; // Number of data bytes - uint8_t* data; // Corresponding data (may be null) + std::vector > data; // Corresponding data (may be null) // The next two fields allow simulated applications to exchange some info uint32_t msgSize; // Total size of message uint32_t responseSize;// Size of response requested diff --git a/src/internet-node/rtt-estimator.cc b/src/internet-stack/rtt-estimator.cc similarity index 100% rename from src/internet-node/rtt-estimator.cc rename to src/internet-stack/rtt-estimator.cc diff --git a/src/internet-node/rtt-estimator.h b/src/internet-stack/rtt-estimator.h similarity index 100% rename from src/internet-node/rtt-estimator.h rename to src/internet-stack/rtt-estimator.h diff --git a/src/internet-node/sequence-number.cc b/src/internet-stack/sequence-number.cc similarity index 100% rename from src/internet-node/sequence-number.cc rename to src/internet-stack/sequence-number.cc diff --git a/src/internet-node/sequence-number.h b/src/internet-stack/sequence-number.h similarity index 100% rename from src/internet-node/sequence-number.h rename to src/internet-stack/sequence-number.h diff --git a/src/internet-node/sgi-hashmap.h b/src/internet-stack/sgi-hashmap.h similarity index 100% rename from src/internet-node/sgi-hashmap.h rename to src/internet-stack/sgi-hashmap.h diff --git a/src/internet-node/tcp-header.cc b/src/internet-stack/tcp-header.cc similarity index 100% rename from src/internet-node/tcp-header.cc rename to src/internet-stack/tcp-header.cc diff --git a/src/internet-node/tcp-header.h b/src/internet-stack/tcp-header.h similarity index 100% rename from src/internet-node/tcp-header.h rename to src/internet-stack/tcp-header.h diff --git a/src/internet-node/tcp-l4-protocol.cc b/src/internet-stack/tcp-l4-protocol.cc similarity index 100% rename from src/internet-node/tcp-l4-protocol.cc rename to src/internet-stack/tcp-l4-protocol.cc diff --git a/src/internet-node/tcp-l4-protocol.h b/src/internet-stack/tcp-l4-protocol.h similarity index 100% rename from src/internet-node/tcp-l4-protocol.h rename to src/internet-stack/tcp-l4-protocol.h diff --git a/src/internet-node/tcp-socket-factory-impl.cc b/src/internet-stack/tcp-socket-factory-impl.cc similarity index 100% rename from src/internet-node/tcp-socket-factory-impl.cc rename to src/internet-stack/tcp-socket-factory-impl.cc diff --git a/src/internet-node/tcp-socket-factory-impl.h b/src/internet-stack/tcp-socket-factory-impl.h similarity index 100% rename from src/internet-node/tcp-socket-factory-impl.h rename to src/internet-stack/tcp-socket-factory-impl.h diff --git a/src/internet-node/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc similarity index 90% rename from src/internet-node/tcp-socket-impl.cc rename to src/internet-stack/tcp-socket-impl.cc index bdb16411c..959b793c5 100644 --- a/src/internet-node/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -127,7 +127,8 @@ TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock) m_cnCount (sock.m_cnCount), m_rxAvailable (0), m_wouldBlock (false), - m_sndBufSize (sock.m_sndBufSize) + m_sndBufSize (sock.m_sndBufSize), + m_rcvBufSize(sock.m_rcvBufSize) { NS_LOG_FUNCTION_NOARGS (); NS_LOG_LOGIC("Invoked the copy constructor"); @@ -347,38 +348,33 @@ TcpSocketImpl::Connect (const Address & address) } int TcpSocketImpl::Send (const Ptr p) //p here is just data, no headers -{ // TCP Does not deal with packets from app, just data - return Send(p->PeekData(), p->GetSize()); -} - -int TcpSocketImpl::Send (const uint8_t* buf, uint32_t size) { - NS_LOG_FUNCTION (this << buf << size); + NS_LOG_FUNCTION (this << p); if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT) - { - if (size > GetTxAvailable ()) - { - m_wouldBlock = true; - m_errno = ERROR_MSGSIZE; - return -1; - } - if (!m_pendingData) - { - m_pendingData = new PendingData (); // Create if non-existent - m_firstPendingSequence = m_nextTxSequence; // Note seq of first - } - //PendingData::Add always copies the data buffer, never modifies - m_pendingData->Add (size,buf); - NS_LOG_DEBUG("TcpSock::Send, pdsize " << m_pendingData->Size() << - " state " << m_state); - Actions_t action = ProcessEvent (APP_SEND); - NS_LOG_DEBUG(" action " << action); - if (!ProcessAction (action)) - { - return -1; // Failed, return zero - } - return size; + { + if (p->GetSize() > GetTxAvailable ()) + { + m_wouldBlock = true; + m_errno = ERROR_MSGSIZE; + return -1; } + if (!m_pendingData) + { + m_pendingData = new PendingData (); // Create if non-existent + m_firstPendingSequence = m_nextTxSequence; // Note seq of first + } + //PendingData::Add stores a copy of the Ptr p + m_pendingData->Add (p); + NS_LOG_DEBUG("TcpSock::Send, pdsize " << m_pendingData->Size() << + " state " << m_state); + Actions_t action = ProcessEvent (APP_SEND); + NS_LOG_DEBUG(" action " << action); + if (!ProcessAction (action)) + { + return -1; // Failed, return zero + } + return p->GetSize(); + } else { m_errno = ERROR_NOTCONN; @@ -386,6 +382,11 @@ int TcpSocketImpl::Send (const uint8_t* buf, uint32_t size) } } +int TcpSocketImpl::Send (const uint8_t* buf, uint32_t size) +{ + return Send (Create (buf, size)); +} + int TcpSocketImpl::DoSendTo (Ptr p, const Address &address) { NS_LOG_FUNCTION (this << p << address); @@ -463,21 +464,63 @@ Ptr TcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags) { NS_LOG_FUNCTION_NOARGS (); - if (m_deliveryQueue.empty() ) + if(m_bufferedData.empty()) { return 0; } - Ptr p = m_deliveryQueue.front (); - if (p->GetSize () <= maxSize) - { - m_deliveryQueue.pop (); - m_rxAvailable -= p->GetSize (); + UnAckData_t out; //serves as buffer to return up to the user + UnAckData_t::iterator i; + while (!m_bufferedData.empty ()) + { // Check the buffered data for delivery + NS_LOG_LOGIC("TCP " << this << " bufferedData.size() " + << m_bufferedData.size () + << " time " << Simulator::Now ()); + i = m_bufferedData.begin (); + SequenceNumber s1 = 0; + if (i->first > m_nextRxSequence) + { + break; // we're done, no more in-sequence data exits + } + else // (i->first <= m_nextRxSequence) + { // Two cases here. + // 1) seq + length > nextRxSeq, can deliver partial + // 2) seq + length <= nextRxSeq, deliver whole + s1 = i->second->GetSize (); + if (i->first + s1 > m_nextRxSequence) + { // Remove partial data to prepare for delivery + uint32_t avail = s1 + i->first - m_nextRxSequence; + i->second = i->second->CreateFragment (0, avail); + } + // else this packet is okay to deliver whole + // so don't do anything else and output it + out[i->first] = i->second; + } + m_rxAvailable -= i->second->GetSize (); + m_bufferedData.erase (i); // Remove from list } - else + if (out.size() == 0) { - p = 0; + return 0; } - return p; + Ptr outPacket = Create(); + for(i = out.begin(); i!=out.end(); ++i) + { + if (outPacket->GetSize() + i->second->GetSize() <= maxSize ) + { + outPacket->AddAtEnd(i->second); + } + else + { + //only append as much as will fit + uint32_t avail = maxSize - outPacket->GetSize(); + outPacket->AddAtEnd(i->second->CreateFragment(0,avail)); + //put the rest back into the buffer + m_bufferedData[i->first+SequenceNumber(avail)] + = i->second->CreateFragment(avail,i->second->GetSize()-avail); + m_rxAvailable += i->second->GetSize()-avail; + } + } + return outPacket; } uint32_t @@ -883,7 +926,7 @@ bool TcpSocketImpl::SendPendingData (bool withAck) uint32_t s = std::min (w, m_segmentSize); // Send no more than window Ptr p = m_pendingData->CopyFromSeq (s, m_firstPendingSequence, m_nextTxSequence); - NS_LOG_LOGIC("TcpSocketImpl " << this << " sendPendingData" + NS_LOG_LOGIC("TcpSocketImpl " << this << " SendPendingData" << " txseq " << m_nextTxSequence << " s " << s << " datasize " << p->GetSize() ); @@ -918,7 +961,7 @@ bool TcpSocketImpl::SendPendingData (bool withAck) if (m_retxEvent.IsExpired () ) //go ahead and schedule the retransmit { Time rto = m_rtt->RetransmitTimeout (); - NS_LOG_LOGIC ("Schedule retransmission timeout at time " << + NS_LOG_LOGIC ("SendPendingData Schedule retransmission timeout at time " << Simulator::Now ().GetSeconds () << " to expire at time " << (Simulator::Now () + rto).GetSeconds () ); m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this); @@ -935,7 +978,7 @@ bool TcpSocketImpl::SendPendingData (bool withAck) // Note the high water mark m_highTxMark = std::max (m_nextTxSequence, m_highTxMark); } - NS_LOG_LOGIC ("Sent "<0); } @@ -994,90 +1037,57 @@ void TcpSocketImpl::NewRx (Ptr p, // Log sequence received if enabled // NoteTimeSeq(LOG_SEQ_RX, h->sequenceNumber); // Three possibilities - // 1) Received seq is expected, deliver this and any buffered data + // 1) Received seq is expected, buffer this, update rxAvailable, and ack // 2) Received seq is < expected, just re-ack previous // 3) Received seq is > expected, just re-ack previous and buffer data if (tcpHeader.GetSequenceNumber () == m_nextRxSequence) { // If seq is expected seq // 1) Update nextRxSeq - // 2) Deliver to application this packet - // 3) See if any buffered can be delivered - // 4) Send the ack + // 2) Buffer this packet so Recv can read it + // 3) Send the ack m_nextRxSequence += s; // Advance next expected sequence //bytesReceived += s; // Statistics NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence ); SocketRxAddressTag tag; tag.SetAddress (fromAddress); p->AddTag (tag); - m_deliveryQueue.push (p); + //buffer this, it'll be read by call to Recv + UnAckData_t::iterator i = + m_bufferedData.find (tcpHeader.GetSequenceNumber () ); + if (i != m_bufferedData.end () ) //we found it already in the buffer + { + i->second = 0; // relase reference to already buffered + } + // Save for later delivery + m_bufferedData[tcpHeader.GetSequenceNumber () ] = p; m_rxAvailable += p->GetSize (); + //putting this into the buffer might have filled in a sequence gap + //so we have to iterate through the list to find the largest contiguous + //sequenced chunk, and update m_rxAvailable appropriately + i = m_bufferedData.find (tcpHeader.GetSequenceNumber () ); + UnAckData_t::iterator next = i; + next++; + while(next != m_bufferedData.end()) + { + if(i->first + SequenceNumber(i->second->GetSize ()) == next->first) + { + //next packet is in sequence, count it + m_rxAvailable += next->second->GetSize(); + m_nextRxSequence += next->second->GetSize(); + } + else + { + break; //no more in this contiguous chunk + } + ++i; + ++next; + } NotifyDataRecv (); if (m_closeNotified) { NS_LOG_LOGIC ("Tcp " << this << " HuH? Got data after closeNotif"); } NS_LOG_LOGIC ("TcpSocketImpl " << this << " adv rxseq by " << s); - // Look for buffered data - UnAckData_t::iterator i; - // Note that the bufferedData list DOES contain the tcp header - while (!m_bufferedData.empty ()) - { // Check the buffered data for delivery - NS_LOG_LOGIC("TCP " << this << " bufferedData.size() " - << m_bufferedData.size () - << " time " << Simulator::Now ()); - i = m_bufferedData.begin (); - Ptr p1 = i->second; - SequenceNumber s1 = 0; - if (i->first > m_nextRxSequence) - { - break; // Not next expected - } - // already have the header as a param - //TCPHeader* h = dynamic_cast(p1->PopPDU()); - // Check non-null here... - uint8_t flags = tcpHeader.GetFlags (); // Flags (used below) - if (i->first < m_nextRxSequence) - { // remove already delivered data - // Two cases here. - // 1) seq + length <= nextRxSeq, just discard - // 2) seq + length > nextRxSeq, can deliver partial - s1 = p->GetSize (); - if (i->first + s1 < m_nextRxSequence) - { // Just remove from list - //bufferedData.erase(i); - p1 = 0; // Nothing to deliver - } - else - { // Remove partial data to prepare for delivery - uint32_t dup = m_nextRxSequence - i->first; - i->second = p1->CreateFragment (0, p1->GetSize () - dup); - p1 = i->second; - } - } - else - { // At this point i->first must equal nextRxSeq - if (i->first != m_nextRxSequence) - { - NS_FATAL_ERROR ("HuH? NexRx failure, first " - << i->first << " nextRxSeq " << m_nextRxSequence); - } - s1 = p1->GetSize (); - } - SocketRxAddressTag tag; - tag.SetAddress (fromAddress); - p1->AddTag (tag); - m_deliveryQueue.push (p1); - m_rxAvailable += p->GetSize (); - NotifyDataRecv (); - - NS_LOG_LOGIC ("TcpSocketImpl " << this << " adv rxseq1 by " << s1 ); - m_nextRxSequence += s1; // Note data received - m_bufferedData.erase (i); // Remove from list - if (flags & TcpHeader::FIN) - NS_LOG_LOGIC("TcpSocketImpl " << this - << " found FIN in buffered"); - } - if (m_pendingClose || (origState > ESTABLISHED)) { // See if we can close now if (m_bufferedData.empty()) @@ -1096,6 +1106,9 @@ void TcpSocketImpl::NewRx (Ptr p, i->second = 0; // relase reference to already buffered } // Save for later delivery + SocketRxAddressTag tag; + tag.SetAddress (fromAddress); + p->AddTag (tag); m_bufferedData[tcpHeader.GetSequenceNumber () ] = p; } else diff --git a/src/internet-node/tcp-socket-impl.h b/src/internet-stack/tcp-socket-impl.h similarity index 99% rename from src/internet-node/tcp-socket-impl.h rename to src/internet-stack/tcp-socket-impl.h index 7adc8669e..8f1f832f5 100644 --- a/src/internet-node/tcp-socket-impl.h +++ b/src/internet-stack/tcp-socket-impl.h @@ -198,16 +198,15 @@ private: // Timer-related members Time m_cnTimeout; uint32_t m_cnCount; - + // Temporary queue for delivering data to application - std::queue > m_deliveryQueue; uint32_t m_rxAvailable; - + bool m_wouldBlock; // set to true whenever socket would block on send() // Attributes - uint32_t m_rcvBufSize; // maximum receive socket buffer size uint32_t m_sndBufSize; // buffer limit for the outgoing queue + uint32_t m_rcvBufSize; // maximum receive socket buffer size }; }//namespace ns3 diff --git a/src/internet-node/tcp-typedefs.h b/src/internet-stack/tcp-typedefs.h similarity index 100% rename from src/internet-node/tcp-typedefs.h rename to src/internet-stack/tcp-typedefs.h diff --git a/src/internet-node/udp-header.cc b/src/internet-stack/udp-header.cc similarity index 100% rename from src/internet-node/udp-header.cc rename to src/internet-stack/udp-header.cc diff --git a/src/internet-node/udp-header.h b/src/internet-stack/udp-header.h similarity index 100% rename from src/internet-node/udp-header.h rename to src/internet-stack/udp-header.h diff --git a/src/internet-node/udp-l4-protocol.cc b/src/internet-stack/udp-l4-protocol.cc similarity index 100% rename from src/internet-node/udp-l4-protocol.cc rename to src/internet-stack/udp-l4-protocol.cc diff --git a/src/internet-node/udp-l4-protocol.h b/src/internet-stack/udp-l4-protocol.h similarity index 100% rename from src/internet-node/udp-l4-protocol.h rename to src/internet-stack/udp-l4-protocol.h diff --git a/src/internet-node/udp-socket-factory-impl.cc b/src/internet-stack/udp-socket-factory-impl.cc similarity index 100% rename from src/internet-node/udp-socket-factory-impl.cc rename to src/internet-stack/udp-socket-factory-impl.cc diff --git a/src/internet-node/udp-socket-factory-impl.h b/src/internet-stack/udp-socket-factory-impl.h similarity index 100% rename from src/internet-node/udp-socket-factory-impl.h rename to src/internet-stack/udp-socket-factory-impl.h diff --git a/src/internet-node/udp-socket-impl.cc b/src/internet-stack/udp-socket-impl.cc similarity index 100% rename from src/internet-node/udp-socket-impl.cc rename to src/internet-stack/udp-socket-impl.cc diff --git a/src/internet-node/udp-socket-impl.h b/src/internet-stack/udp-socket-impl.h similarity index 100% rename from src/internet-node/udp-socket-impl.h rename to src/internet-stack/udp-socket-impl.h diff --git a/src/internet-node/waf b/src/internet-stack/waf similarity index 100% rename from src/internet-node/waf rename to src/internet-stack/waf diff --git a/src/internet-node/wscript b/src/internet-stack/wscript similarity index 91% rename from src/internet-node/wscript rename to src/internet-stack/wscript index 93d87147d..780a84a98 100644 --- a/src/internet-node/wscript +++ b/src/internet-stack/wscript @@ -2,7 +2,7 @@ def build(bld): - obj = bld.create_ns3_module('internet-node', ['node']) + obj = bld.create_ns3_module('internet-stack', ['node']) obj.source = [ 'internet-stack.cc', 'ipv4-l4-demux.cc', @@ -33,7 +33,7 @@ def build(bld): ] headers = bld.create_obj('ns3header') - headers.module = 'internet-node' + headers.module = 'internet-stack' headers.source = [ 'internet-stack.h', 'udp-header.h', diff --git a/src/node/ipv4.h b/src/node/ipv4.h index 600c0e4f1..d2157c959 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -74,7 +74,7 @@ public: typedef Callback, const Ipv4Header&> RouteReplyCallback; /** - * \brief Asynchronously requests a route for a given packet and IP header + * \brief Request that a packet be routed. * * \param ifIndex The interface index on which the packet was received. * \param ipHeader IP header of the packet @@ -94,7 +94,7 @@ public: * RequestRoute() should return false and the routeReply callback * must not be invoked. * - * If the routing protocol implementations assumes it can provide + * If the routing protocol implementation assumes that it can provide * the requested route, then it should return true, and the * routeReply callback must be invoked, either immediately before * returning true (synchronously), or in the future (asynchronous). @@ -105,6 +105,11 @@ public: * allowed to add a new header to the packet, which will appear * immediately after the IP header, although most routing do not * insert any extra header. + * + * Multicast routing is expected to be supported in this method. If a + * multicast route is encountered, all routes to a given multicast + * destination will be serviced by cloning the packet and calling the + * route reply callback once for each outgoing interface in the route. */ virtual bool RequestRoute (uint32_t ifIndex, const Ipv4Header &ipHeader, diff --git a/src/node/socket.cc b/src/node/socket.cc index 5b5c79f02..0bdc167a0 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -40,6 +40,13 @@ Socket::~Socket () NS_LOG_FUNCTION_NOARGS (); } +void +Socket::SetCloseUnblocksCallback (Callback > closeUnblocks) +{ + NS_LOG_FUNCTION_NOARGS (); + m_closeUnblocks = closeUnblocks; +} + Ptr Socket::CreateSocket (Ptr node, TypeId tid) { @@ -103,6 +110,21 @@ Socket::SetRecvCallback (Callback > receivedData) m_receivedData = receivedData; } +void +Socket::NotifyCloseUnblocks (void) +{ + NS_LOG_FUNCTION_NOARGS (); + if (!m_closeUnblocks.IsNull ()) + { + m_closeUnblocks (this); + } +} + +int Socket::Listen (uint32_t queueLimit) +{ + return 0; //XXX the base class version does nothing +} + int Socket::Send (const uint8_t* buf, uint32_t size) { NS_LOG_FUNCTION_NOARGS (); diff --git a/src/node/socket.h b/src/node/socket.h index a9a5bd666..34e018743 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -105,6 +105,8 @@ public: */ virtual Ptr GetNode (void) const = 0; + void SetCloseUnblocksCallback (Callback > closeUnblocks); + /** * \param closeCompleted Callback invoked when the close operation is * completed. @@ -362,6 +364,7 @@ public: virtual uint32_t GetRxAvailable (void) const = 0; protected: + void NotifyCloseUnblocks (void); void NotifyCloseCompleted (void); void NotifyConnectionSucceeded (void); void NotifyConnectionFailed (void); @@ -373,6 +376,7 @@ protected: void NotifySend (uint32_t spaceAvailable); void NotifyDataRecv (void); + Callback > m_closeUnblocks; Callback > m_closeCompleted; Callback > m_connectionSucceeded; Callback > m_connectionFailed; diff --git a/src/routing/olsr/wscript b/src/routing/olsr/wscript index 8a3082c7d..013999cd8 100644 --- a/src/routing/olsr/wscript +++ b/src/routing/olsr/wscript @@ -1,7 +1,7 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def build(bld): - module = bld.create_ns3_module('olsr', ['internet-node', 'contrib']) + module = bld.create_ns3_module('olsr', ['internet-stack', 'contrib']) module.includes = '.' module.source = [ 'olsr-header.cc', diff --git a/src/wscript b/src/wscript index 83a257919..43dddb49b 100644 --- a/src/wscript +++ b/src/wscript @@ -16,7 +16,7 @@ all_modules = ( 'simulator', 'contrib', 'node', - 'internet-node', + 'internet-stack', 'devices/point-to-point', 'devices/csma', 'applications/onoff', diff --git a/tutorial/tutorial-bus-network.cc b/tutorial/tutorial-bus-network.cc index 04f4bae84..a4016a4dc 100644 --- a/tutorial/tutorial-bus-network.cc +++ b/tutorial/tutorial-bus-network.cc @@ -40,7 +40,7 @@ main (int argc, char *argv[]) internet.Install (n); CsmaHelper csma; - csma.SetChannelParameter ("BitRate", StringValue ("10Mbps")); + csma.SetChannelParameter ("DataRate", StringValue ("10Mbps")); csma.SetChannelParameter ("Delay", StringValue ("10ms")); NetDeviceContainer nd = csma.Install (n); diff --git a/tutorial/tutorial-csma-echo-ascii-trace.cc b/tutorial/tutorial-csma-echo-ascii-trace.cc index f4af8afb9..8fef98c97 100644 --- a/tutorial/tutorial-csma-echo-ascii-trace.cc +++ b/tutorial/tutorial-csma-echo-ascii-trace.cc @@ -38,7 +38,7 @@ main (int argc, char *argv[]) internet.Install (n); CsmaHelper csma; - csma.SetChannelParameter ("BitRate", StringValue ("5Mpbs")); + csma.SetChannelParameter ("DataRate", StringValue ("5Mpbs")); csma.SetChannelParameter ("Delay", StringValue ("2ms")); NetDeviceContainer nd = csma.Install (n); diff --git a/tutorial/tutorial-csma-echo-pcap-trace.cc b/tutorial/tutorial-csma-echo-pcap-trace.cc index 55c6c73fd..090fb1b65 100644 --- a/tutorial/tutorial-csma-echo-pcap-trace.cc +++ b/tutorial/tutorial-csma-echo-pcap-trace.cc @@ -36,7 +36,7 @@ main (int argc, char *argv[]) internet.Install (n); CsmaHelper csma; - csma.SetChannelParameter ("BitRate", StringValue ("5Mbps")); + csma.SetChannelParameter ("DataRate", StringValue ("5Mbps")); csma.SetChannelParameter ("Delay", StringValue ("2ms")); NetDeviceContainer nd = csma.Install (n); diff --git a/tutorial/tutorial-csma-echo.cc b/tutorial/tutorial-csma-echo.cc index 3e00efb5e..e4472d4a9 100644 --- a/tutorial/tutorial-csma-echo.cc +++ b/tutorial/tutorial-csma-echo.cc @@ -36,7 +36,7 @@ main (int argc, char *argv[]) internet.Install (n); CsmaHelper csma; - csma.SetChannelParameter ("BitRate", StringValue ("5Mbps")); + csma.SetChannelParameter ("DataRate", StringValue ("5Mbps")); csma.SetChannelParameter ("Delay", StringValue ("2ms")); NetDeviceContainer nd = csma.Install (n); diff --git a/tutorial/tutorial-linear-dumbbell.cc b/tutorial/tutorial-linear-dumbbell.cc index 860c036ef..6b85a7b08 100644 --- a/tutorial/tutorial-linear-dumbbell.cc +++ b/tutorial/tutorial-linear-dumbbell.cc @@ -53,7 +53,7 @@ main (int argc, char *argv[]) internet.Install (lan1); CsmaHelper csma; - csma.SetChannelParameter ("BitRate", StringValue ("10Mbps")); + csma.SetChannelParameter ("DataRate", StringValue ("10Mbps")); csma.SetChannelParameter ("Delay", StringValue ("2ms")); NetDeviceContainer dev1 = csma.Install (lan1); Ipv4AddressHelper ipv4; @@ -78,7 +78,7 @@ main (int argc, char *argv[]) // NodeContainer backbone = NodeContainer (lan1.Get (3), lan2.Get (0)); PointToPointHelper p2p; - p2p.SetChannelParameter ("BitRate", StringValue ("38400bps")); + p2p.SetChannelParameter ("DataRate", StringValue ("38400bps")); p2p.SetChannelParameter ("Delay", StringValue ("20ms")); NetDeviceContainer dev3 = p2p.Install (backbone); ipv4.SetBase ("10.1.3.0", "255.255.255.0"); diff --git a/tutorial/tutorial-point-to-point.cc b/tutorial/tutorial-point-to-point.cc index 66d0fe5df..030920007 100644 --- a/tutorial/tutorial-point-to-point.cc +++ b/tutorial/tutorial-point-to-point.cc @@ -45,7 +45,7 @@ main (int argc, char *argv[]) internet.Install (n); PointToPointHelper p2p; - p2p.SetChannelParameter ("BitRate", StringValue ("38400bps")); + p2p.SetDeviceParameter ("DataRate", StringValue ("38400bps")); p2p.SetChannelParameter ("Delay", StringValue ("20ms")); NetDeviceContainer nd = p2p.Install (n); diff --git a/tutorial/tutorial-star-routing.cc b/tutorial/tutorial-star-routing.cc index 59399b569..1abacf9a4 100644 --- a/tutorial/tutorial-star-routing.cc +++ b/tutorial/tutorial-star-routing.cc @@ -56,7 +56,7 @@ main (int argc, char *argv[]) internet.Install (n); PointToPointHelper p2p; - p2p.SetChannelParameter ("BitRate", StringValue ("38400bps")); + p2p.SetDeviceParameter ("DataRate", StringValue ("38400bps")); p2p.SetChannelParameter ("Delay", StringValue ("20ms")); NetDeviceContainer d01 = p2p.Install (n01); diff --git a/tutorial/tutorial-star.cc b/tutorial/tutorial-star.cc index 9c3f78c18..f13018b9c 100644 --- a/tutorial/tutorial-star.cc +++ b/tutorial/tutorial-star.cc @@ -55,7 +55,7 @@ main (int argc, char *argv[]) internet.Install (n); PointToPointHelper p2p; - p2p.SetChannelParameter ("BitRate", StringValue ("38400bps")); + p2p.SetDeviceParameter ("DataRate", StringValue ("38400bps")); p2p.SetChannelParameter ("Delay", StringValue ("20ms")); NetDeviceContainer d01 = p2p.Install (n01); diff --git a/tutorial/wscript b/tutorial/wscript index bc40b24fe..a302c39bb 100644 --- a/tutorial/wscript +++ b/tutorial/wscript @@ -4,29 +4,29 @@ def build(bld): obj = bld.create_ns3_program('hello-simulator', ['simulator']) obj.source = 'hello-simulator.cc' - obj = bld.create_ns3_program('tutorial-csma-echo', ['internet-node', 'csma']) + obj = bld.create_ns3_program('tutorial-csma-echo', ['internet-stack', 'csma']) obj.source = 'tutorial-csma-echo.cc' - obj = bld.create_ns3_program('tutorial-csma-echo-ascii-trace', ['internet-node', 'csma']) + obj = bld.create_ns3_program('tutorial-csma-echo-ascii-trace', ['internet-stack', 'csma']) obj.source = 'tutorial-csma-echo-ascii-trace.cc' - obj = bld.create_ns3_program('tutorial-csma-echo-pcap-trace', ['internet-node', 'csma']) + obj = bld.create_ns3_program('tutorial-csma-echo-pcap-trace', ['internet-stack', 'csma']) obj.source = 'tutorial-csma-echo-pcap-trace.cc' - obj = bld.create_ns3_program('tutorial-point-to-point', ['internet-node', 'point-to-point']) + obj = bld.create_ns3_program('tutorial-point-to-point', ['internet-stack', 'point-to-point']) obj.source = 'tutorial-point-to-point.cc' - obj = bld.create_ns3_program('tutorial-star', ['internet-node', 'point-to-point']) + obj = bld.create_ns3_program('tutorial-star', ['internet-stack', 'point-to-point']) obj.source = ['tutorial-star.cc'] - obj = bld.create_ns3_program('tutorial-star-routing', ['internet-node', 'point-to-point']) + obj = bld.create_ns3_program('tutorial-star-routing', ['internet-stack', 'point-to-point']) obj.source = ['tutorial-star-routing.cc'] - obj = bld.create_ns3_program('tutorial-linear-dumbbell', ['internet-node', 'point-to-point']) + obj = bld.create_ns3_program('tutorial-linear-dumbbell', ['internet-stack', 'point-to-point']) obj.source = 'tutorial-linear-dumbbell.cc' obj = bld.create_ns3_program('testipv4', ['node']) obj.source = ['testipv4.cc'] - obj = bld.create_ns3_program('tutorial-bus-network', ['internet-node']) + obj = bld.create_ns3_program('tutorial-bus-network', ['internet-stack']) obj.source = ['tutorial-bus-network.cc'] diff --git a/utils/wscript b/utils/wscript index a4901354f..f6cc97626 100644 --- a/utils/wscript +++ b/utils/wscript @@ -28,14 +28,14 @@ def build(bld): obj.source = 'replay-simulation.cc' obj = bld.create_ns3_program('print-introspected-doxygen', - ['internet-node', 'csma-cd', 'point-to-point']) + ['internet-stack', 'csma-cd', 'point-to-point']) obj.source = 'print-introspected-doxygen.cc' # XXX: disable mobility visualizer code temporarily. env['ENABLE_MOBILITY_VISUALIZER'] = '' if env['ENABLE_MOBILITY_VISUALIZER']: obj = bld.create_ns3_program('mobility-visualizer', - ['internet-node', 'mobility']) + ['internet-stack', 'mobility']) obj.source = ['mobility-visualizer-model.cc', 'mobility-visualizer-view.cc'] obj.uselib = 'MOBILITY_VISUALIZER' if os.path.basename(obj.env['CXX']).startswith("g++"):