serial channel functionality
This commit is contained in:
@@ -358,13 +358,4 @@ ns3.add(sample_ns2_simple)
|
||||
sample_ns2_simple.add_deps(['core', 'simulator', 'node', 'serial'])
|
||||
sample_ns2_simple.add_source('ns-2/simple.cc')
|
||||
|
||||
sample_channel = build.Ns3Module('sample-channel', 'samples')
|
||||
sample_channel.set_executable()
|
||||
ns3.add(sample_channel)
|
||||
sample_channel.add_dep ('common')
|
||||
sample_channel.add_dep ('node')
|
||||
sample_channel.add_dep ('core')
|
||||
sample_channel.add_dep ('serial')
|
||||
sample_channel.add_source('main-channel.cc')
|
||||
|
||||
ns3.generate_dependencies()
|
||||
|
||||
@@ -199,6 +199,9 @@ PrintRoutingTable (InternetNode *a, std::string name)
|
||||
|
||||
static SerialChannel *
|
||||
AddDuplexLink(
|
||||
std::string &name,
|
||||
uint64_t bps,
|
||||
uint32_t delay,
|
||||
InternetNode* a,
|
||||
const Ipv4Address& addra,
|
||||
const MacAddress& macaddra,
|
||||
@@ -207,11 +210,10 @@ AddDuplexLink(
|
||||
const MacAddress& macaddrb,
|
||||
// const Rate& rate,
|
||||
// const Time& delay,
|
||||
TraceContainer &traceContainer,
|
||||
std::string &name)
|
||||
TraceContainer &traceContainer)
|
||||
{
|
||||
std::string qName;
|
||||
SerialChannel* channel = new SerialChannel();
|
||||
SerialChannel* channel = new SerialChannel(name, bps, MilliSeconds(delay));
|
||||
|
||||
// Duplex link is assumed to be subnetted as a /30
|
||||
// May run this unnumbered in the future?
|
||||
@@ -276,6 +278,16 @@ SetupTrace (TraceContainer &container, Tracer &tracer)
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
#if 0
|
||||
DebugComponentEnable("Queue");
|
||||
DebugComponentEnable("DropTailQueue");
|
||||
DebugComponentEnable("Channel");
|
||||
DebugComponentEnable("SerialChannel");
|
||||
DebugComponentEnable("SerialNetDevice");
|
||||
DebugComponentEnable("SerialPhy");
|
||||
#endif
|
||||
|
||||
// ** Here, some kind of factory or topology object will instantiates
|
||||
// ** four identical nodes; for now, we just explicitly create them
|
||||
InternetNode *n0 = new InternetNode();
|
||||
@@ -295,24 +307,24 @@ int main (int argc, char *argv[])
|
||||
std::string channelName;
|
||||
|
||||
channelName = "Channel 1";
|
||||
SerialChannel* ch1 = AddDuplexLink (
|
||||
SerialChannel* ch1 = AddDuplexLink (channelName, 5000000, 2,
|
||||
n0, Ipv4Address("10.1.1.1"), MacAddress("00:00:00:00:00:01"),
|
||||
n2, Ipv4Address("10.1.1.2"), MacAddress("00:00:00:00:00:02"),
|
||||
traceContainer, channelName);
|
||||
traceContainer);
|
||||
SetupTrace (traceContainer, tracer);
|
||||
|
||||
channelName = "Channel 2";
|
||||
SerialChannel* ch2 = AddDuplexLink (
|
||||
SerialChannel* ch2 = AddDuplexLink (channelName, 5000000, 2,
|
||||
n1, Ipv4Address("10.1.2.1"), MacAddress("00:00:00:00:00:03"),
|
||||
n2, Ipv4Address("10.1.2.2"), MacAddress("00:00:00:00:00:04"),
|
||||
traceContainer, channelName);
|
||||
traceContainer);
|
||||
SetupTrace (traceContainer, tracer);
|
||||
|
||||
channelName = "Channel 3";
|
||||
SerialChannel* ch3 = AddDuplexLink (
|
||||
SerialChannel* ch3 = AddDuplexLink (channelName, 1500000, 10,
|
||||
n2, Ipv4Address("10.1.3.1"), MacAddress("00:00:00:00:00:05"),
|
||||
n3, Ipv4Address("10.1.3.2"), MacAddress("00:00:00:00:00:06"),
|
||||
traceContainer, channelName);
|
||||
traceContainer);
|
||||
SetupTrace (traceContainer, tracer);
|
||||
|
||||
UdpSocket *source0 = new UdpSocket (n0);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -29,53 +28,32 @@ NS_DEBUG_COMPONENT_DEFINE ("Channel");
|
||||
namespace ns3 {
|
||||
|
||||
Channel::Channel ()
|
||||
: m_name("Channel")
|
||||
{
|
||||
NS_DEBUG("Channel::Channel ()");
|
||||
}
|
||||
|
||||
Channel::Channel (std::string name)
|
||||
: m_name(name)
|
||||
{
|
||||
NS_DEBUG("Channel::Channel (" << name << ")");
|
||||
}
|
||||
|
||||
Channel::~Channel ()
|
||||
{
|
||||
NS_DEBUG("Channel::~Channel ()");
|
||||
}
|
||||
|
||||
bool
|
||||
Channel::DoConnectToUpper (LayerConnectorUpper &upper)
|
||||
void
|
||||
Channel::SetName(std::string name)
|
||||
{
|
||||
NS_DEBUG("Channel::DoConnectToUpper (" << &upper << ")");
|
||||
m_connectorList.push_back(&upper);
|
||||
|
||||
return true;
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
bool
|
||||
Channel::LowerDoNotify (LayerConnectorUpper *upper)
|
||||
std::string
|
||||
Channel::GetName(void)
|
||||
{
|
||||
NS_DEBUG("Channel::LowerDoNotify ()");
|
||||
|
||||
Packet p;
|
||||
|
||||
NS_DEBUG("Channel::LowerDoNotify (): Starting pull");
|
||||
|
||||
upper->UpperPull(p);
|
||||
|
||||
NS_DEBUG("Channel::LowerDoNotify (): Got bits, Propagate()");
|
||||
|
||||
return Propagate(p);
|
||||
}
|
||||
|
||||
bool
|
||||
Channel::Propagate (Packet &p)
|
||||
{
|
||||
NS_DEBUG("Channel::Propagate (" << &p << ")");
|
||||
|
||||
for (ConnectorList::const_iterator i = m_connectorList.begin ();
|
||||
i != m_connectorList.end ();
|
||||
i++)
|
||||
{
|
||||
(*i)->UpperSendUp (p);
|
||||
}
|
||||
|
||||
return true;
|
||||
return m_name;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -30,21 +29,24 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Channel : public LayerConnectorLower
|
||||
/**
|
||||
* \brief Abstract Channel Base Class.
|
||||
*
|
||||
* A channel is a logical path over which information flows. The path can
|
||||
* be as simple as a short piece of wire, or as complicated as space-time.
|
||||
*/
|
||||
class Channel
|
||||
{
|
||||
public:
|
||||
Channel ();
|
||||
Channel (std::string name);
|
||||
virtual ~Channel ();
|
||||
|
||||
// Called by the physical layer to cause bits to propagate along the channel
|
||||
// The channel will call Receive on each of the phys.
|
||||
bool Propagate (Packet &p);
|
||||
bool DoConnectToUpper (LayerConnectorUpper &upper);
|
||||
bool LowerDoNotify (LayerConnectorUpper *upper);
|
||||
virtual void SetName(std::string);
|
||||
virtual std::string GetName(void);
|
||||
|
||||
protected:
|
||||
typedef std::list<LayerConnectorUpper *> ConnectorList;
|
||||
ConnectorList m_connectorList;
|
||||
std::string m_name;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -15,31 +15,123 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Craig Dowell <craigdo@ee.washington.edu>
|
||||
*/
|
||||
|
||||
#include "serial-channel.h"
|
||||
#include "serial-net-device.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/debug.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("SerialChannel");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
void
|
||||
SerialChannel::Attach(SerialNetDevice* nd)
|
||||
//
|
||||
// By default, you get a channel with the name "Serial Channel" that has an
|
||||
// "infitely" fast transmission speed and zero delay.
|
||||
//
|
||||
SerialChannel::SerialChannel()
|
||||
:
|
||||
Channel ("Serial Channel"),
|
||||
m_bps (UINT64_MAX),
|
||||
m_delay (Seconds(0)),
|
||||
m_nDevices(0)
|
||||
{
|
||||
nd->Attach(this);
|
||||
m_devices.push_back (nd);
|
||||
NS_DEBUG("SerialChannel::SerialChannel ()");
|
||||
}
|
||||
|
||||
bool
|
||||
SerialChannel::Send(Packet& p, SerialNetDevice* caller)
|
||||
SerialChannel::SerialChannel(
|
||||
std::string name,
|
||||
DataRate bps,
|
||||
Time delay)
|
||||
:
|
||||
Channel (name),
|
||||
m_bps (bps),
|
||||
m_delay (delay),
|
||||
m_nDevices(0)
|
||||
{
|
||||
for (NetDevicesCI i = m_devices.begin (); i != m_devices.end (); i++) {
|
||||
if (caller != (*i)) {
|
||||
(*i)->Receive (p);
|
||||
return true;
|
||||
}
|
||||
NS_DEBUG("SerialChannel::SerialChannel (" << name << ", " << bps << ", " <<
|
||||
delay << ")");
|
||||
}
|
||||
|
||||
void
|
||||
SerialChannel::Attach(SerialNetDevice *device)
|
||||
{
|
||||
NS_DEBUG("SerialChannel::Attach (" << device << ")");
|
||||
NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
|
||||
NS_ASSERT(device);
|
||||
|
||||
m_link[m_nDevices].m_src = device;
|
||||
++m_nDevices;
|
||||
//
|
||||
// If we have both devices connected to the channel, then finish introducing
|
||||
// the two halves and set the links to IDLE.
|
||||
//
|
||||
if (m_nDevices == N_DEVICES)
|
||||
{
|
||||
m_link[0].m_dst = m_link[1].m_src;
|
||||
m_link[1].m_dst = m_link[0].m_src;
|
||||
m_link[0].m_state = IDLE;
|
||||
m_link[1].m_state = IDLE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
SerialChannel::TransmitCompleteEvent(Packet &p, SerialNetDevice *src)
|
||||
{
|
||||
NS_DEBUG("SerialChannel::TransmitCompleteEvent (" << &p << ", " <<
|
||||
src << ")");
|
||||
|
||||
NS_ASSERT(m_link[0].m_state != INITIALIZING);
|
||||
NS_ASSERT(m_link[1].m_state != INITIALIZING);
|
||||
uint32_t wire = src == m_link[0].m_src ? 0 : 1;
|
||||
NS_ASSERT(m_link[wire].m_state == TRANSMITTING);
|
||||
|
||||
m_link[wire].m_state = IDLE;
|
||||
|
||||
NS_DEBUG("SerialChannel::TransmitCompleteEvent (): Receive()");
|
||||
|
||||
m_link[wire].m_dst->Receive (p);
|
||||
}
|
||||
|
||||
bool
|
||||
SerialChannel::Propagate(Packet& p, SerialNetDevice* src)
|
||||
{
|
||||
NS_DEBUG("SerialChannel::DoPropagate (" << &p << ", " << src << ")");
|
||||
|
||||
NS_ASSERT(m_link[0].m_state != INITIALIZING);
|
||||
NS_ASSERT(m_link[1].m_state != INITIALIZING);
|
||||
|
||||
uint32_t wire = src == m_link[0].m_src ? 0 : 1;
|
||||
|
||||
if (m_link[wire].m_state == TRANSMITTING)
|
||||
{
|
||||
NS_DEBUG("SerialChannel::DoPropagate (): TRANSMITTING, return");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_link[wire].m_state = TRANSMITTING;
|
||||
|
||||
//
|
||||
// I believe Raj has a method in the DataRate class to do this. Should use
|
||||
// it when it is available.
|
||||
//
|
||||
Time tEvent = Simulator::Now () +
|
||||
Seconds (static_cast<double> (p.GetSize() * 8) /
|
||||
static_cast<double> (m_bps)) + m_delay;
|
||||
|
||||
NS_DEBUG("SerialChannel::DoSend (): Schedule Receive at " << tEvent);
|
||||
|
||||
#if 0
|
||||
Simulator::Schedule (tEvent, &SerialChannel::TransmitCompleteEvent, this,
|
||||
p, src);
|
||||
#else
|
||||
TransmitCompleteEvent (p, src);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -17,31 +16,81 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// The queue base class does not have any limit based on the number
|
||||
// of packets or number of bytes. It is, conceptually, infinite
|
||||
// by default. Only subclasses define limitations.
|
||||
// The base class implements tracing and basic statistics calculations.
|
||||
|
||||
#ifndef CHANNEL_SERIAL_H
|
||||
#define CHANNEL_SERIAL_H
|
||||
#ifndef SERIAL_CHANNEL_H
|
||||
#define SERIAL_CHANNEL_H
|
||||
|
||||
#include <list>
|
||||
#include "serial-net-device.h"
|
||||
#include "channel.h"
|
||||
#include "serial-phy.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/nstime.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
// Simple SerialChannel class
|
||||
class SerialChannel {
|
||||
// temporary until Raj's code makes it into the dev tree
|
||||
typedef uint64_t DataRate;
|
||||
|
||||
/**
|
||||
* \brief Simple Serial Channel.
|
||||
*
|
||||
* This class represents a very simple serial channel. Think full duplex
|
||||
* RS-232 or RS-422 with null modem and no handshaking. There is no multi-
|
||||
* drop capability on this channel -- there can be a maximum of two serial
|
||||
* net devices connected. Once we start talking about multi-drop, or CSMA,
|
||||
* or some other sharing mechanism, things begin getting complicated quickly.
|
||||
* Rather than invent some ad-hoc mechanism, we just Keep It Simple everywhere.
|
||||
*
|
||||
* When the channel is instaniated, the constructor takes parameters for
|
||||
* a single channel speed, in bits per second, and a delay time as a Time
|
||||
* object. Both directions use the same speed and delay time.
|
||||
*
|
||||
* There are two "wires" in the channel. The first device connected gets the
|
||||
* [0] wire to transmit on. The second device gets the [1] wire. There is a
|
||||
* state (IDLE, TRANSMITTING) associated with each wire.
|
||||
*/
|
||||
class SerialChannel : public Channel {
|
||||
public:
|
||||
bool Send(Packet& p, SerialNetDevice *caller);
|
||||
//
|
||||
// This is really kidding myself, since just setting N_DEVICES to 3 isn't
|
||||
// going to come close to magically creating a multi-drop link, but I can't
|
||||
// bring myself to just type 2 in the code (even though I type 0 and 1 :-).
|
||||
//
|
||||
static const int N_DEVICES = 2;
|
||||
|
||||
SerialChannel ();
|
||||
SerialChannel (std::string name, DataRate bps, Time delay);
|
||||
|
||||
void Attach (SerialNetDevice* nd);
|
||||
private:
|
||||
typedef std::list<SerialNetDevice *> NetDevices;
|
||||
typedef std::list<SerialNetDevice *>::const_iterator NetDevicesCI;
|
||||
NetDevices m_devices;
|
||||
bool Propagate (Packet& p, SerialNetDevice *src);
|
||||
|
||||
protected:
|
||||
void TransmitCompleteEvent (Packet &p, SerialNetDevice *src);
|
||||
|
||||
std::string m_name;
|
||||
DataRate m_bps;
|
||||
Time m_delay;
|
||||
|
||||
int32_t m_nDevices;
|
||||
|
||||
enum WireState
|
||||
{
|
||||
INITIALIZING,
|
||||
IDLE,
|
||||
TRANSMITTING
|
||||
};
|
||||
|
||||
class Link
|
||||
{
|
||||
public:
|
||||
Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
|
||||
WireState m_state;
|
||||
SerialNetDevice *m_src;
|
||||
SerialNetDevice *m_dst;
|
||||
};
|
||||
|
||||
Link m_link[N_DEVICES];
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* CHANNEL_SERIAL__H */
|
||||
#endif /* SERIAL_CHANNEL_H */
|
||||
|
||||
@@ -125,7 +125,7 @@ SerialNetDevice::NotifyDataAvailable(void)
|
||||
// send packet to address tag.address
|
||||
#endif
|
||||
NS_DEBUG ("SerialNetDevice::NotifyDataAvailable (): Dequeued");
|
||||
m_channel->Send(p, this);
|
||||
m_channel->Propagate(p, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
||||
@@ -55,7 +55,7 @@ SerialPhy::NotifyDataAvailable(void)
|
||||
// send packet to address tag.address
|
||||
#endif
|
||||
NS_DEBUG ("SerialPhy::NotifyDataAvailable (): Dequeued");
|
||||
m_netdevice->GetChannel()->Send(p, m_netdevice);
|
||||
m_netdevice->GetChannel()->Propagate(p, m_netdevice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ void
|
||||
SerialPhy::Receive (Packet& p)
|
||||
{
|
||||
NS_DEBUG ("SerialPhy::Receive (" << &p << ")");
|
||||
|
||||
m_netdevice->ForwardUp (p);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
||||
Reference in New Issue
Block a user