merge
This commit is contained in:
168
examples/simple-csma-cd.cc
Normal file
168
examples/simple-csma-cd.cc
Normal file
@@ -0,0 +1,168 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// Port of ns-2/tcl/ex/simple.tcl to ns-3
|
||||
//
|
||||
// Network topology
|
||||
//
|
||||
// n0
|
||||
// |
|
||||
// |
|
||||
// n2---+----n3
|
||||
// |
|
||||
// |
|
||||
// n1
|
||||
//
|
||||
// - CBR/UDP flows from n0 to n1, and from n3 to n0
|
||||
// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
|
||||
// (i.e., DataRate of 448,000 bps)
|
||||
// - DropTail queues
|
||||
// - Tracing of queues and packet receptions to file "simple-csma-cd.tr"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/default-value.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/random-variable.h"
|
||||
#include "ns3/debug.h"
|
||||
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/data-rate.h"
|
||||
|
||||
#include "ns3/ascii-trace.h"
|
||||
#include "ns3/pcap-trace.h"
|
||||
#include "ns3/internet-node.h"
|
||||
#include "ns3/csma-cd-channel.h"
|
||||
#include "ns3/csma-cd-net-device.h"
|
||||
#include "ns3/csma-cd-topology.h"
|
||||
#include "ns3/csma-cd-ipv4-topology.h"
|
||||
#include "ns3/mac-address.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/ipv4-route.h"
|
||||
#include "ns3/onoff-application.h"
|
||||
|
||||
#include "ns3/ascii-trace.h"
|
||||
|
||||
#include "ns3/trace-context.h"
|
||||
#include "ns3/trace-root.h"
|
||||
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
// Users may find it convenient to turn on explicit debugging
|
||||
// for selected modules; the below lines suggest how to do this
|
||||
#if 0
|
||||
DebugComponentEnable("Channel");
|
||||
DebugComponentEnable("CsmaCdChannel");
|
||||
DebugComponentEnable("CsmaCdNetDevice");
|
||||
DebugComponentEnable("NetDevice");
|
||||
DebugComponentEnable("PacketSocket");
|
||||
#endif
|
||||
|
||||
// Set up some default values for the simulation. Use the Bind()
|
||||
// technique to tell the system what subclass of Queue to use,
|
||||
// and what the queue limit is
|
||||
|
||||
// The below Bind command tells the queue factory which class to
|
||||
// instantiate, when the queue factory is invoked in the topology code
|
||||
Bind ("Queue", "DropTailQueue");
|
||||
|
||||
// Allow the user to override any of the defaults and the above
|
||||
// Bind()s at run-time, via command-line arguments
|
||||
CommandLine::Parse (argc, argv);
|
||||
|
||||
// Here, we will explicitly create four nodes. In more sophisticated
|
||||
// topologies, we could configure a node factory.
|
||||
Ptr<Node> n0 = Create<InternetNode> ();
|
||||
Ptr<Node> n1 = Create<InternetNode> ();
|
||||
Ptr<Node> n2 = Create<InternetNode> ();
|
||||
Ptr<Node> n3 = Create<InternetNode> ();
|
||||
|
||||
// We create the channels first without any IP addressing information
|
||||
Ptr<CsmaCdChannel> channel0 =
|
||||
CsmaCdTopology::CreateCsmaCdChannel(
|
||||
DataRate(5000000), MilliSeconds(2));
|
||||
|
||||
CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0,
|
||||
MacAddress("10:54:23:54:23:50"));
|
||||
CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0,
|
||||
MacAddress("10:54:23:54:23:51"));
|
||||
CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0,
|
||||
MacAddress("10:54:23:54:23:52"));
|
||||
CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0,
|
||||
MacAddress("10:54:23:54:23:53"));
|
||||
|
||||
// Later, we add IP addresses.
|
||||
CsmaCdIpv4Topology::AddIpv4Address (
|
||||
n0, 1, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
|
||||
|
||||
CsmaCdIpv4Topology::AddIpv4Address (
|
||||
n1, 1, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
|
||||
|
||||
CsmaCdIpv4Topology::AddIpv4Address (
|
||||
n2, 1, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
|
||||
|
||||
CsmaCdIpv4Topology::AddIpv4Address (
|
||||
n3, 1, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
|
||||
|
||||
|
||||
// Create the OnOff application to send UDP datagrams of size
|
||||
// 210 bytes at a rate of 448 Kb/s
|
||||
// from n0 to n1
|
||||
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
|
||||
n0,
|
||||
Ipv4Address("10.1.1.2"),
|
||||
80,
|
||||
"Udp",
|
||||
ConstantVariable(1),
|
||||
ConstantVariable(0));
|
||||
// Start the application
|
||||
ooff->Start(Seconds(1.0));
|
||||
ooff->Stop (Seconds(10.0));
|
||||
|
||||
// Create a similar flow from n3 to n0, starting at time 1.1 seconds
|
||||
ooff = Create<OnOffApplication> (
|
||||
n3,
|
||||
Ipv4Address("10.1.1.1"),
|
||||
80,
|
||||
"Udp",
|
||||
ConstantVariable(1),
|
||||
ConstantVariable(0));
|
||||
// Start the application
|
||||
ooff->Start(Seconds(1.1));
|
||||
ooff->Stop (Seconds(10.0));
|
||||
|
||||
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
|
||||
// Trace output will be sent to the simple-p2p.tr file
|
||||
AsciiTrace asciitrace ("simple-csma-cd.tr");
|
||||
asciitrace.TraceAllNetDeviceRx ();
|
||||
// asciitrace.TraceAllQueues ();
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
@@ -54,14 +54,14 @@
|
||||
#include "ns3/ascii-trace.h"
|
||||
#include "ns3/pcap-trace.h"
|
||||
#include "ns3/internet-node.h"
|
||||
#include "ns3/p2p-channel.h"
|
||||
#include "ns3/p2p-net-device.h"
|
||||
#include "ns3/point-to-point-channel.h"
|
||||
#include "ns3/point-to-point-net-device.h"
|
||||
#include "ns3/mac-address.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/ipv4-route.h"
|
||||
#include "ns3/p2p-topology.h"
|
||||
#include "ns3/point-to-point-topology.h"
|
||||
#include "ns3/onoff-application.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
@@ -9,5 +9,6 @@ def build(bld):
|
||||
obj.source = source
|
||||
return obj
|
||||
|
||||
obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['p2p', 'internet-node'])
|
||||
obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['point-to-point', 'internet-node'])
|
||||
obj = create_ns_prog('simple-csma-cd', 'simple-csma-cd.cc', deps=['csma-cd', 'internet-node'])
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ def build(bld):
|
||||
obj = create_ns_prog('main-test', 'main-test.cc')
|
||||
obj = create_ns_prog('main-simple', 'main-simple.cc',
|
||||
deps=['node', 'internet-node', 'applications'])
|
||||
#obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'p2p'])
|
||||
#obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'point-to-point'])
|
||||
obj = create_ns_prog('main-default-value', 'main-default-value.cc',
|
||||
deps=['core', 'simulator', 'node', 'p2p'])
|
||||
deps=['core', 'simulator', 'node', 'point-to-point'])
|
||||
obj = create_ns_prog('main-grid-topology', 'main-grid-topology.cc',
|
||||
deps=['core', 'simulator', 'mobility', 'internet-node'])
|
||||
obj = create_ns_prog('main-random-topology', 'main-random-topology.cc',
|
||||
|
||||
83
src/devices/csma-cd/backoff.cc
Normal file
83
src/devices/csma-cd/backoff.cc
Normal file
@@ -0,0 +1,83 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007, Emmanuelle Laprise
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
|
||||
#include "backoff.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
Backoff::Backoff()
|
||||
{
|
||||
m_slotTime = MicroSeconds(1);
|
||||
m_minSlots = 1;
|
||||
m_maxSlots = 1000;
|
||||
m_ceiling = 10;
|
||||
m_maxRetries = 1000;
|
||||
|
||||
ResetBackoffTime();
|
||||
}
|
||||
|
||||
Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
|
||||
uint32_t ceiling, uint32_t maxRetries)
|
||||
{
|
||||
m_slotTime = slotTime;
|
||||
m_minSlots = minSlots;
|
||||
m_maxSlots = maxSlots;
|
||||
m_ceiling = ceiling;
|
||||
m_maxRetries = maxRetries;
|
||||
}
|
||||
|
||||
Time
|
||||
Backoff::GetBackoffTime (void)
|
||||
{
|
||||
Time backoff;
|
||||
uint32_t ceiling;
|
||||
|
||||
if ((m_ceiling > 0) &&(m_numBackoffRetries > m_ceiling))
|
||||
ceiling = m_ceiling;
|
||||
else
|
||||
ceiling = m_numBackoffRetries;
|
||||
|
||||
uint32_t minSlot = m_minSlots;
|
||||
uint32_t maxSlot = (uint32_t)pow(2, ceiling) - 1;
|
||||
if (maxSlot > m_maxSlots)
|
||||
maxSlot = m_maxSlots;
|
||||
|
||||
uint32_t backoffSlots =
|
||||
(uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot);
|
||||
|
||||
backoff = Scalar(backoffSlots) * m_slotTime;
|
||||
return (backoff);
|
||||
}
|
||||
|
||||
void Backoff::ResetBackoffTime (void)
|
||||
{
|
||||
m_numBackoffRetries = 0;
|
||||
}
|
||||
|
||||
bool Backoff::MaxRetriesReached(void) {
|
||||
return (m_numBackoffRetries >= m_maxRetries);
|
||||
}
|
||||
|
||||
void Backoff::IncrNumRetries(void) {
|
||||
m_numBackoffRetries++;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
87
src/devices/csma-cd/backoff.h
Normal file
87
src/devices/csma-cd/backoff.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
|
||||
* Derived from the p2p net device file
|
||||
Transmi */
|
||||
|
||||
#ifndef BACKOFF_H
|
||||
#define BACKOFF_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/random-variable.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief The backoff class is used for calculating backoff times
|
||||
* when many net devices can write to the same channel
|
||||
*
|
||||
*/
|
||||
|
||||
class Backoff {
|
||||
public:
|
||||
uint32_t m_minSlots; // Minimum number of backoff slots (when
|
||||
// multiplied by m_slotTime, determines minimum
|
||||
// backoff time)
|
||||
uint32_t m_maxSlots; // Maximim number of backoff slots (when
|
||||
// multiplied by m_slotTime, determines
|
||||
// maximum backoff time)
|
||||
uint32_t m_ceiling; // Caps the exponential function when the
|
||||
// number of retries reaches m_ceiling
|
||||
uint32_t m_maxRetries; // Maximum number of transmission retries
|
||||
// before the packet is dropped.
|
||||
Time m_slotTime; // Length of one slot. A slot time, it usually
|
||||
// the packet transmission time, if the packet
|
||||
// size is fixed.
|
||||
|
||||
Backoff();
|
||||
Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
|
||||
uint32_t ceiling, uint32_t maxRetries);
|
||||
|
||||
/**
|
||||
* \return The amount of time that the net device should wait before
|
||||
* trying to retransmit the packet
|
||||
*/
|
||||
Time GetBackoffTime();
|
||||
/**
|
||||
* Indicates to the backoff object that the last packet was
|
||||
* successfully transmitted and that the number of retries should be
|
||||
* reset to 0.
|
||||
*/
|
||||
void ResetBackoffTime();
|
||||
/**
|
||||
* \return True if the maximum number of retries has been reached
|
||||
*/
|
||||
bool MaxRetriesReached();
|
||||
/**
|
||||
* Increments the number of retries by 1.
|
||||
*/
|
||||
void IncrNumRetries();
|
||||
|
||||
private:
|
||||
uint32_t m_numBackoffRetries; // Number of times that the
|
||||
// transmitter has tried to
|
||||
// unsuccessfully transmit the current
|
||||
// packet
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif // BACKOFF_H
|
||||
|
||||
359
src/devices/csma-cd/csma-cd-channel.cc
Normal file
359
src/devices/csma-cd/csma-cd-channel.cc
Normal file
@@ -0,0 +1,359 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
|
||||
#include "csma-cd-channel.h"
|
||||
#include "csma-cd-net-device.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/debug.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("CsmaCdChannel");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
CsmaCdDeviceRec::CsmaCdDeviceRec()
|
||||
{
|
||||
active = false;
|
||||
}
|
||||
|
||||
CsmaCdDeviceRec::CsmaCdDeviceRec(Ptr<CsmaCdNetDevice> device)
|
||||
{
|
||||
devicePtr = device;
|
||||
active = true;
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdDeviceRec::IsActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// By default, you get a channel with the name "CsmaCd Channel" that
|
||||
// has an "infitely" fast transmission speed and zero delay.
|
||||
CsmaCdChannel::CsmaCdChannel()
|
||||
:
|
||||
Channel ("CsmaCd Channel"),
|
||||
m_bps (DataRate(0xffffffff)),
|
||||
m_delay (Seconds(0))
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::CsmaCdChannel ()");
|
||||
Init();
|
||||
}
|
||||
|
||||
CsmaCdChannel::CsmaCdChannel(
|
||||
const DataRate& bps,
|
||||
const Time& delay)
|
||||
:
|
||||
Channel ("CsmaCd Channel"),
|
||||
m_bps (bps),
|
||||
m_delay (delay)
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << Channel::GetName()
|
||||
<< ", " << bps.GetBitRate() << ", " << delay << ")");
|
||||
Init();
|
||||
}
|
||||
|
||||
CsmaCdChannel::CsmaCdChannel(
|
||||
const std::string& name,
|
||||
const DataRate& bps,
|
||||
const Time& delay)
|
||||
:
|
||||
Channel (name),
|
||||
m_bps (bps),
|
||||
m_delay (delay)
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << name << ", " <<
|
||||
bps.GetBitRate() << ", " << delay << ")");
|
||||
Init();
|
||||
}
|
||||
|
||||
void CsmaCdChannel::Init() {
|
||||
m_state = IDLE;
|
||||
m_deviceList.clear();
|
||||
}
|
||||
|
||||
int32_t
|
||||
CsmaCdChannel::Attach(Ptr<CsmaCdNetDevice> device)
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::Attach (" << device << ")");
|
||||
NS_ASSERT(device != 0);
|
||||
|
||||
CsmaCdDeviceRec rec(device);
|
||||
|
||||
m_deviceList.push_back(rec);
|
||||
return (m_deviceList.size() - 1);
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdChannel::Reattach(Ptr<CsmaCdNetDevice> device)
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::Reattach (" << device << ")");
|
||||
NS_ASSERT(device != 0);
|
||||
|
||||
std::vector<CsmaCdDeviceRec>::iterator it;
|
||||
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
|
||||
{
|
||||
if (it->devicePtr == device)
|
||||
{
|
||||
if (!it->active) {
|
||||
it->active = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdChannel::Reattach(uint32_t deviceId)
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::Reattach (" << deviceId << ")");
|
||||
if (deviceId < m_deviceList.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_deviceList[deviceId].active)
|
||||
{
|
||||
return false;
|
||||
} else {
|
||||
m_deviceList[deviceId].active = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdChannel::Detach(uint32_t deviceId)
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::Detach (" << deviceId << ")");
|
||||
|
||||
if (deviceId < m_deviceList.size())
|
||||
{
|
||||
if (!m_deviceList[deviceId].active)
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::Detach Device is already detached ("
|
||||
<< deviceId << ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_deviceList[deviceId].active = false;
|
||||
if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::Detach Device is currently"
|
||||
<< "transmitting (" << deviceId << ")");
|
||||
// Here we will need to place a warning in the packet
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdChannel::Detach(Ptr<CsmaCdNetDevice> device)
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::Detach (" << device << ")");
|
||||
NS_ASSERT(device != 0);
|
||||
|
||||
std::vector<CsmaCdDeviceRec>::iterator it;
|
||||
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
|
||||
{
|
||||
if ((it->devicePtr == device) && (it->active))
|
||||
{
|
||||
it->active = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdChannel::TransmitStart(Packet& p, uint32_t srcId)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdChannel::TransmitStart (" << &p << ", " << srcId
|
||||
<< ")");
|
||||
NS_DEBUG ("CsmaCdChannel::TransmitStart (): UID is " <<
|
||||
p.GetUid () << ")");
|
||||
|
||||
if (m_state != IDLE)
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::TransmitStart (): state is not IDLE");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsActive(srcId))
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::TransmitStart (): ERROR: Seclected "
|
||||
<< "source is not currently attached to network");
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_DEBUG("CsmaCdChannel::TransmitStart (): switch to TRANSMITTING");
|
||||
m_currentPkt = p;
|
||||
m_currentSrc = srcId;
|
||||
m_state = TRANSMITTING;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdChannel::IsActive(uint32_t deviceId) {
|
||||
return (m_deviceList[deviceId].active);
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdChannel::TransmitEnd()
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::TransmitEnd (" << &m_currentPkt << ", "
|
||||
<< m_currentSrc << ")");
|
||||
NS_DEBUG("CsmaCdChannel::TransmitEnd (): UID is " <<
|
||||
m_currentPkt.GetUid () << ")");
|
||||
|
||||
NS_ASSERT(m_state == TRANSMITTING);
|
||||
m_state = PROPAGATING;
|
||||
|
||||
bool retVal = true;
|
||||
|
||||
if (!IsActive(m_currentSrc)) {
|
||||
NS_DEBUG("CsmaCdChannel::TransmitEnd (): ERROR: Seclected source "
|
||||
<< "was detached before the end of the transmission");
|
||||
retVal = false;
|
||||
}
|
||||
|
||||
NS_DEBUG ("CsmaCdChannel::TransmitEnd (): Schedule event in " <<
|
||||
m_delay.GetSeconds () << "sec");
|
||||
|
||||
Simulator::Schedule (m_delay,
|
||||
&CsmaCdChannel::PropagationCompleteEvent,
|
||||
this);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdChannel::PropagationCompleteEvent()
|
||||
{
|
||||
NS_DEBUG("CsmaCdChannel::PropagationCompleteEvent ("
|
||||
<< &m_currentPkt << ")");
|
||||
NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): UID is " <<
|
||||
m_currentPkt.GetUid () << ")");
|
||||
|
||||
NS_ASSERT(m_state == PROPAGATING);
|
||||
m_state = IDLE;
|
||||
|
||||
NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): Receive");
|
||||
|
||||
std::vector<CsmaCdDeviceRec>::iterator it;
|
||||
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
|
||||
{
|
||||
if (it->IsActive())
|
||||
{
|
||||
it->devicePtr->Receive (m_currentPkt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
CsmaCdChannel::GetNumActDevices (void)
|
||||
{
|
||||
int numActDevices = 0;
|
||||
std::vector<CsmaCdDeviceRec>::iterator it;
|
||||
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
|
||||
{
|
||||
if (it->active)
|
||||
{
|
||||
numActDevices++;
|
||||
}
|
||||
}
|
||||
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
|
||||
CsmaCdChannel::GetNDevices (void) const
|
||||
{
|
||||
return (m_deviceList.size());
|
||||
}
|
||||
|
||||
Ptr<NetDevice>
|
||||
CsmaCdChannel::GetDevice (uint32_t i) const
|
||||
{
|
||||
Ptr< CsmaCdNetDevice > netDevice;
|
||||
|
||||
netDevice = m_deviceList[i].devicePtr;
|
||||
return netDevice;
|
||||
}
|
||||
|
||||
int32_t
|
||||
CsmaCdChannel::GetDeviceNum (Ptr<CsmaCdNetDevice> device)
|
||||
{
|
||||
std::vector<CsmaCdDeviceRec>::iterator it;
|
||||
int i = 0;
|
||||
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
|
||||
{
|
||||
if (it->devicePtr == device)
|
||||
{
|
||||
if (it->active)
|
||||
{
|
||||
return i;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdChannel::IsBusy (void)
|
||||
{
|
||||
if (m_state == IDLE)
|
||||
{
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
DataRate
|
||||
CsmaCdChannel::GetDataRate (void)
|
||||
{
|
||||
return m_bps;
|
||||
}
|
||||
|
||||
Time
|
||||
CsmaCdChannel::GetDelay (void)
|
||||
{
|
||||
return m_delay;
|
||||
}
|
||||
|
||||
WireState
|
||||
CsmaCdChannel::GetState(void)
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
307
src/devices/csma-cd/csma-cd-channel.h
Normal file
307
src/devices/csma-cd/csma-cd-channel.h
Normal file
@@ -0,0 +1,307 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
|
||||
#ifndef CSMA_CD_CHANNEL_H
|
||||
#define CSMA_CD_CHANNEL_H
|
||||
|
||||
#include "ns3/channel.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/data-rate.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class CsmaCdNetDevice;
|
||||
|
||||
/**
|
||||
* \brief CsmaCdNetDevice Record
|
||||
*
|
||||
* Stores the information related to each net device that is
|
||||
* connected to the channel.
|
||||
*/
|
||||
class CsmaCdDeviceRec {
|
||||
public:
|
||||
Ptr< CsmaCdNetDevice > devicePtr; /// Pointer to the net device
|
||||
bool active; /// Is net device enabled to TX/RX
|
||||
|
||||
CsmaCdDeviceRec();
|
||||
CsmaCdDeviceRec(Ptr< CsmaCdNetDevice > device);
|
||||
/*
|
||||
* \return If the net device pointed to by the devicePtr is active
|
||||
* and ready to RX/TX.
|
||||
*/
|
||||
bool IsActive();
|
||||
};
|
||||
|
||||
/**
|
||||
* Current state of the channel
|
||||
*/
|
||||
enum WireState
|
||||
{
|
||||
IDLE, /**< Channel is IDLE, no packet is being
|
||||
transmitted */
|
||||
TRANSMITTING, /**< Channel is BUSY, a packet is being written
|
||||
by a net device */
|
||||
PROPAGATING /**< Channel is BUSY, packet is propagating to
|
||||
all attached net devices */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief CsmaCd Channel.
|
||||
*
|
||||
* This class represents a simple Csma/Cd channel that can be used
|
||||
* when many nodes are connected to one wire. It uses a single busy
|
||||
* 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 CsmaCdChannel : public Channel {
|
||||
public:
|
||||
/**
|
||||
* \brief Create a CsmaCdChannel
|
||||
*
|
||||
* By default, you get a channel with the name "CsmaCd Channel" that
|
||||
* has an "infitely" fast transmission speed and zero delay.
|
||||
*/
|
||||
CsmaCdChannel ();
|
||||
|
||||
/**
|
||||
* \brief Create a CsmaCdChannel
|
||||
*
|
||||
* \param bps The bitrate of the channel
|
||||
* \param delay Transmission delay through the channel
|
||||
*/
|
||||
CsmaCdChannel (const DataRate& bps, const Time& delay);
|
||||
|
||||
/**
|
||||
* \brief Create a CsmaCdChannel
|
||||
*
|
||||
* \param name the name of the channel for identification purposes
|
||||
* \param bps The bitrate of the channel
|
||||
* \param delay Transmission delay through the channel
|
||||
*/
|
||||
CsmaCdChannel (const std::string& name,
|
||||
const DataRate& bps, const Time& delay);
|
||||
|
||||
/**
|
||||
* \brief Attach a given netdevice to this channel
|
||||
*
|
||||
* \param device Device pointer to the netdevice to attach to the channel
|
||||
* \return The assigned device number
|
||||
*/
|
||||
int32_t Attach (Ptr<CsmaCdNetDevice> device);
|
||||
/**
|
||||
* \brief Detach a given netdevice from this channel
|
||||
*
|
||||
* The net device is marked as inactive and it is not allowed to
|
||||
* receive or transmit packets
|
||||
*
|
||||
* \param device Device pointer to the netdevice to detach from the channel
|
||||
* \return True if the device is found and attached to the channel,
|
||||
* false if the device is not currently connected to the channel or
|
||||
* can't be found.
|
||||
*/
|
||||
bool Detach (Ptr<CsmaCdNetDevice> device);
|
||||
/**
|
||||
* \brief Detach a given netdevice from this channel
|
||||
*
|
||||
* The net device is marked as inactive and it is not allowed to
|
||||
* receive or transmit packets
|
||||
*
|
||||
* \param deviceId The deviceID assigned to the net device when it
|
||||
* was connected to the channel
|
||||
* \return True if the device is found and attached to the channel,
|
||||
* false if the device is not currently connected to the channel or
|
||||
* can't be found.
|
||||
*/
|
||||
bool Detach (uint32_t deviceId);
|
||||
/**
|
||||
* \brief Reattach a previously detached net device to the channel
|
||||
*
|
||||
* The net device is marked as active. It is now allowed to receive
|
||||
* or transmit packets. The net device must have been previously
|
||||
* attached to the channel using the attach function.
|
||||
*
|
||||
* \param deviceId The device ID assigned to the net device when it
|
||||
* was connected to the channel
|
||||
* \return True if the device is found and is not attached to the
|
||||
* channel, false if the device is currently connected to the
|
||||
* channel or can't be found.
|
||||
*/
|
||||
bool Reattach(uint32_t deviceId);
|
||||
/**
|
||||
* \brief Reattach a previously detached net device to the channel
|
||||
*
|
||||
* The net device is marked as active. It is now allowed to receive
|
||||
* or transmit packets. The net device must have been previously
|
||||
* attached to the channel using the attach function.
|
||||
*
|
||||
* \param device Device pointer to the netdevice to detach from the channel
|
||||
* \return True if the device is found and is not attached to the
|
||||
* channel, false if the device is currently connected to the
|
||||
* channel or can't be found.
|
||||
*/
|
||||
bool Reattach(Ptr<CsmaCdNetDevice> device);
|
||||
/**
|
||||
* \brief Start transmitting a packet over the channel
|
||||
*
|
||||
* If the srcId belongs to a net device that is connected to the
|
||||
* channel, packet transmission begins, and the channel becomes busy
|
||||
* until the packet has completely reached all destinations.
|
||||
*
|
||||
* \param p A reference to the packet that will be transmitted over
|
||||
* the channel
|
||||
* \param srcId The device Id of the net device that wants to
|
||||
* transmit on the channel.
|
||||
* \return True if the channel is not busy and the transmitting net
|
||||
* device is currently active.
|
||||
*/
|
||||
bool TransmitStart (Packet& p, uint32_t srcId);
|
||||
/**
|
||||
* \brief Indicates that the net device has finished transmitting
|
||||
* the packet over the channel
|
||||
*
|
||||
* The channel will stay busy until the packet has completely
|
||||
* propagated to all net devices attached to the channel. The
|
||||
* TransmitEnd function schedules the PropagationCompleteEvent which
|
||||
* will free the channel for further transmissions. Stores the
|
||||
* packet p as the m_currentPkt, the packet being currently
|
||||
* transmitting.
|
||||
*
|
||||
* \return Returns true unless the source was detached before it
|
||||
* completed its transmission.
|
||||
*/
|
||||
bool TransmitEnd ();
|
||||
/**
|
||||
* \brief Indicates that the channel has finished propagating the
|
||||
* current packet. The channel is released and becomes free.
|
||||
*
|
||||
* Calls the receive function of every active net device that is
|
||||
* attached to the channel.
|
||||
*/
|
||||
void PropagationCompleteEvent();
|
||||
/**
|
||||
* \return Returns the device number assigned to a net device by the
|
||||
* channel
|
||||
*
|
||||
* \param device Device pointer to the netdevice for which the device
|
||||
* number is needed
|
||||
*/
|
||||
int32_t GetDeviceNum (Ptr<CsmaCdNetDevice> device);
|
||||
/**
|
||||
* \return Returns the state of the channel (IDLE -- free,
|
||||
* TRANSMITTING -- busy, PROPAGATING - busy )
|
||||
*/
|
||||
WireState GetState();
|
||||
|
||||
/**
|
||||
* \brief Indicates if the channel is busy. The channel will only
|
||||
* accept new packets for transmission if it is not busy.
|
||||
*
|
||||
* \return Returns true if the channel is busy and false if it is
|
||||
* free.
|
||||
*/
|
||||
bool IsBusy();
|
||||
|
||||
/**
|
||||
* \brief Indicates if a net device is currently attached or
|
||||
* detached from the channel.
|
||||
*
|
||||
* \param deviceId The ID that was assigned to the net device when
|
||||
* it was attached to the channel.
|
||||
* \return Returns true if the net device is attached to the
|
||||
* channel, false otherwise.
|
||||
*/
|
||||
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;
|
||||
/**
|
||||
* \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
|
||||
* with deviceId i.
|
||||
*/
|
||||
virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
|
||||
|
||||
virtual DataRate GetDataRate (void);
|
||||
virtual Time GetDelay (void);
|
||||
|
||||
private:
|
||||
DataRate m_bps; /// Data rate of the channel
|
||||
Time m_delay; /// Delay of the channel.
|
||||
|
||||
/**
|
||||
* List of the net devices that have been or are currently connected
|
||||
* to the channel.
|
||||
*
|
||||
* Devices are nor removed from this list, they are marked as
|
||||
* inactive. Otherwise the assigned device IDs will not refer to the
|
||||
* correct NetDevice. The DeviceIds are used so that it is possible
|
||||
* to have a number to refer to an entry in the list so that the
|
||||
* 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< CsmaCdDeviceRec > m_deviceList;
|
||||
/**
|
||||
* Packet that is currently being transmitted on the channel (or last
|
||||
* packet to have been transmitted on the channel if the channel is
|
||||
* free.)
|
||||
*/
|
||||
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
|
||||
*/
|
||||
WireState m_state;
|
||||
/**
|
||||
* Initializes the channel when it is constructed. Resets the
|
||||
* deviceList and sets the channel state to IDLE.
|
||||
*/
|
||||
void Init (void);
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* CSMA_CD_CHANNEL_H */
|
||||
162
src/devices/csma-cd/csma-cd-ipv4-topology.cc
Normal file
162
src/devices/csma-cd/csma-cd-ipv4-topology.cc
Normal file
@@ -0,0 +1,162 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2007 Emmanuelle Laprise
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation;
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/fatal-error.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/internet-node.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/queue.h"
|
||||
|
||||
#include "csma-cd-channel.h"
|
||||
#include "csma-cd-net-device.h"
|
||||
#include "csma-cd-ipv4-topology.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
void
|
||||
CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
|
||||
Ptr<CsmaCdChannel> ch,
|
||||
MacAddress addr)
|
||||
{
|
||||
Ptr<Queue> q = Queue::CreateDefault ();
|
||||
|
||||
// Use the first net device in the node to transmit
|
||||
Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
|
||||
ns3::CsmaCdNetDevice::IP_ARP,
|
||||
true, false);
|
||||
nd0->AddQueue(q);
|
||||
nd0->Attach (ch);
|
||||
|
||||
// Use the second net device in the node to transmit
|
||||
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
|
||||
ns3::CsmaCdNetDevice::IP_ARP,
|
||||
false, true);
|
||||
nd1->AddQueue(q);
|
||||
nd1->Attach (ch);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr<Node> n1,
|
||||
Ptr<CsmaCdChannel> ch,
|
||||
MacAddress addr)
|
||||
{
|
||||
Ptr<Queue> q = Queue::CreateDefault ();
|
||||
|
||||
Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
|
||||
ns3::CsmaCdNetDevice::LLC,
|
||||
true, false);
|
||||
nd0->AddQueue(q);
|
||||
nd0->Attach (ch);
|
||||
|
||||
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
|
||||
ns3::CsmaCdNetDevice::LLC,
|
||||
false, true);
|
||||
nd1->AddQueue(q);
|
||||
nd1->Attach (ch);
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr<Node> n1,
|
||||
Ptr<CsmaCdChannel> ch,
|
||||
MacAddress addr)
|
||||
{
|
||||
Ptr<Queue> q = Queue::CreateDefault ();
|
||||
|
||||
Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
|
||||
ns3::CsmaCdNetDevice::RAW,
|
||||
true, false);
|
||||
nd0->AddQueue(q);
|
||||
nd0->Attach (ch);
|
||||
|
||||
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
|
||||
ns3::CsmaCdNetDevice::RAW,
|
||||
false, true);
|
||||
nd1->AddQueue(q);
|
||||
nd1->Attach (ch);
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdIpv4Topology::AddIpv4Address(Ptr<Node> n1,
|
||||
int ndNum,
|
||||
const Ipv4Address& addr1,
|
||||
const Ipv4Mask& netmask1)
|
||||
{
|
||||
|
||||
// Duplex link is assumed to be subnetted as a /30
|
||||
// May run this unnumbered in the future?
|
||||
Ipv4Mask netmask(netmask1);
|
||||
|
||||
Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
|
||||
|
||||
Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
uint32_t index1 = ip1->AddInterface (nd1);
|
||||
|
||||
ip1->SetAddress (index1, addr1);
|
||||
ip1->SetNetworkMask (index1, netmask);
|
||||
ip1->SetUp (index1);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdIpv4Topology::AddIpv4Routes (
|
||||
Ptr<NetDevice> nd1, Ptr<NetDevice> nd2)
|
||||
{
|
||||
// Assert that both are Ipv4 nodes
|
||||
Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
NS_ASSERT(ip1 != 0 && ip2 != 0);
|
||||
|
||||
// Get interface indexes for both nodes corresponding to the right channel
|
||||
uint32_t index1 = 0;
|
||||
bool found = false;
|
||||
for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
|
||||
{
|
||||
if (ip1 ->GetNetDevice (i) == nd1)
|
||||
{
|
||||
index1 = i;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
NS_ASSERT(found);
|
||||
|
||||
uint32_t index2 = 0;
|
||||
found = false;
|
||||
for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
|
||||
{
|
||||
if (ip2 ->GetNetDevice (i) == nd2)
|
||||
{
|
||||
index2 = i;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
NS_ASSERT(found);
|
||||
|
||||
ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
|
||||
ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
120
src/devices/csma-cd/csma-cd-ipv4-topology.h
Normal file
120
src/devices/csma-cd/csma-cd-ipv4-topology.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2007 Emmanuelle Laprise
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation;
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
//
|
||||
|
||||
#ifndef __CSMA_CD_IPV4_TOPOLOGY_H__
|
||||
#define __CSMA_CD_IPV4_TOPOLOGY_H__
|
||||
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/ipv4-route.h"
|
||||
#include "ns3/internet-node.h"
|
||||
#include "ns3/csma-cd-net-device.h"
|
||||
|
||||
// The topology class consists of only static methods thar are used to
|
||||
// create the topology and data flows for an ns3 simulation
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class CsmaCdIpv4Channel;
|
||||
class Node;
|
||||
class IPAddr;
|
||||
class DataRate;
|
||||
class Queue;
|
||||
|
||||
/**
|
||||
* \brief A helper class to create Topologies based on the
|
||||
* InternetNodes and CsmaCdChannels. Either the
|
||||
* SimpleCsmaCdNetDevice or the LLCCsmaCdNetDevice can be used
|
||||
* when constructing these topologies.
|
||||
*/
|
||||
class CsmaCdIpv4Topology {
|
||||
public:
|
||||
|
||||
/**
|
||||
* \param n1 Node to be attached to the Csma/Cd channel
|
||||
* \param ch CsmaCdChannel to which node n1 should be attached
|
||||
* \param addr Mac address of the node
|
||||
*
|
||||
* Add a Csma/Cd node to a Csma/Cd channel. This function adds
|
||||
* a EthernetCsmaCdNetDevice to the nodes so that they can
|
||||
* connect to a CsmaCdChannel. This means that Ethernet headers
|
||||
* and trailers will be added to the packet before sending out on
|
||||
* the net device.
|
||||
*/
|
||||
static void AddIpv4CsmaCdNode( Ptr<Node> n1,
|
||||
Ptr<CsmaCdChannel> ch,
|
||||
MacAddress addr);
|
||||
|
||||
/**
|
||||
* \param n1 Node to be attached to the Csma/Cd channel
|
||||
* \param ch CsmaCdChannel to which node n1 should be attached
|
||||
* \param addr Mac address of the node
|
||||
*
|
||||
* Add a Csma/Cd node to a Csma/Cd channel. This function adds
|
||||
* a RawCsmaCdNetDevice to the nodes so that they can connect
|
||||
* to a CsmaCdChannel.
|
||||
*/
|
||||
static void AddIpv4RawCsmaCdNode( Ptr<Node> n1,
|
||||
Ptr<CsmaCdChannel> ch,
|
||||
MacAddress addr);
|
||||
|
||||
/**
|
||||
* \param n1 Node to be attached to the Csma/Cd channel
|
||||
* \param ch CsmaCdChannel to which node n1 should be attached
|
||||
* \param addr Mac address of the node
|
||||
*
|
||||
* Add a Csma/Cd node to a Csma/Cd channel. This function adds
|
||||
* a LlcCsmaCdNetDevice to the nodes so that they can connect
|
||||
* to a CsmaCdChannel.
|
||||
*/
|
||||
static void AddIpv4LlcCsmaCdNode( Ptr<Node> n1,
|
||||
Ptr<CsmaCdChannel> ch,
|
||||
MacAddress addr);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \param n1 Node
|
||||
* \param ndNum NetDevice number with which to associate address
|
||||
* \param addr1 Ipv4 Address for ndNum of n1
|
||||
* \param network network mask for ndNum of node n1
|
||||
*
|
||||
* Add an Ipv4Address to the Ipv4 interface associated with the
|
||||
* ndNum CsmaCdIpv4NetDevices on the provided
|
||||
* CsmaCdIpv4Channel
|
||||
*/
|
||||
static void AddIpv4Address(Ptr<Node> n1, int ndNum,
|
||||
const Ipv4Address& addr1,
|
||||
const Ipv4Mask& netmask1);
|
||||
|
||||
/**
|
||||
* \param nd1 Node
|
||||
* \param nd2 Node
|
||||
*
|
||||
* Add an IPV4 host route between the two specified net devices
|
||||
*/
|
||||
static void AddIpv4Routes (Ptr<NetDevice> nd1, Ptr<NetDevice> nd2);
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif
|
||||
|
||||
504
src/devices/csma-cd/csma-cd-net-device.cc
Normal file
504
src/devices/csma-cd/csma-cd-net-device.cc
Normal file
@@ -0,0 +1,504 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/queue.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/composite-trace-resolver.h"
|
||||
#include "csma-cd-net-device.h"
|
||||
#include "csma-cd-channel.h"
|
||||
#include "ns3/ethernet-header.h"
|
||||
#include "ns3/ethernet-trailer.h"
|
||||
#include "ns3/llc-snap-header.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("CsmaCdNetDevice");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
|
||||
CsmaCdEncapsulationMode pktType)
|
||||
: NetDevice(node, addr), m_bps (DataRate (0xffffffff))
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
|
||||
m_pktType = pktType;
|
||||
|
||||
Init(true, true);
|
||||
}
|
||||
|
||||
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
|
||||
CsmaCdEncapsulationMode pktType,
|
||||
bool sendEnable, bool receiveEnable)
|
||||
: NetDevice(node, addr), m_bps (DataRate (0xffffffff))
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
|
||||
m_pktType = pktType;
|
||||
|
||||
Init(sendEnable, receiveEnable);
|
||||
}
|
||||
|
||||
CsmaCdNetDevice::~CsmaCdNetDevice()
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::~CsmaCdNetDevice ()");
|
||||
m_queue = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy constructor for CsmaCdNetDevice.
|
||||
//
|
||||
// We use the underlying NetDevice copy constructor to get the base class
|
||||
// copied. These just remain as is (e.g. you get the same name, the same
|
||||
// MAC address). If you need to fix them up, YOU, the copier need to do
|
||||
// that.
|
||||
//
|
||||
// The things we need to be careful of are the channel, the queue and the
|
||||
// trace callback. If the channel pointer is non-zero, we copy the pointer
|
||||
// and add a reference. If the queue is non-zero, we copy it using the queue
|
||||
// assignment operator. We don't mess with the trace -- we just reset it.
|
||||
// We're assuming that the tracing will be set up after the topology creation
|
||||
// phase and this won't actually matter.
|
||||
//
|
||||
|
||||
CsmaCdNetDevice::CsmaCdNetDevice (const CsmaCdNetDevice& nd)
|
||||
: NetDevice(nd), m_bps (nd.m_bps)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << &nd << ")");
|
||||
|
||||
m_txMachineState = READY;
|
||||
m_tInterframeGap = nd.m_tInterframeGap;
|
||||
m_backoff = nd.m_backoff;
|
||||
m_channel = nd.m_channel;
|
||||
m_queue = 0;
|
||||
m_pktType = nd.m_pktType;
|
||||
m_sendEnable = nd.m_sendEnable;
|
||||
m_receiveEnable = nd.m_receiveEnable;
|
||||
|
||||
if (nd.m_queue)
|
||||
{
|
||||
m_queue = nd.m_queue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::DoDispose ()
|
||||
{
|
||||
m_channel = 0;
|
||||
NetDevice::DoDispose ();
|
||||
}
|
||||
|
||||
//
|
||||
// Assignment operator for CsmaCdNetDevice.
|
||||
//
|
||||
// This uses the non-obvious trick of taking the source net device passed by
|
||||
// value instead of by reference. This causes the copy constructor to be
|
||||
// invoked (where the real work is done -- see above). All we have to do
|
||||
// here is to return the newly constructed net device.
|
||||
//
|
||||
/*
|
||||
CsmaCdNetDevice&
|
||||
CsmaCdNetDevice::operator= (const CsmaCdNetDevice nd)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::operator= (" << &nd << ")");
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable)
|
||||
{
|
||||
m_txMachineState = READY;
|
||||
m_tInterframeGap = Seconds(0);
|
||||
m_channel = 0;
|
||||
m_queue = 0;
|
||||
|
||||
EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
|
||||
EnableMulticast();
|
||||
EnablePointToPoint();
|
||||
|
||||
SetSendEnable (sendEnable);
|
||||
SetReceiveEnable (receiveEnable);
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::SetSendEnable (bool sendEnable)
|
||||
{
|
||||
m_sendEnable = sendEnable;
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::SetReceiveEnable (bool receiveEnable)
|
||||
{
|
||||
m_receiveEnable = receiveEnable;
|
||||
}
|
||||
bool
|
||||
CsmaCdNetDevice::IsSendEnabled (void)
|
||||
{
|
||||
return (m_sendEnable);
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdNetDevice::IsReceiveEnabled (void)
|
||||
{
|
||||
return (m_receiveEnable);
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::SetDataRate (DataRate bps)
|
||||
{
|
||||
m_bps = bps;
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::SetInterframeGap (Time t)
|
||||
{
|
||||
m_tInterframeGap = t;
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots,
|
||||
uint32_t maxSlots, uint32_t ceiling,
|
||||
uint32_t maxRetries)
|
||||
{
|
||||
m_backoff.m_slotTime = slotTime;
|
||||
m_backoff.m_minSlots = minSlots;
|
||||
m_backoff.m_maxSlots = maxSlots;
|
||||
m_backoff.m_ceiling = ceiling;
|
||||
m_backoff.m_maxRetries = maxRetries;
|
||||
}
|
||||
void
|
||||
CsmaCdNetDevice::AddHeader (Packet& p, const MacAddress& dest,
|
||||
uint16_t protocolNumber)
|
||||
{
|
||||
if ((m_pktType == ETHERNET_V1) || (m_pktType == IP_ARP))
|
||||
{
|
||||
EthernetHeader header;
|
||||
EthernetTrailer trailer;
|
||||
|
||||
header.SetSource(this->GetAddress());
|
||||
header.SetDestination(dest);
|
||||
switch (m_pktType)
|
||||
{
|
||||
case IP_ARP:
|
||||
header.SetLengthType(protocolNumber);
|
||||
break;
|
||||
default:
|
||||
header.SetLengthType(p.GetSize() + header.GetSize() + trailer.GetSize());
|
||||
break;
|
||||
}
|
||||
p.AddHeader(header);
|
||||
trailer.CalcFcs(p);
|
||||
p.AddTrailer(trailer);
|
||||
}
|
||||
else if (m_pktType == LLC)
|
||||
{
|
||||
LlcSnapHeader llc;
|
||||
llc.SetType (protocolNumber);
|
||||
p.AddHeader (llc);
|
||||
}
|
||||
}
|
||||
bool
|
||||
CsmaCdNetDevice::ProcessHeader(Packet& p, int& param)
|
||||
{
|
||||
bool retVal = true;
|
||||
|
||||
if ((m_pktType == ETHERNET_V1) || (m_pktType == IP_ARP))
|
||||
{
|
||||
EthernetHeader header;
|
||||
EthernetTrailer trailer;
|
||||
|
||||
p.RemoveTrailer(trailer);
|
||||
trailer.CheckFcs(p);
|
||||
p.RemoveHeader(header);
|
||||
|
||||
param = header.GetLengthType();
|
||||
if ((header.GetDestination() != this->GetBroadcast()) &&
|
||||
(header.GetDestination() != this->GetAddress()))
|
||||
{
|
||||
retVal = false;
|
||||
}
|
||||
}
|
||||
else if (m_pktType == LLC)
|
||||
{
|
||||
LlcSnapHeader llc;
|
||||
p.RemoveHeader (llc);
|
||||
|
||||
param = llc.GetType ();
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdNetDevice::DoNeedsArp (void) const
|
||||
{
|
||||
if ((m_pktType == IP_ARP) || (m_pktType == LLC))
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdNetDevice::SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")");
|
||||
NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")");
|
||||
|
||||
NS_ASSERT (IsLinkUp ());
|
||||
|
||||
// Only transmit if send side of net device is enabled
|
||||
if (!IsSendEnabled())
|
||||
return false;
|
||||
|
||||
AddHeader(p, dest, protocolNumber);
|
||||
|
||||
// Place the packet to be sent on the send queue
|
||||
if (m_queue->Enqueue(p) == 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
|
||||
if (m_queue->Dequeue (m_currentPkt))
|
||||
{
|
||||
TransmitStart();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::TransmitStart ()
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (" << &m_currentPkt << ")");
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): UID is "
|
||||
<< m_currentPkt.GetUid () << ")");
|
||||
//
|
||||
// This function is called to start the process of transmitting a packet.
|
||||
// We need to tell the channel that we've started wiggling the wire and
|
||||
// schedule an event that will be executed when it's time to tell the
|
||||
// channel that we're done wiggling the wire.
|
||||
//
|
||||
NS_ASSERT_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;
|
||||
|
||||
if (m_channel->GetState() != IDLE)
|
||||
{ // Channel busy, backoff and rechedule TransmitStart()
|
||||
m_txMachineState = BACKOFF;
|
||||
if (m_backoff.MaxRetriesReached())
|
||||
{ // Too many retries reached, abort transmission of packet
|
||||
TransmitAbort();
|
||||
} else {
|
||||
m_backoff.IncrNumRetries();
|
||||
Time backoffTime = m_backoff.GetBackoffTime();
|
||||
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): "
|
||||
<< "Channel busy, backing off for "
|
||||
<< backoffTime.GetSeconds () << "sec");
|
||||
|
||||
Simulator::Schedule (backoffTime,
|
||||
&CsmaCdNetDevice::TransmitStart,
|
||||
this);
|
||||
}
|
||||
} else {
|
||||
// Channel is free, transmit packet
|
||||
m_txMachineState = BUSY;
|
||||
Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
|
||||
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
|
||||
"Schedule TransmitCompleteEvent in " <<
|
||||
tEvent.GetSeconds () << "sec");
|
||||
|
||||
Simulator::Schedule (tEvent,
|
||||
&CsmaCdNetDevice::TransmitCompleteEvent,
|
||||
this);
|
||||
if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
|
||||
"Channel transmit start did not work at " <<
|
||||
tEvent.GetSeconds () << "sec");
|
||||
m_txMachineState = READY;
|
||||
} else {
|
||||
// Transmission success, reset backoff time parameters.
|
||||
m_backoff.ResetBackoffTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::TransmitAbort (void)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitAbort ()");
|
||||
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitAbort (): Pkt UID is " <<
|
||||
m_currentPkt.GetUid () << ")");
|
||||
|
||||
// Try to transmit a new packet
|
||||
bool found;
|
||||
found = m_queue->Dequeue (m_currentPkt);
|
||||
NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
|
||||
m_backoff.ResetBackoffTime();
|
||||
m_txMachineState = READY;
|
||||
TransmitStart ();
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::TransmitCompleteEvent (void)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent ()");
|
||||
//
|
||||
// This function is called to finish the process of transmitting a packet.
|
||||
// We need to tell the channel that we've stopped wiggling the wire and
|
||||
// schedule an event that will be executed when it's time to re-enable
|
||||
// the transmitter after the interframe gap.
|
||||
//
|
||||
NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
|
||||
// Channel should be transmitting
|
||||
NS_ASSERT(m_channel->GetState() == TRANSMITTING);
|
||||
m_txMachineState = GAP;
|
||||
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent (): Pkt UID is " <<
|
||||
m_currentPkt.GetUid () << ")");
|
||||
m_channel->TransmitEnd ();
|
||||
|
||||
NS_DEBUG (
|
||||
"CsmaCdNetDevice::TransmitCompleteEvent (): " <<
|
||||
"Schedule TransmitReadyEvent in "
|
||||
<< m_tInterframeGap.GetSeconds () << "sec");
|
||||
|
||||
Simulator::Schedule (m_tInterframeGap,
|
||||
&CsmaCdNetDevice::TransmitReadyEvent,
|
||||
this);
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::TransmitReadyEvent (void)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::TransmitReadyEvent ()");
|
||||
//
|
||||
// This function is called to enable the transmitter after the interframe
|
||||
// gap has passed. If there are pending transmissions, we use this opportunity
|
||||
// to start the next transmit.
|
||||
//
|
||||
NS_ASSERT_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())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool found;
|
||||
found = m_queue->Dequeue (m_currentPkt);
|
||||
NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
|
||||
TransmitStart ();
|
||||
}
|
||||
}
|
||||
|
||||
TraceResolver *
|
||||
CsmaCdNetDevice::DoCreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
|
||||
resolver->Add ("queue",
|
||||
MakeCallback (&Queue::CreateTraceResolver,
|
||||
PeekPointer (m_queue)),
|
||||
CsmaCdNetDevice::QUEUE);
|
||||
resolver->Add ("rx",
|
||||
m_rxTrace,
|
||||
CsmaCdNetDevice::RX);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
bool
|
||||
CsmaCdNetDevice::Attach (Ptr<CsmaCdChannel> ch)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::Attach (" << &ch << ")");
|
||||
|
||||
m_channel = ch;
|
||||
|
||||
m_deviceId = m_channel->Attach(this);
|
||||
m_bps = m_channel->GetDataRate ();
|
||||
m_tInterframeGap = m_channel->GetDelay ();
|
||||
|
||||
/*
|
||||
* For now, this device is up whenever a channel is attached to it.
|
||||
*/
|
||||
NotifyLinkUp ();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::AddQueue (Ptr<Queue> q)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::AddQueue (" << q << ")");
|
||||
|
||||
m_queue = q;
|
||||
}
|
||||
|
||||
void
|
||||
CsmaCdNetDevice::Receive (Packet& p)
|
||||
{
|
||||
NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")");
|
||||
|
||||
// Only receive if send side of net device is enabled
|
||||
if (!IsReceiveEnabled())
|
||||
return;
|
||||
|
||||
int param = 0;
|
||||
Packet packet = p;
|
||||
|
||||
if (ProcessHeader(packet, param))
|
||||
{
|
||||
m_rxTrace (packet);
|
||||
ForwardUp (packet, param);
|
||||
} else {
|
||||
m_dropTrace (packet);
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<Queue>
|
||||
CsmaCdNetDevice::GetQueue(void) const
|
||||
{
|
||||
return m_queue;
|
||||
}
|
||||
|
||||
Ptr<Channel>
|
||||
CsmaCdNetDevice::DoGetChannel(void) const
|
||||
{
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
424
src/devices/csma-cd/csma-cd-net-device.h
Normal file
424
src/devices/csma-cd/csma-cd-net-device.h
Normal file
@@ -0,0 +1,424 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
|
||||
* Derived from the p2p net device file
|
||||
*/
|
||||
|
||||
#ifndef CSMA_CD_NET_DEVICE_H
|
||||
#define CSMA_CD_NET_DEVICE_H
|
||||
|
||||
#include <string.h>
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/backoff.h"
|
||||
#include "ns3/mac-address.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/callback-trace-source.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/data-rate.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/random-variable.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Queue;
|
||||
class CsmaCdChannel;
|
||||
|
||||
/**
|
||||
* \class CsmaCdNetDevice
|
||||
* \brief A Device for a CsmaCd Network Link.
|
||||
*
|
||||
* The Csma/Cd 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/Cd 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
|
||||
* 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/Cd net device will receive all
|
||||
* packets written to the Csma/Cd 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 CsmaCdNetDevice : public NetDevice {
|
||||
public:
|
||||
/**
|
||||
* Enumeration of the types of traces supported in the class.
|
||||
*
|
||||
*/
|
||||
enum TraceType {
|
||||
QUEUE, /**< Trace queue events on the attached queue */
|
||||
RX, /**< Trace packet reception events (from the channel) */
|
||||
DROP /**< Trace packet drop events (from the channel) */
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumeration of the types of packets supported in the class.
|
||||
*
|
||||
*/
|
||||
enum CsmaCdEncapsulationMode {
|
||||
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 CsmaCdNetDevice
|
||||
*
|
||||
* This is the constructor for the CsmaCdNetDevice. 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.
|
||||
*
|
||||
* \param node the Node to which this device is connected.
|
||||
* \param addr The source MAC address of the net device.
|
||||
*/
|
||||
CsmaCdNetDevice (Ptr<Node> node, MacAddress addr, CsmaCdEncapsulationMode pktType);
|
||||
CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
|
||||
CsmaCdEncapsulationMode pktType,
|
||||
bool sendEnable, bool receiveEnable);
|
||||
/**
|
||||
* Copy Construct a CsmaCdNetDevice
|
||||
*
|
||||
* This is the copy constructor for the CsmaCdNetDevice. This is
|
||||
* primarily used in topology creation.
|
||||
*
|
||||
* \param nd the object to be copied
|
||||
*/
|
||||
CsmaCdNetDevice (const CsmaCdNetDevice& nd);
|
||||
/**
|
||||
* Destroy a CsmaCdNetDevice
|
||||
*
|
||||
* This is the destructor for the CsmaCdNetDevice.
|
||||
*/
|
||||
virtual ~CsmaCdNetDevice();
|
||||
/**
|
||||
* Assignment Operator for a CsmaCdNetDevice
|
||||
*
|
||||
* This is the assignment operator for the CsmaCdNetDevice. This is
|
||||
* to allow
|
||||
*
|
||||
* \param nd the object to be copied
|
||||
*/
|
||||
// CsmaCdNetDevice& operator= (CsmaCdNetDevice nd);
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @see Attach ()
|
||||
* \param slotTime Length of a packet slot (or average packet time)
|
||||
* \param minSlots Minimum number of slots to wait
|
||||
* \param maxSlots Maximum number of slots to wait
|
||||
* \param maxRetries Maximum number of retries before packet is discard
|
||||
* \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);
|
||||
/**
|
||||
* Attach the device to a channel.
|
||||
*
|
||||
* The function Attach is used to add a CsmaCdNetDevice to a
|
||||
* CsmaCdChannel.
|
||||
*
|
||||
* @see SetDataRate ()
|
||||
* @see SetInterframeGap ()
|
||||
* \param ch a pointer to the channel to which this object is being attached.
|
||||
*/
|
||||
bool Attach (Ptr<CsmaCdChannel> ch);
|
||||
/**
|
||||
* Attach a queue to the CsmaCdNetDevice.
|
||||
*
|
||||
* The CsmaCdNetDevice "owns" a queue. This queue is created by the
|
||||
* CsmaCdTopology object and implements a queueing method such as
|
||||
* DropTail or RED. The CsmaCdNetDevice assumes ownership of this
|
||||
* queue and must delete it when the device is destroyed.
|
||||
*
|
||||
* @see CsmaCdTopology::AddCsmaCdLink ()
|
||||
* @see Queue
|
||||
* @see DropTailQueue
|
||||
* \param queue a pointer to the queue for which object is assuming
|
||||
* ownership.
|
||||
*/
|
||||
void AddQueue (Ptr<Queue> queue);
|
||||
/**
|
||||
* Receive a packet from a connected CsmaCdChannel.
|
||||
*
|
||||
* The CsmaCdNetDevice receives packets from its connected channel
|
||||
* and forwards them up the protocol stack. This is the public method
|
||||
* used by the channel to indicate that the last bit of a packet has
|
||||
* arrived at the device.
|
||||
*
|
||||
* @see CsmaCdChannel
|
||||
* \param p a reference to the received packet
|
||||
*/
|
||||
void Receive (Packet& p);
|
||||
|
||||
bool IsSendEnabled (void);
|
||||
bool IsReceiveEnabled (void);
|
||||
|
||||
void SetSendEnable (bool);
|
||||
void SetReceiveEnable (bool);
|
||||
|
||||
protected:
|
||||
virtual bool DoNeedsArp (void) const;
|
||||
virtual void DoDispose (void);
|
||||
/**
|
||||
* Get a copy of the attached Queue.
|
||||
*
|
||||
* This method is provided for any derived class that may need to get
|
||||
* direct access to the underlying queue.
|
||||
*
|
||||
* \return a pointer to the queue.
|
||||
*/
|
||||
Ptr<Queue> GetQueue (void) const;
|
||||
/**
|
||||
* Get a copy of the attached Channel
|
||||
*
|
||||
* This method is provided for any derived class that may need to get
|
||||
* direct access to the connected channel
|
||||
*
|
||||
* \return a pointer to the channel
|
||||
*/
|
||||
virtual Ptr<Channel> DoGetChannel (void) const;
|
||||
/**
|
||||
* Adds the necessary headers and trailers to a packet of data in order to
|
||||
* respect the packet type
|
||||
*
|
||||
* \param p Packet to which header should be added
|
||||
* \param dest MAC destination address to which packet should be sent
|
||||
* \param protocolNumber In some protocols, identifies the type of
|
||||
* payload contained in this packet.
|
||||
*/
|
||||
void AddHeader (Packet& p, const MacAddress& dest,
|
||||
uint16_t protocolNumber);
|
||||
/**
|
||||
* Removes, from a packet of data, all headers and trailers that
|
||||
* relate to the packet type
|
||||
*
|
||||
* \param p Packet whose headers need to be processed
|
||||
* \param param An integer parameter that can be set by the function
|
||||
* to return information gathered in the header
|
||||
* \return Returns true if the packet should be forwarded up the
|
||||
* protocol stack.
|
||||
*/
|
||||
bool ProcessHeader (Packet& p, int& param);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Initializes variablea when construction object.
|
||||
*/
|
||||
void Init (bool sendEnable, bool receiveEnable);
|
||||
/**
|
||||
* Send a Packet on the Csma/Cd network
|
||||
*
|
||||
* This method does not use a destination address since all packets
|
||||
* are broadcast to all NetDevices attached to the channel. Packet
|
||||
* should contain all needed headers at this time.
|
||||
*
|
||||
* If the device is ready to transmit, the next packet is read off
|
||||
* of the queue and stored locally until it has been transmitted.
|
||||
*
|
||||
* \param p a reference to the packet to send
|
||||
* \param dest destination address
|
||||
* \param protocolNumber -- this parameter is not used here
|
||||
* \return true if success, false on failure
|
||||
*/
|
||||
virtual bool SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber);
|
||||
|
||||
/**
|
||||
* Start Sending a Packet Down the Wire.
|
||||
*
|
||||
* The TransmitStart method is the method that is used internally in
|
||||
* the CsmaCdNetDevice to begin the process of sending a packet
|
||||
* out on the channel. The 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)
|
||||
*
|
||||
* @see CsmaCdChannel::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
|
||||
* 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.
|
||||
*
|
||||
* @see CsmaCdChannel::TransmitEnd ()
|
||||
* @see TransmitReadyEvent ()
|
||||
*/
|
||||
void TransmitCompleteEvent (void);
|
||||
/**
|
||||
* Cause the Transmitter to Become Ready to Send Another Packet.
|
||||
*
|
||||
* The TransmitReadyEvent method is used internally to re-enable the
|
||||
* transmit machine of the net device. It is scheduled after a suitable
|
||||
* interframe gap after the completion of the previous transmission.
|
||||
* The queue is checked at this time, and if there is a packet waiting on
|
||||
* the queue, the transmission process is begun.
|
||||
*
|
||||
* If a packet is in the queue, it is extracted for the queue as the
|
||||
* next packet to be transmitted by the net device.
|
||||
*
|
||||
* @see TransmitStart ()
|
||||
*/
|
||||
void TransmitReadyEvent (void);
|
||||
/**
|
||||
* Create a Trace Resolver for events in the net device.
|
||||
* (NOT TESTED)
|
||||
* @see class TraceResolver
|
||||
*/
|
||||
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
|
||||
|
||||
/**
|
||||
* Aborts the transmission of the current packet
|
||||
*
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Device ID returned by the attached functions. It is used by the
|
||||
* mp-channel to identify each net device to make sure that only
|
||||
* active net devices are writing to the channel
|
||||
*/
|
||||
uint32_t m_deviceId;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
enum TxMachineState
|
||||
{
|
||||
READY, /**< The transmitter is ready to begin transmission of a packet */
|
||||
BUSY, /**< The transmitter is busy transmitting a packet */
|
||||
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
|
||||
*/
|
||||
TxMachineState m_txMachineState;
|
||||
|
||||
/**
|
||||
* The type of packet that should be created by the AddHeader
|
||||
* function and that should be processed by the ProcessHeader
|
||||
* function.
|
||||
*/
|
||||
CsmaCdEncapsulationMode m_pktType;
|
||||
/**
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
Packet m_currentPkt;
|
||||
/**
|
||||
* The CsmaCdChannel to which this CsmaCdNetDevice has been
|
||||
* attached.
|
||||
* @see class CsmaCdChannel
|
||||
*/
|
||||
Ptr<CsmaCdChannel> m_channel;
|
||||
/**
|
||||
* The Queue which this CsmaCdNetDevice uses as a packet source.
|
||||
* Management of this Queue has been delegated to the CsmaCdNetDevice
|
||||
* and it has the responsibility for deletion.
|
||||
* @see class Queue
|
||||
* @see class DropTailQueue
|
||||
*/
|
||||
Ptr<Queue> m_queue;
|
||||
/**
|
||||
* NOT TESTED
|
||||
* The trace source for the packet reception events that the device can
|
||||
* fire.
|
||||
*
|
||||
* @see class CallBackTraceSource
|
||||
* @see class TraceResolver
|
||||
*/
|
||||
CallbackTraceSource<Packet &> m_rxTrace;
|
||||
CallbackTraceSource<Packet &> m_dropTrace;
|
||||
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif // CSMA_CD_NET_DEVICE_H
|
||||
|
||||
103
src/devices/csma-cd/csma-cd-topology.cc
Normal file
103
src/devices/csma-cd/csma-cd-topology.cc
Normal file
@@ -0,0 +1,103 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2007 Emmanuelle Laprise
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation;
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
//
|
||||
|
||||
//
|
||||
// Topology helper for CsmaCd channels in ns3.
|
||||
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/queue.h"
|
||||
|
||||
#include "csma-cd-channel.h"
|
||||
#include "csma-cd-net-device.h"
|
||||
#include "csma-cd-topology.h"
|
||||
#include "ns3/socket-factory.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
Ptr<CsmaCdChannel>
|
||||
CsmaCdTopology::CreateCsmaCdChannel(
|
||||
const DataRate& bps,
|
||||
const Time& delay)
|
||||
{
|
||||
Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (bps, delay);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
#if 0
|
||||
Ptr<CsmaCdNetDevice>
|
||||
CsmaCdTopology::AddCsmaCdEthernetNode(
|
||||
Ptr<Node> n1,
|
||||
Ptr<CsmaCdChannel> ch,
|
||||
MacAddress addr)
|
||||
{
|
||||
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
|
||||
ns3::CsmaCdNetDevice::ETHERNET_V1);
|
||||
|
||||
Ptr<Queue> q = Queue::CreateDefault ();
|
||||
nd1->AddQueue(q);
|
||||
nd1->Attach (ch);
|
||||
|
||||
return nd1;
|
||||
}
|
||||
|
||||
Ptr<PacketSocket>
|
||||
CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
|
||||
Ptr<CsmaCdNetDevice> ndSrc,
|
||||
Ptr<CsmaCdNetDevice> ndDest)
|
||||
{
|
||||
Ptr<PacketSocket> socket = Create<PacketSocket> ();
|
||||
socket->Bind(ndSrc);
|
||||
socket->Connect(ndDest->GetAddress());
|
||||
app->Connect(socket);
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
Ptr<PacketSocket>
|
||||
CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
|
||||
Ptr<CsmaCdNetDevice> ndSrc,
|
||||
MacAddress macAddr)
|
||||
{
|
||||
Ptr<PacketSocket> socket = Create<PacketSocket> ();
|
||||
socket->Bind(ndSrc);
|
||||
socket->Connect(macAddr);
|
||||
app->Connect(socket);
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
Ptr<Socket>
|
||||
CsmaCdTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
|
||||
{
|
||||
InterfaceId iid = InterfaceId::LookupByName (iid_name);
|
||||
|
||||
Ptr<SocketFactory> socketFactory =
|
||||
n1->QueryInterface<SocketFactory> (iid);
|
||||
|
||||
Ptr<Socket> socket = socketFactory->CreateSocket ();
|
||||
|
||||
return socket;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
128
src/devices/csma-cd/csma-cd-topology.h
Normal file
128
src/devices/csma-cd/csma-cd-topology.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2007 Emmanuelle Laprise
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation;
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
//
|
||||
// Topology helper for multipoint channels in ns3.
|
||||
//
|
||||
#ifndef CSMA_CD_TOPOLOGY_H
|
||||
#define CSMA_CD_TOPOLOGY_H
|
||||
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/csma-cd-net-device.h"
|
||||
#if 0
|
||||
#include "ns3/packet-socket.h"
|
||||
#include "ns3/packet-socket-app.h"
|
||||
#endif
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/mac-address.h"
|
||||
|
||||
// The topology class consists of only static methods thar are used to
|
||||
// create the topology and data flows for an ns3 simulation
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class CsmaCdChannel;
|
||||
class Node;
|
||||
class DataRate;
|
||||
class Queue;
|
||||
|
||||
/**
|
||||
* \brief A helper class to create CsmaCd Topologies
|
||||
*
|
||||
* CsmaCd topologies are created based on the
|
||||
* ns3::CsmaCdNetDevice subclasses and ns3::CsmaCdChannel
|
||||
* objects. This class uses the EthernetNetDevice and
|
||||
* PacketSocket classes in order to create logical connections between
|
||||
* net devices. The PacketSocket class generates the data and the
|
||||
* EthernetNetDevice class creates ethernet packets from the
|
||||
* data, filling in source and destination addresses. The
|
||||
* EthernetNetDevice class filters received data packets
|
||||
* according to its destination Mac addresses.
|
||||
*/
|
||||
class CsmaCdTopology {
|
||||
public:
|
||||
/**
|
||||
* \param dataRate Maximum transmission link rate
|
||||
* \param delay propagation delay between any two nodes
|
||||
* \return Pointer to the created CsmaCdChannel
|
||||
*
|
||||
* Create a CsmaCdChannel. All nodes connected to a multipoint
|
||||
* channels will receive all packets written to that channel
|
||||
*/
|
||||
static Ptr<CsmaCdChannel> CreateCsmaCdChannel(
|
||||
const DataRate& dataRate, const Time& delay);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* \param n1 Node to be attached to the multipoint channel
|
||||
* \param ch CsmaCdChannel to which node n1 should be attached
|
||||
* \param addr MacAddress that should be assigned to the
|
||||
* EthernetNetDevice that will be added to the node.
|
||||
*
|
||||
* Add a multipoint node to a multipoint channel
|
||||
*/
|
||||
static Ptr<CsmaCdNetDevice> AddCsmaCdEthernetNode(Ptr<Node> n1,
|
||||
Ptr<CsmaCdChannel> ch,
|
||||
MacAddress addr);
|
||||
|
||||
/**
|
||||
* \param app Application that will be sending data to the agent
|
||||
* \param ndSrc Net Device that will be sending the packets onto the
|
||||
* network
|
||||
* \param ndDest Net Device to which ndSrc will be sending the packets
|
||||
* \return A pointer to the PacketSocket
|
||||
*
|
||||
* Creates an PacketSocket and configure it to send packets between
|
||||
* two net devices
|
||||
*/
|
||||
static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
|
||||
Ptr<CsmaCdNetDevice> ndSrc,
|
||||
Ptr<CsmaCdNetDevice> ndDest);
|
||||
|
||||
/**
|
||||
* \param app Application that will be sending data to the agent
|
||||
* \param ndSrc Net Device that will be sending the packets onto the
|
||||
* network
|
||||
* \param macAddr Mac destination address for the packets send by
|
||||
* the ndSrc net device \return a Pointer to the created
|
||||
* PacketSocket
|
||||
*
|
||||
* Creates an PacketSocket and configure it to send packets from a
|
||||
* net device to a destination MacAddress
|
||||
*/
|
||||
static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
|
||||
Ptr<CsmaCdNetDevice> ndSrc,
|
||||
MacAddress macAddr);
|
||||
|
||||
/**
|
||||
* \param n1 Node from which socketfactory should be tested.
|
||||
* \param iid_name Interface identifier ("Packet", in this case)
|
||||
*
|
||||
* This is a test function to make sure that a socket can be created
|
||||
* by using the socketfactory interface provided in the
|
||||
* netdevicenode.
|
||||
*/
|
||||
static Ptr<Socket> CreatePacketSocket(Ptr<Node> n1,
|
||||
std::string iid_name);
|
||||
#endif
|
||||
|
||||
};
|
||||
} // namespace ns3
|
||||
|
||||
#endif
|
||||
|
||||
24
src/devices/csma-cd/wscript
Normal file
24
src/devices/csma-cd/wscript
Normal file
@@ -0,0 +1,24 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
|
||||
def build(bld):
|
||||
obj = bld.create_obj('cpp', 'shlib')
|
||||
obj.name = 'ns3-csma-cd'
|
||||
obj.target = obj.name
|
||||
obj.uselib_local = ['ns3-node']
|
||||
obj.source = [
|
||||
'backoff.cc',
|
||||
'csma-cd-net-device.cc',
|
||||
'csma-cd-channel.cc',
|
||||
'csma-cd-topology.cc',
|
||||
'csma-cd-ipv4-topology.cc',
|
||||
]
|
||||
headers = bld.create_obj('ns3header')
|
||||
headers.source = [
|
||||
'backoff.h',
|
||||
'csma-cd-net-device.h',
|
||||
'csma-cd-channel.h',
|
||||
'csma-cd-topology.h',
|
||||
'csma-cd-ipv4-topology.h',
|
||||
]
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
|
||||
def build(bld):
|
||||
p2p = bld.create_obj('cpp', 'shlib')
|
||||
p2p.name = 'ns3-p2p'
|
||||
p2p.target = p2p.name
|
||||
p2p.uselib_local = ['ns3-node']
|
||||
p2p.source = [
|
||||
'p2p-net-device.cc',
|
||||
'p2p-channel.cc',
|
||||
'p2p-topology.cc',
|
||||
]
|
||||
p2p.includes = '.'
|
||||
|
||||
headers = bld.create_obj('ns3header')
|
||||
headers.source = [
|
||||
'p2p-net-device.h',
|
||||
'p2p-channel.h',
|
||||
'p2p-topology.h',
|
||||
]
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
* Author: Craig Dowell <craigdo@ee.washington.edu>
|
||||
*/
|
||||
|
||||
#include "p2p-channel.h"
|
||||
#include "p2p-net-device.h"
|
||||
#include "point-to-point-channel.h"
|
||||
#include "point-to-point-net-device.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/debug.h"
|
||||
@@ -26,8 +26,9 @@
|
||||
#include "ns3/queue.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/composite-trace-resolver.h"
|
||||
#include "p2p-net-device.h"
|
||||
#include "p2p-channel.h"
|
||||
#include "point-to-point-net-device.h"
|
||||
#include "point-to-point-channel.h"
|
||||
#include "ns3/llc-snap-header.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice");
|
||||
|
||||
@@ -65,13 +66,30 @@ PointToPointNetDevice::~PointToPointNetDevice()
|
||||
m_queue = 0;
|
||||
}
|
||||
|
||||
void PointToPointNetDevice::AddHeader(Packet& p, const MacAddress& dest,
|
||||
uint16_t protocolNumber)
|
||||
{
|
||||
LlcSnapHeader llc;
|
||||
llc.SetType (protocolNumber);
|
||||
p.AddHeader (llc);
|
||||
}
|
||||
|
||||
bool PointToPointNetDevice::ProcessHeader(Packet& p, int& param)
|
||||
{
|
||||
LlcSnapHeader llc;
|
||||
p.RemoveHeader (llc);
|
||||
|
||||
param = llc.GetType ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PointToPointNetDevice::DoDispose()
|
||||
{
|
||||
m_channel = 0;
|
||||
NetDevice::DoDispose ();
|
||||
}
|
||||
|
||||
|
||||
void PointToPointNetDevice::SetDataRate(const DataRate& bps)
|
||||
{
|
||||
m_bps = bps;
|
||||
@@ -82,7 +100,8 @@ void PointToPointNetDevice::SetInterframeGap(const Time& t)
|
||||
m_tInterframeGap = t;
|
||||
}
|
||||
|
||||
bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
|
||||
bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest,
|
||||
uint16_t protocolNumber)
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
|
||||
NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
|
||||
@@ -91,6 +110,7 @@ bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
|
||||
// "go down" during the simulation? Shouldn't we just wait for it
|
||||
// to come back up?
|
||||
NS_ASSERT (IsLinkUp ());
|
||||
AddHeader(p, dest, protocolNumber);
|
||||
|
||||
//
|
||||
// This class simulates a point to point device. In the case of a serial
|
||||
@@ -198,9 +218,12 @@ void PointToPointNetDevice::AddQueue (Ptr<Queue> q)
|
||||
void PointToPointNetDevice::Receive (Packet& p)
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")");
|
||||
int param = 0;
|
||||
Packet packet = p;
|
||||
|
||||
m_rxTrace (p);
|
||||
ForwardUp (p);
|
||||
ProcessHeader(packet, param);
|
||||
m_rxTrace (packet);
|
||||
ForwardUp (packet, param);
|
||||
}
|
||||
|
||||
Ptr<Queue> PointToPointNetDevice::GetQueue(void) const
|
||||
@@ -187,11 +187,18 @@ protected:
|
||||
static const DataRate& GetDefaultRate();
|
||||
|
||||
private:
|
||||
// unimplemented methods to make it impossible
|
||||
// to copy these objects.
|
||||
PointToPointNetDevice (const PointToPointNetDevice& nd);
|
||||
PointToPointNetDevice& operator = (const PointToPointNetDevice&o);
|
||||
|
||||
/**
|
||||
* Adds the necessary headers and trailers to a packet of data in order to
|
||||
* respect the protocol implemented by the agent.
|
||||
*/
|
||||
void AddHeader(Packet& p, const MacAddress& dest, uint16_t protocolNumber);
|
||||
/**
|
||||
* Removes, from a packet of data, all headers and trailers that
|
||||
* relate to the protocol implemented by the agent
|
||||
* \return Returns true if the packet should be forwarded up the
|
||||
* protocol stack.
|
||||
*/
|
||||
bool ProcessHeader(Packet& p, int& param);
|
||||
/**
|
||||
* Send a Packet Down the Wire.
|
||||
*
|
||||
@@ -202,9 +209,11 @@ private:
|
||||
* @see NetDevice
|
||||
* @param p a reference to the packet to send
|
||||
* @param dest a reference to the MacAddress of the destination device
|
||||
* @param protocolNumber Protocol Number used to find protocol touse
|
||||
* @returns true if success, false on failure
|
||||
*/
|
||||
virtual bool SendTo (Packet& p, const MacAddress& dest);
|
||||
virtual bool SendTo (Packet& p, const MacAddress& dest,
|
||||
uint16_t protocolNumber);
|
||||
/**
|
||||
* Start Sending a Packet Down the Wire.
|
||||
*
|
||||
@@ -32,9 +32,9 @@
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/queue.h"
|
||||
|
||||
#include "p2p-channel.h"
|
||||
#include "p2p-net-device.h"
|
||||
#include "p2p-topology.h"
|
||||
#include "point-to-point-channel.h"
|
||||
#include "point-to-point-net-device.h"
|
||||
#include "point-to-point-topology.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
21
src/devices/point-to-point/wscript
Normal file
21
src/devices/point-to-point/wscript
Normal file
@@ -0,0 +1,21 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
|
||||
def build(bld):
|
||||
module = bld.create_obj('cpp', 'shlib')
|
||||
module.name = 'ns3-point-to-point'
|
||||
module.target = module.name
|
||||
module.uselib_local = ['ns3-node']
|
||||
module.source = [
|
||||
'point-to-point-net-device.cc',
|
||||
'point-to-point-channel.cc',
|
||||
'point-to-point-topology.cc',
|
||||
]
|
||||
headers = bld.create_obj('ns3header')
|
||||
headers.source = [
|
||||
'point-to-point-net-device.h',
|
||||
'point-to-point-channel.h',
|
||||
'point-to-point-topology.h',
|
||||
]
|
||||
module.includes = '.'
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/address-utils.h"
|
||||
#include "arp-header.h"
|
||||
#include "header-utils.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ def build(bld):
|
||||
'arp-ipv4-interface.cc',
|
||||
'arp-l3-protocol.cc',
|
||||
'ipv4-loopback-interface.cc',
|
||||
'header-utils.cc',
|
||||
'udp-socket.cc',
|
||||
'ipv4-end-point-demux.cc',
|
||||
'arp-private.cc',
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "header-utils.h"
|
||||
#include "address-utils.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#ifndef HEADER_UTILS_H
|
||||
#define HEADER_UTILS_H
|
||||
#ifndef ADDRESS_UTILS_H
|
||||
#define ADDRESS_UTILS_H
|
||||
|
||||
#include "ns3/buffer.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
@@ -35,4 +35,4 @@ void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len);
|
||||
|
||||
};
|
||||
|
||||
#endif /* HEADER_UTILS_H */
|
||||
#endif /* ADDRESS_UTILS_H */
|
||||
173
src/node/ethernet-header.cc
Normal file
173
src/node/ethernet-header.cc
Normal file
@@ -0,0 +1,173 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2005 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/header.h"
|
||||
#include "ethernet-header.h"
|
||||
#include "address-utils.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("EthernetHeader");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
bool EthernetHeader::m_enPreambleSfd = false;
|
||||
|
||||
EthernetHeader::EthernetHeader ()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
EthernetHeader::~EthernetHeader ()
|
||||
{}
|
||||
|
||||
void
|
||||
EthernetHeader::Init()
|
||||
{
|
||||
m_preambleSfd = 0;
|
||||
m_lengthType = 0x0;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHeader::EnablePreambleSfd (bool enable)
|
||||
{
|
||||
m_enPreambleSfd = enable;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHeader::SetLengthType (uint16_t lengthType)
|
||||
{
|
||||
m_lengthType = lengthType;
|
||||
}
|
||||
uint16_t
|
||||
EthernetHeader::GetLengthType (void) const
|
||||
{
|
||||
return m_lengthType;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHeader::SetPreambleSfd (uint64_t preambleSfd)
|
||||
{
|
||||
m_preambleSfd = preambleSfd;
|
||||
}
|
||||
uint64_t
|
||||
EthernetHeader::GetPreambleSfd (void) const
|
||||
{
|
||||
return m_preambleSfd;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHeader::SetSource (MacAddress source)
|
||||
{
|
||||
m_source = source;
|
||||
}
|
||||
MacAddress
|
||||
EthernetHeader::GetSource (void) const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHeader::SetDestination (MacAddress dst)
|
||||
{
|
||||
m_destination = dst;
|
||||
}
|
||||
MacAddress
|
||||
EthernetHeader::GetDestination (void) const
|
||||
{
|
||||
return m_destination;
|
||||
}
|
||||
|
||||
ethernet_header_t
|
||||
EthernetHeader::GetPacketType (void) const
|
||||
{
|
||||
return LENGTH;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
EthernetHeader::GetHeaderSize (void) const
|
||||
{
|
||||
return GetSerializedSize();
|
||||
}
|
||||
|
||||
std::string
|
||||
EthernetHeader::DoGetName (void) const
|
||||
{
|
||||
return "ETHERNET";
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHeader::PrintTo (std::ostream &os) const
|
||||
{
|
||||
// ethernet, right ?
|
||||
os << "(ethernet)";
|
||||
if (m_enPreambleSfd)
|
||||
{
|
||||
os << " preamble/sfd=" << m_preambleSfd << ",";
|
||||
}
|
||||
os << " length/type=" << m_lengthType
|
||||
<< ", source=" << m_source
|
||||
<< ", destination=" << m_destination;
|
||||
}
|
||||
uint32_t
|
||||
EthernetHeader::GetSerializedSize (void) const
|
||||
{
|
||||
if (m_enPreambleSfd)
|
||||
{
|
||||
return PREAMBLE_SIZE + LENGTH_SIZE + 2*MAC_ADDR_SIZE;
|
||||
} else {
|
||||
return LENGTH_SIZE + 2*MAC_ADDR_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EthernetHeader::SerializeTo (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
if (m_enPreambleSfd)
|
||||
{
|
||||
i.WriteU64(m_preambleSfd);
|
||||
}
|
||||
NS_ASSERT (m_destination.GetLength () == MAC_ADDR_SIZE);
|
||||
NS_ASSERT (m_source.GetLength () == MAC_ADDR_SIZE);
|
||||
WriteTo (i, m_destination);
|
||||
WriteTo (i, m_source);
|
||||
i.WriteU16 (m_lengthType);
|
||||
}
|
||||
uint32_t
|
||||
EthernetHeader::DeserializeFrom (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
if (m_enPreambleSfd)
|
||||
{
|
||||
m_enPreambleSfd = i.ReadU64 ();
|
||||
}
|
||||
|
||||
ReadFrom (i, m_destination, MAC_ADDR_SIZE);
|
||||
ReadFrom (i, m_source, MAC_ADDR_SIZE);
|
||||
m_lengthType = i.ReadU16 ();
|
||||
|
||||
return GetSerializedSize ();
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
128
src/node/ethernet-header.h
Normal file
128
src/node/ethernet-header.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
|
||||
#ifndef ETHERNET_HEADER_H
|
||||
#define ETHERNET_HEADER_H
|
||||
|
||||
#include "ns3/header.h"
|
||||
#include "ns3/mac-address.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* Types of ethernet packets. Indicates the type of the current
|
||||
* header.
|
||||
*/
|
||||
enum ethernet_header_t {
|
||||
LENGTH, /**< Basic ethernet packet, no tags, type/length field
|
||||
indicates packet length or IP/ARP packet */
|
||||
VLAN, /**< Single tagged packet. Header includes VLAN tag */
|
||||
QINQ /**< Double tagged packet. Header includes two VLAN tags */
|
||||
};
|
||||
/**
|
||||
* \brief Packet header for Ethernet
|
||||
*
|
||||
* This class can be used to add a header to an ethernet packet that
|
||||
* will specify the source and destination addresses and the length of
|
||||
* the packet. Eventually the class will be improved to also support
|
||||
* VLAN tags in packet headers.
|
||||
*/
|
||||
class EthernetHeader : public Header {
|
||||
public:
|
||||
static const int PREAMBLE_SIZE = 8; /// size of the preamble_sfd header field
|
||||
static const int LENGTH_SIZE = 2; /// size of the length_type header field
|
||||
static const int MAC_ADDR_SIZE = 6; /// size of src/dest addr header fields
|
||||
|
||||
/**
|
||||
* \brief Construct a null ethernet header
|
||||
*/
|
||||
EthernetHeader ();
|
||||
virtual ~EthernetHeader ();
|
||||
/**
|
||||
* \brief Enable or disabled the serialisation of the preamble and
|
||||
* Sfd header fields
|
||||
*/
|
||||
static void EnablePreambleSfd (bool enable);
|
||||
/**
|
||||
* \param size The size of the payload in bytes
|
||||
*/
|
||||
void SetLengthType (uint16_t size);
|
||||
/**
|
||||
* \param source The source address of this packet
|
||||
*/
|
||||
void SetSource (MacAddress source);
|
||||
/**
|
||||
* \param destination The destination address of this packet.
|
||||
*/
|
||||
void SetDestination (MacAddress destination);
|
||||
/**
|
||||
* \param preambleSfd The value that the preambleSfd field should take
|
||||
*/
|
||||
void SetPreambleSfd (uint64_t preambleSfd);
|
||||
/**
|
||||
* \return The size of the payload in bytes
|
||||
*/
|
||||
uint16_t GetLengthType (void) const;
|
||||
/**
|
||||
* \return The type of packet (only basic Ethernet is currently supported)
|
||||
*/
|
||||
ethernet_header_t GetPacketType (void) const;
|
||||
/**
|
||||
* \return The source address of this packet
|
||||
*/
|
||||
MacAddress GetSource (void) const;
|
||||
/**
|
||||
* \return The destination address of this packet
|
||||
*/
|
||||
MacAddress GetDestination (void) const;
|
||||
/**
|
||||
* \return The value of the PreambleSfd field
|
||||
*/
|
||||
uint64_t GetPreambleSfd () const;
|
||||
/**
|
||||
* \return The size of the header
|
||||
*/
|
||||
uint32_t GetHeaderSize() const;
|
||||
|
||||
private:
|
||||
virtual std::string DoGetName (void) const;
|
||||
virtual void PrintTo (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void SerializeTo (Buffer::Iterator start) const;
|
||||
virtual uint32_t DeserializeFrom (Buffer::Iterator start);
|
||||
|
||||
void Init (void);
|
||||
|
||||
/**
|
||||
* If false, the preamble/sfd are not serialised/deserialised.
|
||||
*/
|
||||
static bool m_enPreambleSfd;
|
||||
|
||||
uint64_t m_preambleSfd; /// Value of the Preamble/SFD fields
|
||||
uint16_t m_lengthType : 16; /// Length or type of the packet
|
||||
MacAddress m_source; /// Source address
|
||||
MacAddress m_destination; /// Destination address
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
|
||||
#endif /* ETHERNET_HEADER_H */
|
||||
124
src/node/ethernet-trailer.cc
Normal file
124
src/node/ethernet-trailer.cc
Normal file
@@ -0,0 +1,124 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2005 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/trailer.h"
|
||||
#include "ethernet-trailer.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("EthernetTrailer");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
bool EthernetTrailer::m_calcFcs = false;
|
||||
|
||||
EthernetTrailer::EthernetTrailer ()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
EthernetTrailer::~EthernetTrailer ()
|
||||
{}
|
||||
|
||||
void EthernetTrailer::Init()
|
||||
{
|
||||
m_fcs = 0;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetTrailer::EnableFcs (bool enable)
|
||||
{
|
||||
m_calcFcs = enable;
|
||||
}
|
||||
|
||||
bool
|
||||
EthernetTrailer::CheckFcs (const Packet& p) const
|
||||
{
|
||||
if (!m_calcFcs)
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
NS_DEBUG("FCS calculation is not yet enabled" << std::endl);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EthernetTrailer::CalcFcs (const Packet& p)
|
||||
{
|
||||
NS_DEBUG("FCS calculation is not yet enabled" << std::endl);
|
||||
}
|
||||
|
||||
void
|
||||
EthernetTrailer::SetFcs (uint32_t fcs)
|
||||
{
|
||||
m_fcs = fcs;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
EthernetTrailer::GetFcs (void)
|
||||
{
|
||||
return m_fcs;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
EthernetTrailer::GetTrailerSize (void) const
|
||||
{
|
||||
return GetSerializedSize();
|
||||
}
|
||||
std::string
|
||||
EthernetTrailer::DoGetName (void) const
|
||||
{
|
||||
return "ETHERNET";
|
||||
}
|
||||
|
||||
void
|
||||
EthernetTrailer::PrintTo (std::ostream &os) const
|
||||
{
|
||||
os << " fcs=" << m_fcs;
|
||||
}
|
||||
uint32_t
|
||||
EthernetTrailer::GetSerializedSize (void) const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
void
|
||||
EthernetTrailer::SerializeTo (Buffer::Iterator end) const
|
||||
{
|
||||
Buffer::Iterator i = end;
|
||||
i.Prev(GetSerializedSize());
|
||||
|
||||
i.WriteU32 (m_fcs);
|
||||
}
|
||||
uint32_t
|
||||
EthernetTrailer::DeserializeFrom (Buffer::Iterator end)
|
||||
{
|
||||
Buffer::Iterator i = end;
|
||||
uint32_t size = GetSerializedSize();
|
||||
i.Prev(size);
|
||||
|
||||
m_fcs = i.ReadU32 ();
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
104
src/node/ethernet-trailer.h
Normal file
104
src/node/ethernet-trailer.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 Emmanuelle Laprise
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
|
||||
#ifndef ETHERNET_TRAILER_H
|
||||
#define ETHERNET_TRAILER_H
|
||||
|
||||
#include "ns3/trailer.h"
|
||||
#include "ns3/packet.h"
|
||||
|
||||
namespace ns3 {
|
||||
/**
|
||||
* \brief Packet trailer for Ethernet
|
||||
*
|
||||
* This class can be used to add and verify the FCS at the end of an
|
||||
* ethernet packet. The actual FCS functionality is not yet coded and
|
||||
* so this acts more as a placeholder.
|
||||
*/
|
||||
class EthernetTrailer : public Trailer {
|
||||
public:
|
||||
/**
|
||||
* \brief Construct a null ethernet trailer
|
||||
*/
|
||||
EthernetTrailer ();
|
||||
virtual ~EthernetTrailer ();
|
||||
/**
|
||||
* \brief Enable or disabled FCS checking and calculations
|
||||
* \param enable If true, enables FCS calculations.
|
||||
*/
|
||||
static void EnableFcs (bool enable);
|
||||
/**
|
||||
* \brief Updates the Fcs Field to the correct FCS
|
||||
* \param p Reference to a packet on which the FCS should be
|
||||
* calculated. The packet should not currently contain an FCS
|
||||
* trailer.
|
||||
*/
|
||||
void CalcFcs (const Packet& p);
|
||||
/**
|
||||
* \brief Sets the FCS to a new value
|
||||
* \param fcs New FCS value
|
||||
*/
|
||||
void SetFcs (uint32_t fcs);
|
||||
/**
|
||||
* \return the FCS contained in this trailer
|
||||
*/
|
||||
uint32_t GetFcs ();
|
||||
|
||||
/**
|
||||
* \param p Reference to the packet on which the FCS should be
|
||||
* calculated. The packet should not contain an FCS trailer.
|
||||
* \return Returns true if the packet fcs is correct, false otherwise.
|
||||
*
|
||||
* If FCS checking is disabled, this method will always
|
||||
* return true.
|
||||
*/
|
||||
bool CheckFcs (const Packet& p) const;
|
||||
|
||||
/**
|
||||
*\return Returns the size of the trailer
|
||||
*/
|
||||
uint32_t GetTrailerSize() const;
|
||||
|
||||
private:
|
||||
virtual std::string DoGetName (void) const;
|
||||
virtual void PrintTo (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void SerializeTo (Buffer::Iterator end) const;
|
||||
virtual uint32_t DeserializeFrom (Buffer::Iterator end);
|
||||
|
||||
/**
|
||||
* Initializes the trailer parameters during construction.
|
||||
*/
|
||||
void Init (void);
|
||||
|
||||
/**
|
||||
* Enabled FCS calculations. If false, fcs is set to 0 and checkFCS
|
||||
* returns true.
|
||||
*/
|
||||
static bool m_calcFcs;
|
||||
uint32_t m_fcs; /// Value of the fcs contained in the trailer
|
||||
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
|
||||
#endif /* ETHERNET_TRAILER_H */
|
||||
@@ -22,12 +22,15 @@
|
||||
#include <iostream>
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/debug.h"
|
||||
|
||||
|
||||
#include "channel.h"
|
||||
#include "net-device.h"
|
||||
#include "llc-snap-header.h"
|
||||
#include "node.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("NetDevice");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
const InterfaceId NetDevice::iid = MakeInterfaceId ("NetDevice", Object::iid);
|
||||
@@ -172,10 +175,7 @@ NetDevice::Send(Packet& p, const MacAddress& dest, uint16_t protocolNumber)
|
||||
{
|
||||
if (m_isUp)
|
||||
{
|
||||
LlcSnapHeader llc;
|
||||
llc.SetType (protocolNumber);
|
||||
p.AddHeader (llc);
|
||||
return SendTo(p, dest);
|
||||
return SendTo(p, dest, protocolNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -195,18 +195,24 @@ NetDevice::GetChannel (void) const
|
||||
return DoGetChannel ();
|
||||
}
|
||||
|
||||
// Receive packet from below
|
||||
// Receive packets from below
|
||||
bool
|
||||
NetDevice::ForwardUp (Packet& packet)
|
||||
NetDevice::ForwardUp(Packet& p, uint32_t param)
|
||||
{
|
||||
bool retval = false;
|
||||
LlcSnapHeader llc;
|
||||
packet.RemoveHeader (llc);
|
||||
Packet packet = p;
|
||||
|
||||
NS_DEBUG ("NetDevice::ForwardUp: UID is " << packet.GetUid()
|
||||
<< " device is: " << GetName());
|
||||
|
||||
if (!m_receiveCallback.IsNull ())
|
||||
{
|
||||
retval = m_receiveCallback (this, packet, llc.GetType ());
|
||||
retval = m_receiveCallback (this, packet, param);
|
||||
} else {
|
||||
NS_DEBUG ("NetDevice::Receive call back is NULL");
|
||||
}
|
||||
return retval;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
* Modified by Emmanuelle Laprise to remove dependance on LLC headers
|
||||
*/
|
||||
#ifndef NET_DEVICE_H
|
||||
#define NET_DEVICE_H
|
||||
@@ -227,6 +228,8 @@ public:
|
||||
|
||||
/**
|
||||
* \param p packet sent from below up to Network Device
|
||||
* \param param Extra parameter extracted from header and needed by
|
||||
* some protocols
|
||||
* \returns true if the packet was forwarded successfully,
|
||||
* false otherwise.
|
||||
*
|
||||
@@ -234,7 +237,8 @@ public:
|
||||
* forwards it to the higher layers by calling this method
|
||||
* which is responsible for passing it up to the Rx callback.
|
||||
*/
|
||||
bool ForwardUp (Packet& p);
|
||||
bool ForwardUp (Packet& p, uint32_t param);
|
||||
|
||||
|
||||
/**
|
||||
* The dispose method for this NetDevice class.
|
||||
@@ -244,10 +248,13 @@ public:
|
||||
*/
|
||||
virtual void DoDispose (void);
|
||||
|
||||
Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
|
||||
|
||||
private:
|
||||
/**
|
||||
* \param p packet to send
|
||||
* \param dest address of destination to which packet must be sent
|
||||
* \param protocolNumber Number of the protocol (used with some protocols)
|
||||
* \returns true if the packet could be sent successfully, false
|
||||
* otherwise.
|
||||
*
|
||||
@@ -255,7 +262,7 @@ public:
|
||||
* method. When the link is Up, this method is invoked to ask
|
||||
* subclasses to forward packets. Subclasses MUST override this method.
|
||||
*/
|
||||
virtual bool SendTo (Packet& p, const MacAddress& dest) = 0;
|
||||
virtual bool SendTo (Packet& p, const MacAddress &dest, uint16_t protocolNumber) = 0;
|
||||
/**
|
||||
* \returns true if this NetDevice needs the higher-layers
|
||||
* to perform ARP over it, false otherwise.
|
||||
@@ -279,7 +286,7 @@ public:
|
||||
*/
|
||||
virtual Ptr<Channel> DoGetChannel (void) const = 0;
|
||||
|
||||
Ptr<Node> m_node;
|
||||
Ptr<Node> m_node;
|
||||
std::string m_name;
|
||||
uint16_t m_ifIndex;
|
||||
MacAddress m_address;
|
||||
@@ -290,7 +297,6 @@ public:
|
||||
bool m_isMulticast;
|
||||
bool m_isPointToPoint;
|
||||
Callback<void> m_linkChangeCallback;
|
||||
Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
@@ -10,7 +10,10 @@ def build(bld):
|
||||
'ipv4-address.cc',
|
||||
'net-device.cc',
|
||||
'mac-address.cc',
|
||||
'address-utils.cc',
|
||||
'llc-snap-header.cc',
|
||||
'ethernet-header.cc',
|
||||
'ethernet-trailer.cc',
|
||||
'ipv4-route.cc',
|
||||
'queue.cc',
|
||||
'drop-tail-queue.cc',
|
||||
@@ -30,10 +33,13 @@ def build(bld):
|
||||
'ipv4-address.h',
|
||||
'net-device.h',
|
||||
'mac-address.h',
|
||||
'address-utils.h',
|
||||
'ipv4-route.h',
|
||||
'queue.h',
|
||||
'drop-tail-queue.h',
|
||||
'llc-snap-header.h',
|
||||
'ethernet-header.h',
|
||||
'ethernet-trailer.h',
|
||||
'channel.h',
|
||||
'node-list.h',
|
||||
'socket.h',
|
||||
|
||||
@@ -15,7 +15,8 @@ all_modules = (
|
||||
'simulator',
|
||||
'node',
|
||||
'internet-node',
|
||||
'devices/p2p',
|
||||
'devices/point-to-point',
|
||||
'devices/csma-cd',
|
||||
'applications',
|
||||
'mobility',
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user