merge with HEAD

This commit is contained in:
Mathieu Lacage
2008-06-11 16:20:04 -07:00
95 changed files with 973 additions and 666 deletions

View File

@@ -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
*

View File

@@ -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"

View File

@@ -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

View File

@@ -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<Ipv4RoutingProtocol> 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

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -67,8 +67,9 @@ main (int argc, char *argv[])
// create the shared medium used by all csma devices.
NS_LOG_INFO ("Create channels.");
Ptr<CsmaChannel> channel = CreateObject<CsmaChannel> ("BitRate", DataRateValue (DataRate(5000000)),
"Delay", TimeValue (MilliSeconds(2)));
Ptr<CsmaChannel> channel = CreateObject<CsmaChannel> (
"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.");

View File

@@ -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);

View File

@@ -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);
//

View File

@@ -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 <ctype.h>
#include <iostream>
#include <fstream>
@@ -73,39 +77,9 @@ ApplicationTraceSink (Ptr<const Packet> packet,
#endif
}
void CloseConnection (Ptr<Socket> localSocket)
{
localSocket->Close ();
}
void StartFlow(Ptr<Socket> 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<void, Ptr<Socket> > (),
Callback<void, Ptr<Socket> > ());
//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<Socket> localSocket);
void StartFlow(Ptr<Socket>, uint32_t, Ipv4Address, uint16_t);
void WriteUntilBufferFull (Ptr<Socket>, 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<Socket> localSocket)
{
localSocket->Close ();
}
void StartFlow(Ptr<Socket> 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<void, Ptr<Socket> > (),
Callback<void, Ptr<Socket> > ());
//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<Socket> 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;
}
}

View File

@@ -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);

View File

@@ -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',

View File

@@ -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',

View File

@@ -37,19 +37,23 @@ UdpEchoClient::GetTypeId (void)
static TypeId tid = TypeId ("ns3::UdpEchoClient")
.SetParent<Application> ()
.AddConstructor<UdpEchoClient> ()
.AddAttribute ("MaxPackets", "XXX",
.AddAttribute ("MaxPackets",
"The maximum number of packets the application will send",
UintegerValue (100),
MakeUintegerAccessor (&UdpEchoClient::m_count),
MakeUintegerChecker<uint32_t> ())
.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<uint16_t> ())

View File

@@ -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',

View File

@@ -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;

View File

