serial channel functionality

This commit is contained in:
Craig Dowell
2007-03-18 03:43:49 -07:00
parent c6bb8b9b64
commit e4f68cc58d
10 changed files with 217 additions and 96 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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