@@ -30,29 +30,15 @@ namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (CsmaChannel);
CsmaDeviceRec::CsmaDeviceRec()
{
active = false;
}
CsmaDeviceRec::CsmaDeviceRec(Ptr<CsmaNetDevice> device)
{
devicePtr = device;
active = true;
}
bool
CsmaDeviceRec::IsActive() {
return active;
}
TypeId
TypeId
CsmaChannel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CsmaChannel")
.SetParent<Channel> ()
.AddConstructor<CsmaChannel> ()
.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<CsmaNetDevice> device)
int32_t
CsmaChannel::Attach (Ptr<CsmaNetDevice> 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<CsmaNetDevice> device)
bool
CsmaChannel::Reattach (Ptr<CsmaNetDevice> device)
{
NS_LOG_FUNCTION (this << device);
NS_ASSERT(device != 0);
NS_ASSERT (device != 0);
std::vector<CsmaDeviceRec>::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<CsmaNetDevice> 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<CsmaNetDevice> device)
bool
CsmaChannel::Detach (Ptr<CsmaNetDevice> device)
{
NS_LOG_FUNCTION (this << device);
NS_ASSERT(device != 0);
NS_ASSERT (device != 0);
std::vector<CsmaDeviceRec>::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<CsmaNetDevice> device)
return false;
}
bool
CsmaChannel::TransmitStart(Ptr<Packet> p, uint32_t srcId)
bool
CsmaChannel::TransmitStart (Ptr<Packet> 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<Packet> 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<CsmaDeviceRec>::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<CsmaDeviceRec>::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<CsmaNetDevice>
Ptr<CsmaNetDevice>
CsmaChannel::GetCsmaDevice (uint32_t i) const
{
Ptr< CsmaNetDevice > netDevice;
netDevice = m_deviceList[i].devicePtr;
Ptr<CsmaNetDevice> netDevice = m_deviceList[i].devicePtr;
return netDevice;
}
int32_t
int32_t
CsmaChannel::GetDeviceNum (Ptr<CsmaNetDevice> device)
{
std::vector<CsmaDeviceRec>::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<CsmaNetDevice> 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<NetDevice>
Ptr<NetDevice>
CsmaChannel::GetDevice (uint32_t i) const
{
return GetCsmaDevice (i);
}
CsmaDeviceRec::CsmaDeviceRec ()
{
active = false;
}
CsmaDeviceRec::CsmaDeviceRec (Ptr<CsmaNetDevice> device)
{
devicePtr = device;
active = true;
}
bool
CsmaDeviceRec::IsActive ()
{
return active;
}
} // namespace ns3

View File

@@ -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<CsmaNetDevice> device);
/**
* \brief Detach a given netdevice from this channel
*
@@ -116,6 +104,7 @@ public:
* can't be found.
*/
bool Detach (Ptr<CsmaNetDevice> 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<CsmaNetDevice> device);
/**
* \brief Start transmitting a packet over the channel
*
@@ -171,6 +163,7 @@ public:
* device is currently active.
*/
bool TransmitStart (Ptr<Packet> 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<CsmaNetDevice> 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<NetDevice> 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<NetDevice> 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<CsmaNetDevice> 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<CsmaDeviceRec> 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<Packet> m_currentPkt;
Ptr<Packet> 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
*/

View File

@@ -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<NetDevice> ()
.AddConstructor<CsmaNetDevice> ()
.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<ErrorModel> ())
.AddAttribute ("TxQueue", "XXX",
.AddAttribute ("TxQueue",
"A queue to use as the transmit queue in the device.",
PointerValue (),
MakePointerAccessor (&CsmaNetDevice::m_queue),
MakePointerChecker<Queue> ())
.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<Packet> p, Mac48Address dest,
uint16_t protocolNumber)
void
CsmaNetDevice::AddHeader (
Ptr<Packet> 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<Packet> 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<Packet> p, uint16_t & param)
{
NS_LOG_FUNCTION_NOARGS ();
@@ -222,15 +227,17 @@ CsmaNetDevice::ProcessHeader (Ptr<Packet> 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<Packet> 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<Packet> 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<CsmaChannel> 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<Queue> q)
{
NS_LOG_FUNCTION (this << q);
m_queue = q;
}
void CsmaNetDevice::SetReceiveErrorModel (Ptr<ErrorModel> em)
void
CsmaNetDevice::SetReceiveErrorModel (Ptr<ErrorModel> em)
{
NS_LOG_FUNCTION (em);
m_receiveErrorModel = em;
}
void
void
CsmaNetDevice::Receive (Ptr<Packet> 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> 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> 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> 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 <protocol> 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> packet)
{
case ETHERNET_V1:
case IP_ARP:
protocol = header.GetLengthType();
protocol = header.GetLengthType ();
break;
case LLC:
{
@@ -516,95 +560,109 @@ CsmaNetDevice::Receive (Ptr<Packet> packet)
}
}
Ptr<Queue>
CsmaNetDevice::GetQueue(void) const
Ptr<Queue>
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<Channel>
Ptr<Channel>
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<void> 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> packet, const Address& dest, uint16_t protocolNumber)
bool
CsmaNetDevice::Send(
Ptr<Packet> packet,
const Address& dest,
uint16_t protocolNumber)
{
NS_LOG_FUNCTION_NOARGS ();
NS_LOG_LOGIC ("p=" << packet);
@@ -669,43 +732,56 @@ CsmaNetDevice::Send(Ptr<Packet> 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<Node>
Ptr<Node>
CsmaNetDevice::GetNode (void) const
{
return m_node;
}
void
void
CsmaNetDevice::SetNode (Ptr<Node> 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;

View File

@@ -16,7 +16,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
* Derived from the p2p net device file
*/
#ifndef CSMA_NET_DEVICE_H
@@ -48,18 +47,19 @@ class ErrorModel;
*
* The Csma net device class is analogous to layer 1 and 2 of the
* TCP stack. The NetDevice takes a raw packet of bytes and creates a
* protocol specific packet from them. The Csma net device class
* takes this packet and adds and processes the headers/trailers that
* are associated with EthernetV1, EthernetV2, RAW or LLC
* protocols. The EthernetV1 packet type adds and removes Ethernet
* protocol specific packet from them.
*
* The Csma net device class takes a packet and adds (or removes) the
* headers/trailers that are associated with EthernetV1, EthernetV2, RAW
* or LLC protocols. The EthernetV1 packet type adds and removes Ethernet
* destination and source addresses. The LLC packet type adds and
* removes LLC snap headers. The raw packet type does not add or
* remove any headers. Each Csma net device will receive all
* packets written to the Csma link. The ProcessHeader function can
* be used to filter out the packets such that higher level layers
* only receive packets that are addressed to their associated net
* devices
* remove any headers.
*
* Each Csma net device will receive all packets written to the Csma link.
* The ProcessHeader function can be used to filter out the packets such that
* higher level layers only receive packets that are addressed to their
* associated net devices
*/
class CsmaNetDevice : public NetDevice
{
@@ -69,49 +69,36 @@ public:
* Enumeration of the types of packets supported in the class.
*
*/
enum CsmaEncapsulationMode {
ETHERNET_V1, /**< Version one ethernet packet, length field */
IP_ARP, /**< Ethernet packet encapsulates IP/ARP packet */
RAW, /**< Packet that contains no headers */
LLC, /**< LLC packet encapsulation */
};
enum CsmaEncapsulationMode {
ETHERNET_V1, /**< Version one ethernet packet, length field */
IP_ARP, /**< Ethernet packet encapsulates IP/ARP packet */
RAW, /**< Packet that contains no headers */
LLC, /**< LLC packet encapsulation */
};
/**
* Construct a CsmaNetDevice
*
* This is the constructor for the CsmaNetDevice. It takes as a
* parameter the Node to which this device is connected. Ownership of the
* Node pointer is not implied and the node must not be deleted.
*
* This is the default constructor for a CsmaNetDevice.
*/
CsmaNetDevice ();
/**
* Destroy a CsmaNetDevice
*
* This is the destructor for the CsmaNetDevice.
* This is the destructor for a CsmaNetDevice.
*/
virtual ~CsmaNetDevice();
/**
* Set the Data Rate used for transmission of packets. The data rate is
* set in the Attach () method from the corresponding field in the channel
* to which the device is attached. It can be overridden using this method.
*
* @see Attach ()
* \param bps the data rate at which this object operates
*/
void SetDataRate (DataRate bps);
virtual ~CsmaNetDevice ();
/**
* Set the inteframe gap used to separate packets. The interframe gap
* defines the minimum space required between packets sent by this device.
* It is usually set in the Attach () method based on the speed of light
* delay of the channel to which the device is attached. It can be
* overridden using this method if desired.
* As in Ethernet, it defaults to 96 bit times.
*
* @see Attach ()
* \param t the interframe gap time
*/
void SetInterframeGap (Time t);
/**
* Set the backoff parameters used to determine the wait to retry
* transmitting a packet when the channel is busy.
@@ -124,43 +111,43 @@ enum CsmaEncapsulationMode {
* \param ceiling Cap on the exponential function when calculating max slots
*/
void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots,
uint32_t maxRetries, uint32_t ceiling);
uint32_t maxRetries, uint32_t ceiling);
/**
* Attach the device to a channel.
*
* The function Attach is used to add a CsmaNetDevice to a
* CsmaChannel.
* The function Attach is used to add a CsmaNetDevice to a CsmaChannel.
*
* @see SetDataRate ()
* @see SetInterframeGap ()
* \param ch a pointer to the channel to which this object is being attached.
*/
bool Attach (Ptr<CsmaChannel> 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> 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<ErrorModel> em);
void SetReceiveErrorModel (Ptr<ErrorModel> em);
/**
* Receive a packet from a connected CsmaChannel.
*
@@ -174,20 +161,48 @@ enum CsmaEncapsulationMode {
*/
void Receive (Ptr<Packet> 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<Channel> 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> packet, const Address& dest, uint16_t protocolNumber);
/**
* Start sending a packet down the channel.
*/
virtual bool Send (Ptr<Packet> 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<Node> 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> 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<Queue> 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<Packet> p, Mac48Address dest,
uint16_t protocolNumber);
void AddHeader (Ptr<Packet> 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<Packet> 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<Packet> m_currentPkt;
/**
* The CsmaChannel to which this CsmaNetDevice has been
* attached.
* @see class CsmaChannel
*/
Ptr<CsmaChannel> 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<ErrorModel> m_receiveErrorModel;
/**
* NOT TESTED
* The trace source for the packet reception events that the device can
* fire.
*
* @see class CallBackTraceSource
*/
TracedCallback<Ptr<const Packet> > m_rxTrace;
/**
* The trace source for the packet drop events that the device can
* fire.
*
* @see class CallBackTraceSource
*/
TracedCallback<Ptr<const Packet> > m_dropTrace;
/**
* The Node to which this device is attached.
*/
Ptr<Node> 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<void> 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

View File

@@ -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;

View File

@@ -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.
*/

View File

@@ -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',

View File

@@ -29,26 +29,10 @@
#include <string.h>
#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<Packet> (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<Packet> ((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<Packet> (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<Packet> (s));
}
size += s;
}
void PendingData::Remove(uint32_t s)
void PendingData::Add (Ptr<Packet> 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<Packet> 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<Packet> (data+o, s1);
uint32_t count = 0;
std::vector<Ptr<Packet> >::size_type begin = 0;
bool beginFound = false;
std::vector<Ptr<Packet> >::size_type end = 0;
Ptr<Packet> outPacket;
Ptr<Packet> endFragment;
for (std::vector<Ptr<Packet> >::size_type i=0;i<data.size();++i)
{
count+=data[i]->GetSize();
if (!beginFound)
{
if (count > o)
{
if (count >= o + s1) //then just copy within this packet
{
Ptr<Packet> 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<Packet> 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<Packet> toFragment = data[end];
uint32_t packetStart = count - toFragment->GetSize();
uint32_t fragmentLength = o + s1 - packetStart;
endFragment = toFragment->CreateFragment(0, fragmentLength);
break;
}
}
}
for (std::vector<Ptr<Packet> >::size_type i=begin+1;i<end;++i)
{
outPacket->AddAtEnd (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<Packet> (s1);
}
}

View File

@@ -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<Packet> 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<Ptr<Packet> > 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

View File

@@ -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<Packet> 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<Packet> (buf, size));
}
int TcpSocketImpl::DoSendTo (Ptr<Packet> p, const Address &address)
{
NS_LOG_FUNCTION (this << p << address);
@@ -463,21 +464,63 @@ Ptr<Packet>
TcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
{
NS_LOG_FUNCTION_NOARGS ();
if (m_deliveryQueue.empty() )
if(m_bufferedData.empty())
{
return 0;
}
Ptr<Packet> 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<Packet> outPacket = Create<Packet>();
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<Packet> 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 "<<nPacketsSent<<" packets");
NS_LOG_LOGIC ("SendPendingData Sent "<<nPacketsSent<<" packets");
NS_LOG_LOGIC("RETURN SendPendingData");
return (nPacketsSent>0);
}
@@ -994,90 +1037,57 @@ void TcpSocketImpl::NewRx (Ptr<Packet> 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<Packet> 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<TCPHeader*>(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<Packet> 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

View File

@@ -198,16 +198,15 @@ private:
// Timer-related members
Time m_cnTimeout;
uint32_t m_cnCount;
// Temporary queue for delivering data to application
std::queue<Ptr<Packet> > 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

View File

@@ -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',

View File

@@ -74,7 +74,7 @@ public:
typedef Callback<void, bool, const Ipv4Route&, Ptr<Packet>, 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,

View File

@@ -40,6 +40,13 @@ Socket::~Socket ()
NS_LOG_FUNCTION_NOARGS ();
}
void
Socket::SetCloseUnblocksCallback (Callback<void,Ptr<Socket> > closeUnblocks)
{
NS_LOG_FUNCTION_NOARGS ();
m_closeUnblocks = closeUnblocks;
}
Ptr<Socket>
Socket::CreateSocket (Ptr<Node> node, TypeId tid)
{
@@ -103,6 +110,21 @@ Socket::SetRecvCallback (Callback<void, Ptr<Socket> > 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 ();

View File

@@ -105,6 +105,8 @@ public:
*/
virtual Ptr<Node> GetNode (void) const = 0;
void SetCloseUnblocksCallback (Callback<void, Ptr<Socket> > 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<void, Ptr<Socket> > m_closeUnblocks;
Callback<void,Ptr<Socket> > m_closeCompleted;
Callback<void, Ptr<Socket> > m_connectionSucceeded;
Callback<void, Ptr<Socket> > m_connectionFailed;

View File

@@ -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',

View File

@@ -16,7 +16,7 @@ all_modules = (
'simulator',
'contrib',
'node',
'internet-node',
'internet-stack',
'devices/point-to-point',
'devices/csma',
'applications/onoff',

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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']

View File

@@ -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++"):