branch merge

This commit is contained in:
Craig Dowell
2010-02-23 12:18:35 -08:00
47 changed files with 2707 additions and 1217 deletions

View File

@@ -121,7 +121,7 @@ event with a context different from the execution context of the caller. This AP
by the ns-3 logging system to report the execution context of each log line.
<li><b>Object::DoStart</b>: Users who need to complete their object setup at the start of a simulation
can override this virtual method, perform their adhoc setup, and then, must chain up to their parent.
<li><b>Aod hoc On-Demand Distance Vector (AODV)</b> routing model,
<li><b>Ad hoc On-Demand Distance Vector (AODV)</b> routing model,
<a href=http://www.ietf.org/rfc/rfc3561.txt>RFC 3561</a> </li>
<li><b>Ipv4::IsDestinationAddress (Ipv4Address address, uint32_t iif)</b> Method added to support checks of whether a destination address should be accepted
as one of the host's own addresses. RFC 1122 Strong/Weak end system behavior can be changed with a new attribute (WeakEsModel) in class Ipv4. </li>

File diff suppressed because it is too large Load Diff

View File

@@ -135,7 +135,7 @@ If you want to store a newed object into a smart pointer,
we recommend you to use the CreateObject template functions
to create the object and store it in a smart pointer to avoid
memory leaks. These functions are really small convenience
functions and their goal is just is save you a small
functions and their goal is just to save you a small
bit of typing.
@subsection CreateObject and Create
@@ -292,7 +292,7 @@ For example:
factory.Set ("SystemLoss", DoubleValue (3.0));
// Create another object
Ptr<Object> object = m_factory.Create ();
Wend verbatim
@end verbatim
@node Downcasting
@section Downcasting

View File

@@ -0,0 +1,7 @@
# Container with network virtualized using a pre-configured bridge named br-left and
# veth pair virtual network devices
lxc.utsname = left
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br-left
lxc.network.ipv4 = 10.0.0.1/24

View File

@@ -0,0 +1,7 @@
# Container with network virtualized using a pre-configured bridge named br-right and
# veth pair virtual network devices
lxc.utsname = right
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br-right
lxc.network.ipv4 = 10.0.0.2/24

View File

@@ -0,0 +1,133 @@
/* -*- 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
*/
//
// This is an illustration of how one could use virtualization techniques to
// allow running applications on virtual machines talking over simulated
// networks.
//
// The actual steps required to configure the virtual machines can be rather
// involved, so we don't go into that here. Please have a look at one of
// our HOWTOs on the nsnam wiki for more details about how to get the
// system confgured. For an example, have a look at "HOWTO Use Linux
// Containers to set up virtual networks" which uses this code as an
// example.
//
// The configuration you are after is explained in great detail in the
// HOWTO, but looks like the following:
//
// +----------+ +----------+
// | virtual | | virtual |
// | Linux | | Linux |
// | Host | | Host |
// | | | |
// | eth0 | | eth0 |
// +----------+ +----------+
// | |
// +----------+ +----------+
// | Linux | | Linux |
// | Bridge | | Bridge |
// +----------+ +----------+
// | |
// +------------+ +-------------+
// | "tap-left" | | "tap-right" |
// +------------+ +-------------+
// | n0 n1 |
// | +--------+ +--------+ |
// +-------| tap | | tap |-------+
// | bridge | | bridge |
// +--------+ +--------+
// | CSMA | | CSMA |
// +--------+ +--------+
// | |
// | |
// | |
// ===============
// CSMA LAN 10.0.0
//
// The CSMA device on node zero is: 10.0.0.1
// The CSMA device on node one is: 10.0.0.2
//
#include <iostream>
#include <fstream>
#include "ns3/simulator-module.h"
#include "ns3/node-module.h"
#include "ns3/core-module.h"
#include "ns3/helper-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TapCsmaVirtualMachineExample");
int
main (int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse (argc, argv);
//
// We are interacting with the outside, real, world. This means we have to
// interact in real-time and therefore means we have to use the real-time
// simulator and take the time to calculate checksums.
//
GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
//
// Create two ghost nodes. The first will represent the virtual machine host
// on the left side of the network; and the second will represent the VM on
// the right side.
//
NodeContainer nodes;
nodes.Create (2);
//
// Use a CsmaHelper to get a CSMA channel created, and the needed net
// devices installed on both of the nodes. The data rate and delay for the
// channel can be set through the command-line parser. For example,
//
// ./waf --run "tap=csma-virtual-machine --ns3::CsmaChannel::DataRate=10000000"
//
CsmaHelper csma;
NetDeviceContainer devices = csma.Install (nodes);
//
// Use the TapBridgeHelper to connect to the pre-configured tap devices for
// the left side. We go with "UseBridge" mode since the CSMA devices support
// promiscuous mode and can therefore make it appear that the bridge is
// extended into ns-3. The install method essentially bridges the specified
// tap to the specified CSMA device.
//
TapBridgeHelper tapBridge;
tapBridge.SetAttribute ("Mode", StringValue ("UseBridge"));
tapBridge.SetAttribute ("DeviceName", StringValue ("tap-left"));
tapBridge.Install (nodes.Get (0), devices.Get (0));
//
// Connect the right side tap to the right side CSMA device on the right-side
// ghost node.
//
tapBridge.SetAttribute ("DeviceName", StringValue ("tap-right"));
tapBridge.Install (nodes.Get (1), devices.Get (1));
//
// Run the simulation for ten minutes to give the user time to play around
//
Simulator::Stop (Seconds (600.));
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -0,0 +1,171 @@
/* -*- 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
*/
//
// This is an illustration of how one could use virtualization techniques to
// allow running applications on virtual machines talking over simulated
// networks.
//
// The actual steps required to configure the virtual machines can be rather
// involved, so we don't go into that here. Please have a look at one of
// our HOWTOs on the nsnam wiki for more details about how to get the
// system confgured. For an example, have a look at "HOWTO Use Linux
// Containers to set up virtual networks" which uses this code as an
// example.
//
// The configuration you are after is explained in great detail in the
// HOWTO, but looks like the following:
//
// +----------+ +----------+
// | virtual | | virtual |
// | Linux | | Linux |
// | Host | | Host |
// | | | |
// | eth0 | | eth0 |
// +----------+ +----------+
// | |
// +----------+ +----------+
// | Linux | | Linux |
// | Bridge | | Bridge |
// +----------+ +----------+
// | |
// +------------+ +-------------+
// | "tap-left" | | "tap-right" |
// +------------+ +-------------+
// | n0 n1 |
// | +--------+ +--------+ |
// +-------| tap | | tap |-------+
// | bridge | | bridge |
// +--------+ +--------+
// | wifi | | wifi |
// +--------+ +--------+
// | |
// ((*)) ((*))
//
// Wifi LAN 10.0.0
//
// ((*))
// |
// +--------+
// | wifi |
// +--------+
// | access |
// | point |
// +--------+
//
// The wifi device on node zero is: 10.0.0.1
// The wifi device on node one is: 10.0.0.2
// The wifi device (AP) is: 10.0.0.3
//
#include <iostream>
#include <fstream>
#include "ns3/simulator-module.h"
#include "ns3/node-module.h"
#include "ns3/core-module.h"
#include "ns3/wifi-module.h"
#include "ns3/helper-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("TapWifiVirtualMachineExample");
int
main (int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse (argc, argv);
//
// We are interacting with the outside, real, world. This means we have to
// interact in real-time and therefore means we have to use the real-time
// simulator and take the time to calculate checksums.
//
GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
//
// Create two ghost nodes. The first will represent the virtual machine host
// on the left side of the network; and the second will represent the VM on
// the right side.
//
NodeContainer nodes;
nodes.Create (2);
//
// We're going to use 802.11 A so set up a wifi helper to reflect that.
//
WifiHelper wifi = WifiHelper::Default ();
wifi.SetStandard (WIFI_PHY_STANDARD_80211a);
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("wifia-54mbs"));
//
// No reason for pesky access points, so we'll use an ad-hoc network.
//
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
wifiMac.SetType ("ns3::AdhocWifiMac");
//
// Configure the physcial layer.
//
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
//
// Install the wireless devices onto our ghost nodes.
//
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, nodes);
//
// We need location information since we are talking about wifi, so add a
// constant position to the ghost nodes.
//
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (5.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (nodes);
//
// Use the TapBridgeHelper to connect to the pre-configured tap devices for
// the left side. We go with "UseLocal" mode since the wifi devices do not
// support promiscuous mode (because of their natures0. This is a special
// case mode that allows us to extend a linux bridge into ns-3 IFF we will
// only see traffic from one other device on that bridge. That is the case
// for this configuration.
//
TapBridgeHelper tapBridge;
tapBridge.SetAttribute ("Mode", StringValue ("UseLocal"));
tapBridge.SetAttribute ("DeviceName", StringValue ("tap-left"));
tapBridge.Install (nodes.Get (0), devices.Get (0));
//
// Connect the right side tap to the right side wifi device on the right-side
// ghost node.
//
tapBridge.SetAttribute ("DeviceName", StringValue ("tap-right"));
tapBridge.Install (nodes.Get (1), devices.Get (1));
//
// Run the simulation for ten minutes to give the user time to play around
//
Simulator::Stop (Seconds (600.));
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -5,5 +5,9 @@ def build(bld):
if env['ENABLE_TAP']:
obj = bld.create_ns3_program('tap-csma', ['csma', 'tap-bridge', 'internet-stack'])
obj.source = 'tap-csma.cc'
obj = bld.create_ns3_program('tap-csma-virtual-machine', ['csma', 'tap-bridge', 'internet-stack'])
obj.source = 'tap-csma-virtual-machine.cc'
obj = bld.create_ns3_program('tap-wifi-virtual-machine', ['csma', 'tap-bridge', 'internet-stack'])
obj.source = 'tap-wifi-virtual-machine.cc'
obj = bld.create_ns3_program('tap-wifi-dumbbell', ['wifi', 'csma', 'point-to-point', 'tap-bridge', 'internet-stack'])
obj.source = 'tap-wifi-dumbbell.cc'

View File

@@ -61,7 +61,7 @@ public:
/**
* \brief creates a traceBasedStreamer application
* \param dataSize ip the destination ip address to which the stream will be sent
* \param ip the destination ip address to which the stream will be sent
* \param port the destination udp port to which the stream will be sent
* \param traceFile a path to an MPEG4 trace file formatted as follows:
* FrameNo Frametype Time[ms] Length [byte]
@@ -83,7 +83,7 @@ public:
/**
* \brief set the trace file to be used by the application
* \param traceFile a path to an MPEG4 trace file formatted as follows:
* \param filename a path to an MPEG4 trace file formatted as follows:
* Frame No Frametype Time[ms] Length [byte]
* Frame No Frametype Time[ms] Length [byte]
* ...

View File

@@ -130,6 +130,9 @@ public:
* time zone from UTC/GMT. For example, Pacific Standard Time in the US is
* GMT-8, so one would enter -8 for that correction. Defaults to 0 (UTC).
*
* \param swapMode Flag indicating a difference in endianness of the
* writing system. Defaults to false.
*
* \return false if the open succeeds, true otherwise.
*
* \warning Calling this method on an existing file will result in the loss
@@ -256,7 +259,7 @@ public:
* \param f1 First PCAP file name
* \param f2 Second PCAP file name
* \param sec [out] Time stamp of first different packet, seconds. Undefined if files doesn't differ.
* \param uses [out] Time stamp of first different packet, microseconds. Undefined if files doesn't differ.
* \param usec [out] Time stamp of first different packet, microseconds. Undefined if files doesn't differ.
* \param snapLen Snap length (if used)
*/
static bool Diff (std::string const & f1, std::string const & f2,

View File

@@ -252,7 +252,9 @@ public:
*/
double GetSystemLoss (void) const;
/**
* \Set the model antenna height above the node's Z coordinate
* \param heightAboveZ the model antenna height above the node's Z coordinate
*
* Set the model antenna height above the node's Z coordinate
*/
void SetHeightAboveZ (double heightAboveZ);

View File

@@ -1,15 +1,35 @@
/* -*- 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
*
* Authors: Faker Moatamri <faker.moatamri@sophia.inria.fr>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "attribute-default-iterator.h"
#include "ns3/type-id.h"
#include "ns3/attribute.h"
#include "ns3/object-vector.h"
#include "ns3/pointer.h"
#include "ns3/global-value.h"
#include "ns3/string.h"
namespace ns3 {
namespace ns3
{
AttributeDefaultIterator::~AttributeDefaultIterator ()
{}
{
}
void
AttributeDefaultIterator::Iterate (void)
{
@@ -17,72 +37,87 @@ AttributeDefaultIterator::Iterate (void)
{
TypeId tid = TypeId::GetRegistered (i);
if (tid.MustHideFromDocumentation ())
{
continue;
}
{
continue;
}
bool calledStart = false;
for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
{
uint32_t flags = tid.GetAttributeFlags (j);
if (!(flags & TypeId::ATTR_CONSTRUCT))
{
// we can't construct the attribute, so, there is no
// initial value for the attribute
continue;
}
Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (j);
if (accessor == 0)
{
continue;
}
if (!accessor->HasSetter ())
{
continue;
}
Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (j);
if (checker == 0)
{
continue;
}
Ptr<const AttributeValue> value = tid.GetAttributeInitialValue (j);
if (value == 0)
{
continue;
}
Ptr<const ObjectVectorValue> vector = DynamicCast<const ObjectVectorValue> (value);
if (vector != 0)
{
continue;
}
Ptr<const PointerValue> pointer = DynamicCast<const PointerValue> (value);
if (pointer != 0)
{
continue;
}
if (!calledStart)
{
StartVisitTypeId (tid.GetName ());
}
VisitAttribute (tid.GetAttributeName (j),
value->SerializeToString (checker));
calledStart = true;
}
{
uint32_t flags = tid.GetAttributeFlags (j);
if (!(flags & TypeId::ATTR_CONSTRUCT))
{
// we can't construct the attribute, so, there is no
// initial value for the attribute
continue;
}
Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (j);
//No accessor, go to next attribute
if (accessor == 0)
{
continue;
}
if (!accessor->HasSetter ())
{
//skip this attribute it doesn't have an setter
continue;
}
Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (j);
if (checker == 0)
{
//skip, it doesn't have a checker
continue;
}
Ptr<const AttributeValue> value = tid.GetAttributeInitialValue (j);
if (value == 0)
{
//No value, check next attribute
continue;
}
Ptr<const ObjectVectorValue> vector = DynamicCast<const ObjectVectorValue> (value);
if (vector != 0)
{
//a vector value, won't take it
continue;
}
Ptr<const PointerValue> pointer = DynamicCast<const PointerValue> (value);
if (pointer != 0)
{
//pointer value, won't take it
continue;
}
//We take only values, no pointers or vectors
if (!calledStart)
{
StartVisitTypeId (tid.GetName ());
}
VisitAttribute (tid, tid.GetAttributeName (j), value->SerializeToString (checker), j);
calledStart = true;
}
if (calledStart)
{
EndVisitTypeId ();
}
{
EndVisitTypeId ();
}
}
}
void
AttributeDefaultIterator::StartVisitTypeId (std::string name)
{}
{
}
void
AttributeDefaultIterator::EndVisitTypeId (void)
{}
void
AttributeDefaultIterator::VisitAttribute (std::string name, std::string defaultValue)
{}
{
}
void
AttributeDefaultIterator::DoVisitAttribute (std::string name, std::string defaultValue)
{
}
void
AttributeDefaultIterator::VisitAttribute (TypeId tid, std::string name, std::string defaultValue, uint32_t index)
{
DoVisitAttribute (name, defaultValue);
}
} // namespace ns3

View File

@@ -1,6 +1,26 @@
/* -*- 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
*
* Authors: Faker Moatamri <faker.moatamri@sophia.inria.fr>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef ATTRIBUTE_DEFAULT_ITERATOR_H
#define ATTRIBUTE_DEFAULT_ITERATOR_H
#include "ns3/type-id.h"
#include <string>
namespace ns3 {
@@ -9,11 +29,30 @@ class AttributeDefaultIterator
{
public:
virtual ~AttributeDefaultIterator () = 0;
/**
* \brief This function will go through all the TypeIds and get only the attributes which are
* explicit values (not vectors or pointer or arrays) and apply StartVisitTypeId
* and VisitAttribute on the attributes in one TypeId. At the end of each TypeId
* EndVisitTypeId is called.
*/
void Iterate (void);
private:
/**
* \brief Just an interface that needs to be implemented
*/
virtual void StartVisitTypeId (std::string name);
/**
* \brief Just an interface that needs to be implemented
*/
virtual void EndVisitTypeId (void);
virtual void VisitAttribute (std::string name, std::string defaultValue);
/**
* \brief This method can be implemented, otherwise, it will call DoVisitAttribute
*/
virtual void VisitAttribute (TypeId tid, std::string name, std::string defaultValue, uint32_t index);
/**
* \brief This method is just an interface and needs to be implemented
*/
virtual void DoVisitAttribute (std::string name, std::string defaultValue);
};
} // namespace ns3

View File

@@ -1,3 +1,21 @@
/* -*- 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
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "attribute-iterator.h"
#include "ns3/config.h"
#include "ns3/log.h"
@@ -13,10 +31,12 @@ namespace ns3 {
AttributeIterator::AttributeIterator ()
{}
{
}
AttributeIterator::~AttributeIterator ()
{}
{
}
void
AttributeIterator::Iterate (void)
@@ -38,9 +58,9 @@ AttributeIterator::IsExamined (Ptr<const Object> object)
for (uint32_t i = 0; i < m_examined.size (); ++i)
{
if (object == m_examined[i])
{
return true;
}
{
return true;
}
}
return false;
}
@@ -74,28 +94,36 @@ AttributeIterator::GetCurrentPath (void) const
void
AttributeIterator::DoStartVisitObject (Ptr<Object> object)
{}
{
}
void
AttributeIterator::DoEndVisitObject (void)
{}
{
}
void
AttributeIterator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> item)
{}
{
}
void
AttributeIterator::DoEndVisitPointerAttribute (void)
{}
{
}
void
AttributeIterator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector)
{}
{
}
void
AttributeIterator::DoEndVisitArrayAttribute (void)
{}
{
}
void
AttributeIterator::DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item)
{}
{
}
void
AttributeIterator::DoEndVisitArrayItem (void)
{}
{
}
void
AttributeIterator::VisitAttribute (Ptr<Object> object, std::string name)
@@ -174,58 +202,59 @@ AttributeIterator::DoIterate (Ptr<Object> object)
{
NS_LOG_DEBUG ("store " << tid.GetName ());
for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
{
Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (checker));
if (ptrChecker != 0)
{
NS_LOG_DEBUG ("pointer attribute " << tid.GetAttributeName (i));
PointerValue ptr;
object->GetAttribute (tid.GetAttributeName (i), ptr);
Ptr<Object> tmp = ptr.Get<Object> ();
if (tmp != 0)
{
StartVisitPointerAttribute (object, tid.GetAttributeName (i), tmp);
m_examined.push_back (object);
DoIterate (tmp);
m_examined.pop_back ();
EndVisitPointerAttribute ();
}
continue;
}
// attempt to cast to an object vector.
const ObjectVectorChecker *vectorChecker = dynamic_cast<const ObjectVectorChecker *> (PeekPointer (checker));
if (vectorChecker != 0)
{
NS_LOG_DEBUG ("vector attribute " << tid.GetAttributeName (i));
ObjectVectorValue vector;
object->GetAttribute (tid.GetAttributeName (i), vector);
StartVisitArrayAttribute (object, tid.GetAttributeName (i), vector);
for (uint32_t j = 0; j < vector.GetN (); ++j)
{
NS_LOG_DEBUG ("vector attribute item " << j);
Ptr<Object> tmp = vector.Get (j);
StartVisitArrayItem (vector, j, tmp);
m_examined.push_back (object);
DoIterate (tmp);
m_examined.pop_back ();
EndVisitArrayItem ();
}
EndVisitArrayAttribute ();
continue;
}
uint32_t flags = tid.GetAttributeFlags (i);
Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i);
if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () &&
(flags & TypeId::ATTR_SET) && accessor->HasSetter ())
{
VisitAttribute (object, tid.GetAttributeName (i));
}
else
{
NS_LOG_DEBUG ("could not store " << tid.GetAttributeName (i));
}
}
{
Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (checker));
if (ptrChecker != 0)
{
NS_LOG_DEBUG ("pointer attribute " << tid.GetAttributeName (i));
PointerValue ptr;
object->GetAttribute (tid.GetAttributeName (i), ptr);
Ptr<Object> tmp = ptr.Get<Object> ();
if (tmp != 0)
{
StartVisitPointerAttribute (object, tid.GetAttributeName (i),
tmp);
m_examined.push_back (object);
DoIterate (tmp);
m_examined.pop_back ();
EndVisitPointerAttribute ();
}
continue;
}
// attempt to cast to an object vector.
const ObjectVectorChecker *vectorChecker = dynamic_cast<const ObjectVectorChecker *> (PeekPointer (checker));
if (vectorChecker != 0)
{
NS_LOG_DEBUG ("vector attribute " << tid.GetAttributeName (i));
ObjectVectorValue vector;
object->GetAttribute (tid.GetAttributeName (i), vector);
StartVisitArrayAttribute (object, tid.GetAttributeName (i), vector);
for (uint32_t j = 0; j < vector.GetN (); ++j)
{
NS_LOG_DEBUG ("vector attribute item " << j);
Ptr<Object> tmp = vector.Get (j);
StartVisitArrayItem (vector, j, tmp);
m_examined.push_back (object);
DoIterate (tmp);
m_examined.pop_back ();
EndVisitArrayItem ();
}
EndVisitArrayAttribute ();
continue;
}
uint32_t flags = tid.GetAttributeFlags (i);
Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i);
if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () &&
(flags & TypeId::ATTR_SET) && accessor->HasSetter ())
{
VisitAttribute (object, tid.GetAttributeName (i));
}
else
{
NS_LOG_DEBUG ("could not store " << tid.GetAttributeName (i));
}
}
}
Object::AggregateIterator iter = object->GetAggregateIterator ();
bool recursiveAggregate = false;
@@ -233,22 +262,22 @@ AttributeIterator::DoIterate (Ptr<Object> object)
{
Ptr<const Object> tmp = iter.Next ();
if (IsExamined (tmp))
{
recursiveAggregate = true;
}
{
recursiveAggregate = true;
}
}
if (!recursiveAggregate)
{
iter = object->GetAggregateIterator ();
while (iter.HasNext ())
{
Ptr<Object> tmp = const_cast<Object *> (PeekPointer (iter.Next ()));
StartVisitObject (tmp);
m_examined.push_back (object);
DoIterate (tmp);
m_examined.pop_back ();
EndVisitObject ();
}
{
Ptr<Object> tmp = const_cast<Object *> (PeekPointer (iter.Next ()));
StartVisitObject (tmp);
m_examined.push_back (object);
DoIterate (tmp);
m_examined.pop_back ();
EndVisitObject ();
}
}
}

View File

@@ -1,3 +1,21 @@
/* -*- 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
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef ATTRIBUTE_ITERATOR_H
#define ATTRIBUTE_ITERATOR_H

View File

@@ -0,0 +1,594 @@
/* -*- 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
*
* Authors: Faker Moatamri <faker.moatamri@sophia.inria.fr>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "display-functions.h"
#include "raw-text-config.h"
#include "ns3/config.h"
#include "ns3/string.h"
#include "ns3/pointer.h"
namespace ns3 {
/**
* This function includes the name of the attribute or the editable value
* in the second column
*/
void
cell_data_function_col_1 (GtkTreeViewColumn *col, GtkCellRenderer *renderer,
GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
ModelNode *node;
gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
if (node->type == ModelNode::NODE_ATTRIBUTE)
{
StringValue str;
node->object->GetAttribute (node->name, str);
g_object_set (renderer, "text", str.Get ().c_str (), (char*) 0);
g_object_set (renderer, "editable", TRUE, (char*) 0);
}
else
{
g_object_set (renderer, "text", "", (char*) 0);
g_object_set (renderer, "editable", FALSE, (char*) 0);
}
}
/**
* This function includes the name of the object, pointer, vector or vector item
* in the first column
*/
void
cell_data_function_col_0 (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model,
GtkTreeIter *iter, gpointer user_data)
{
ModelNode *node;
gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
g_object_set (renderer, "editable", FALSE, (char*) 0);
switch (node->type)
{
case ModelNode::NODE_OBJECT:
g_object_set (renderer, "text", node->object->GetInstanceTypeId ().GetName ().c_str (), (char*) 0);
break;
case ModelNode::NODE_POINTER:
g_object_set (renderer, "text", node->name.c_str (), (char*) 0);
break;
case ModelNode::NODE_VECTOR:
g_object_set (renderer, "text", node->name.c_str (), (char*) 0);
break;
case ModelNode::NODE_VECTOR_ITEM:
{
std::stringstream oss;
oss << node->index;
g_object_set (renderer, "text", oss.str ().c_str (), (char*) 0);
}
break;
case ModelNode::NODE_ATTRIBUTE:
g_object_set (renderer, "text", node->name.c_str (), (char*) 0);
break;
}
}
/**
* This is the callback called when the value of an attribute is changed
*/
void
cell_edited_callback (GtkCellRendererText *cell, gchar *path_string,
gchar *new_text, gpointer user_data)
{
GtkTreeModel *model = GTK_TREE_MODEL (user_data);
GtkTreeIter iter;
gtk_tree_model_get_iter_from_string (model, &iter, path_string);
ModelNode *node;
gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
NS_ASSERT (node->type == ModelNode::NODE_ATTRIBUTE);
node->object->SetAttribute (node->name, StringValue (new_text));
}
/**
* This function gets the column number 0 or 1 from the mouse
* click
*/
int
get_col_number_from_tree_view_column (GtkTreeViewColumn *col)
{
GList *cols;
int num;
g_return_val_if_fail (col != 0, -1);
g_return_val_if_fail (col->tree_view != 0, -1);
cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (col->tree_view));
num = g_list_index (cols, (gpointer) col);
g_list_free (cols);
return num;
}
/**
* This function displays the tooltip for an object, pointer, vector
* item or an attribute
*/
gboolean
cell_tooltip_callback (GtkWidget *widget, gint x, gint y, gboolean keyboard_tip,
GtkTooltip *tooltip, gpointer user_data)
{
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeViewColumn * column;
if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget), &x, &y,
keyboard_tip, &model, 0, &iter))
{
return FALSE;
}
if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, 0, &column, 0, 0))
{
return FALSE;
}
int col = get_col_number_from_tree_view_column (column);
ModelNode *node;
gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
switch (node->type)
{
case ModelNode::NODE_OBJECT:
if (col == 0)
{
std::string tip = "This object is of type "
+ node->object->GetInstanceTypeId ().GetName ();
gtk_tooltip_set_text (tooltip, tip.c_str ());
return TRUE;
}
break;
case ModelNode::NODE_POINTER:
if (col == 0)
{
PointerValue ptr;
node->object->GetAttribute (node->name, ptr);
std::string tip = "This object is of type "
+ ptr.GetObject ()->GetInstanceTypeId ().GetName ();
gtk_tooltip_set_text (tooltip, tip.c_str ());
return TRUE;
}
break;
case ModelNode::NODE_VECTOR:
break;
case ModelNode::NODE_VECTOR_ITEM:
if (col == 0)
{
std::string tip = "This object is of type "
+ node->object->GetInstanceTypeId ().GetName ();
gtk_tooltip_set_text (tooltip, tip.c_str ());
return TRUE;
}
break;
case ModelNode::NODE_ATTRIBUTE:
{
uint32_t attrIndex = 0;
TypeId tid;
for (tid = node->object->GetInstanceTypeId (); tid.HasParent (); tid
= tid.GetParent ())
{
for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
{
if (tid.GetAttributeName (i) == node->name)
{
attrIndex = i;
goto out;
}
}
}
out: if (col == 0)
{
std::string tip = tid.GetAttributeHelp (attrIndex);
gtk_tooltip_set_text (tooltip, tip.c_str ());
}
else
{
Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (
attrIndex);
std::string tip;
tip = "This attribute is of type " + checker->GetValueTypeName ();
if (checker->HasUnderlyingTypeInformation ())
{
tip += " " + checker->GetUnderlyingTypeInformation ();
}
gtk_tooltip_set_text (tooltip, tip.c_str ());
}
return TRUE;
}
break;
}
return FALSE;
}
/**
* This is the main view opening the widget, getting tooltips and drawing the
* tree of attributes...
*/
GtkWidget *
create_view (GtkTreeStore *model)
{
GtkTreeViewColumn *col;
GtkCellRenderer *renderer;
GtkWidget *view;
view = gtk_tree_view_new ();
g_object_set (view, "has-tooltip", TRUE, (char*) 0);
g_signal_connect (view, "query-tooltip", (GCallback) cell_tooltip_callback, 0);
gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
col = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (col, "Object Attributes");
gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (col, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_0, 0, 0);
g_object_set (renderer, "editable", FALSE, (char*) 0);
col = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (col, "Attribute Value");
gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
renderer = gtk_cell_renderer_text_new ();
g_signal_connect (renderer, "edited", (GCallback) cell_edited_callback, model);
gtk_tree_view_column_pack_start (col, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_1, 0, 0);
gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (model));
g_object_unref (model); /* destroy model automatically with view */
return view;
}
/**
* This is the action done when the user presses on the save button.
* It will save the config to a file.
*/
void
save_clicked (GtkButton *button, gpointer user_data)
{
GtkWidget *parent_window = GTK_WIDGET (user_data);
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("Save File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE,
GTK_RESPONSE_ACCEPT, (char *) 0);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
TRUE);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "config.txt");
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
RawTextConfigSave config;
config.SetFilename (filename);
config.Attributes ();
g_free (filename);
}
gtk_widget_destroy (dialog);
}
/**
* If the user presses the button load, it will load the config file into memory.
*/
void
load_clicked (GtkButton *button, gpointer user_data)
{
GtkWidget *parent_window = GTK_WIDGET (user_data);
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("Open File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN,
GTK_RESPONSE_ACCEPT, (char *) 0);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
RawTextConfigLoad config;
config.SetFilename (filename);
config.Attributes ();
}
gtk_widget_destroy (dialog);
}
/**
* Exit the window when exit button is pressed
*/
void
exit_clicked_callback (GtkButton *button, gpointer user_data)
{
gtk_main_quit ();
gtk_widget_hide (GTK_WIDGET (user_data));
}
/**
* Exit the application
*/
gboolean
delete_event_callback (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
gtk_main_quit ();
gtk_widget_hide (GTK_WIDGET (user_data));
return TRUE;
}
/**
* Delete the tree model contents
*/
gboolean
clean_model_callback (GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter *iter, gpointer data)
{
ModelNode *node;
gtk_tree_model_get (GTK_TREE_MODEL (model), iter, COL_NODE, &node, -1);
delete node;
gtk_tree_store_set (GTK_TREE_STORE (model), iter, COL_NODE, (ModelNode*) 0,
-1);
return FALSE;
}
/************************** display functions used by default configurator **********************/
/**
* This function writes data in the second column, this data is going to be editable
* if it is a NODE_ATTRIBUTE
*/
void
cell_data_function_col_1_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer,
GtkTreeModel *model, GtkTreeIter *iter,
gpointer user_data)
{
ModelTypeid *node;
gtk_tree_model_get (model, iter, COL_TYPEID, &node, -1);
if (node->type == ModelTypeid::NODE_ATTRIBUTE)
{
g_object_set (renderer, "text", node->defaultValue.c_str (), (char*) 0);
g_object_set (renderer, "editable", TRUE, (char*) 0);
}
else
{
g_object_set (renderer, "text", "", (char*) 0);
g_object_set (renderer, "editable", FALSE, (char*) 0);
}
}
/**
* This function writes the attribute or typeid name in the column 0
*/
void
cell_data_function_col_0_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model,
GtkTreeIter *iter, gpointer user_data)
{
ModelTypeid *node;
gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
g_object_set (renderer, "editable", FALSE, (char*) 0);
switch (node->type)
{
case ModelTypeid::NODE_TYPEID:
g_object_set (renderer, "text", node->tid.GetName ().c_str (), (char*) 0);
break;
case ModelTypeid::NODE_ATTRIBUTE:
g_object_set (renderer, "text", node->name.c_str (), (char*) 0);
break;
}
}
/**
* This functions is called whenever there is a change in the value of an attribute
* If the input value is ok, it will be updated in the default value and in the
* gui, otherwise, it won't be updated in both.
*/
void
cell_edited_callback_config_default (GtkCellRendererText *cell, gchar *path_string,
gchar *new_text, gpointer user_data)
{
GtkTreeModel *model = GTK_TREE_MODEL (user_data);
GtkTreeIter iter;
gtk_tree_model_get_iter_from_string (model, &iter, path_string);
ModelTypeid *node;
gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
NS_ASSERT (node->type == ModelTypeid::NODE_ATTRIBUTE);
if (Config::SetDefaultFailSafe (node->tid.GetAttributeFullName (node->index),StringValue (new_text)))
{
node->defaultValue = new_text;
}
}
/**
* This function is used to display a tooltip whenever the user puts the mouse
* over a type ID or an attribute. It will give the type and the possible values of
* an attribute value and the type of the object for an attribute object or a
* typeID object
*/
gboolean
cell_tooltip_callback_config_default (GtkWidget *widget, gint x, gint y,
gboolean keyboard_tip, GtkTooltip *tooltip, gpointer user_data)
{
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeViewColumn * column;
if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget), &x, &y,
keyboard_tip, &model, 0, &iter))
{
return FALSE;
}
if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, 0, &column, 0, 0))
{
return FALSE;
}
int col = get_col_number_from_tree_view_column (column);
ModelTypeid *node;
gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
switch (node->type)
{
case ModelTypeid::NODE_TYPEID:
if (col == 0)
{
std::string tip = "This object is of type " + node->tid.GetName ();
gtk_tooltip_set_text (tooltip, tip.c_str ());
return TRUE;
}
break;
case ModelTypeid::NODE_ATTRIBUTE:
{
uint32_t attrIndex = node->index;
if (col == 0)
{
std::string tip = node->tid.GetAttributeHelp (attrIndex);
gtk_tooltip_set_text (tooltip, tip.c_str ());
}
else
{
Ptr<const AttributeChecker> checker = node->tid.GetAttributeChecker (attrIndex);
std::string tip;
tip = "This attribute is of type " + checker->GetValueTypeName ();
if (checker->HasUnderlyingTypeInformation ())
{
tip += " " + checker->GetUnderlyingTypeInformation ();
}
gtk_tooltip_set_text (tooltip, tip.c_str ());
}
return TRUE;
}
break;
}
return FALSE;
}
/**
* This is the action done when the user presses on the save button.
* It will save the config to a file.
*/
void
save_clicked_default (GtkButton *button, gpointer user_data)
{
GtkWidget *parent_window = GTK_WIDGET (user_data);
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("Save File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE,
GTK_RESPONSE_ACCEPT, (char *) 0);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
TRUE);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "config.txt");
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
RawTextConfigSave config;
config.SetFilename (filename);
config.Default ();
g_free (filename);
}
gtk_widget_destroy (dialog);
}
/**
* If the user presses the button load, it will load the config file into memory.
*/
void
load_clicked_default (GtkButton *button, gpointer user_data)
{
GtkWidget *parent_window = GTK_WIDGET (user_data);
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("Open File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN,
GTK_RESPONSE_ACCEPT, (char *) 0);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
RawTextConfigLoad config;
config.SetFilename (filename);
config.Default ();
}
gtk_widget_destroy (dialog);
}
/**
* This is the main view opening the widget, getting tooltips and drawing the
* tree of attributes
*/
GtkWidget *
create_view_config_default (GtkTreeStore *model)
{
GtkTreeViewColumn *col;
GtkCellRenderer *renderer;
GtkWidget *view;
view = gtk_tree_view_new ();
g_object_set (view, "has-tooltip", TRUE, (char*) 0);
g_signal_connect (view, "query-tooltip", (GCallback) cell_tooltip_callback_config_default, 0);
gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
col = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (col, "Object Attributes");
gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (col, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_0_config_default, 0, 0);
g_object_set (renderer, "editable", FALSE, (char*) 0);
col = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (col, "Attribute Value");
gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
renderer = gtk_cell_renderer_text_new ();
g_signal_connect (renderer, "edited", (GCallback) cell_edited_callback_config_default, model);
gtk_tree_view_column_pack_start (col, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_1_config_default, 0, 0);
gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (model));
g_object_unref (model); /* destroy model automatically with view */
return view;
}
/**
* Delete the tree model contents
*/
gboolean
clean_model_callback_config_default (GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter *iter, gpointer data)
{
ModelTypeid *node;
gtk_tree_model_get (GTK_TREE_MODEL (model), iter, COL_TYPEID, &node, -1);
delete node;
gtk_tree_store_set (GTK_TREE_STORE (model), iter, COL_TYPEID, (ModelTypeid*) 0, -1);
return FALSE;
}
}//end ns3 namespace

View File

@@ -0,0 +1,150 @@
/* -*- 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
*
* Authors: Faker Moatamri <faker.moatamri@sophia.inria.fr>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef DISPLAY_FUNCTIONS_H
#define DISPLAY_FUNCTIONS_H
#include "model-node-creator.h"
#include "model-typeid-creator.h"
#include <gtk/gtk.h>
namespace ns3 {
/**
* This function includes the name of the attribute or the editable value
* in the second column
*/
void
cell_data_function_col_1 (GtkTreeViewColumn *col, GtkCellRenderer *renderer,
GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data);
/**
* This function includes the name of the object, pointer, vector or vector item
* in the first column
*/
void
cell_data_function_col_0 (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model,
GtkTreeIter *iter, gpointer user_data);
/**
* This is the callback called when the value of an attribute is changed
*/
void
cell_edited_callback (GtkCellRendererText *cell, gchar *path_string,
gchar *new_text, gpointer user_data);
/**
* This function gets the column number 0 or 1 from the mouse
* click
*/
int
get_col_number_from_tree_view_column (GtkTreeViewColumn *col);
/**
* This function displays the tooltip for an object, pointer, vector
* item or an attribute
*/
gboolean
cell_tooltip_callback (GtkWidget *widget, gint x, gint y, gboolean keyboard_tip,
GtkTooltip *tooltip, gpointer user_data);
/**
* This is the main view opening the widget, getting tooltips and drawing the
* tree of attributes...
*/
GtkWidget *
create_view (GtkTreeStore *model);
/**
* This is the action done when the user presses on the save button.
* It will save the config to a file.
*/
void
save_clicked (GtkButton *button, gpointer user_data);
/**
* If the user presses the button load, it will load the config file into memory.
*/
void
load_clicked (GtkButton *button, gpointer user_data);
/**
* Exit the window when exit button is pressed
*/
void
exit_clicked_callback (GtkButton *button, gpointer user_data);
/**
* Exit the application
*/
gboolean
delete_event_callback (GtkWidget *widget, GdkEvent *event, gpointer user_data);
/**
* Delete the tree model contents
*/
gboolean
clean_model_callback (GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter *iter, gpointer data);
/************************** display functions used by default configurator **********************/
/**
* This function writes data in the second column, this data is going to be editable
* if it is a NODE_ATTRIBUTE
*/
void
cell_data_function_col_1_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer,
GtkTreeModel *model, GtkTreeIter *iter,
gpointer user_data);
/**
* This function writes the attribute or typeid name in the column 0
*/
void
cell_data_function_col_0_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model,
GtkTreeIter *iter, gpointer user_data);
/**
* This is the action done when the user presses on the save button.
* It will save the config to a file.
*/
void
save_clicked_default (GtkButton *button, gpointer user_data);
/**
* If the user presses the button load, it will load the config file into memory.
*/
void
load_clicked_default (GtkButton *button, gpointer user_data);
/**
* This functions is called whenever there is a change in the value of an attribute
* If the input value is ok, it will be updated in the default value and in the
* gui, otherwise, it won't be updated in both.
*/
void
cell_edited_callback_config_default (GtkCellRendererText *cell, gchar *path_string,
gchar *new_text, gpointer user_data);
/**
* This function is used to display a tooltip whenever the user puts the mouse
* over a type ID or an attribute. It will give the type and the possible values of
* an attribute value and the type of the object for an attribute object or a
* typeID object
*/
gboolean
cell_tooltip_callback_config_default (GtkWidget *widget, gint x, gint y,
gboolean keyboard_tip, GtkTooltip *tooltip, gpointer user_data);
/**
* This is the main view opening the widget, getting tooltips and drawing the
* tree of attributes
*/
GtkWidget *
create_view_config_default (GtkTreeStore *model);
/**
* Delete the tree model contents
*/
gboolean
clean_model_callback_config_default (GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter *iter, gpointer data);
}//end namespace ns3
#endif

View File

@@ -1,11 +1,26 @@
/* -*- 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
*
* Authors: Faker Moatamri <faker.moatamri@sophia.inria.fr>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "gtk-config-store.h"
#include "attribute-iterator.h"
#include "raw-text-config.h"
#include "ns3/config.h"
#include "ns3/string.h"
#include "ns3/pointer.h"
#include "display-functions.h"
#include "ns3/log.h"
#include <gtk/gtk.h>
#include <fstream>
@@ -13,474 +28,61 @@ namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("GtkconfigStore");
enum {
COL_NODE = 0,
COL_LAST
};
struct ModelNode
{
enum {
// store object + attribute name
NODE_ATTRIBUTE,
// store object + attribute name
NODE_POINTER,
// store object + attribute name
NODE_VECTOR,
// store index + value (object)
NODE_VECTOR_ITEM,
// store object
NODE_OBJECT
} type;
std::string name;
Ptr<Object> object;
uint32_t index;
};
class ModelCreator : public AttributeIterator
{
public:
ModelCreator ();
void Build (GtkTreeStore *treestore);
private:
virtual void DoVisitAttribute (Ptr<Object> object, std::string name);
virtual void DoStartVisitObject (Ptr<Object> object);
virtual void DoEndVisitObject (void);
virtual void DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value);
virtual void DoEndVisitPointerAttribute (void);
virtual void DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector);
virtual void DoEndVisitArrayAttribute (void);
virtual void DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item);
virtual void DoEndVisitArrayItem (void);
void Add (ModelNode *node);
void Remove (void);
GtkTreeStore *m_treestore;
std::vector<GtkTreeIter *> m_iters;
};
ModelCreator::ModelCreator ()
{}
void
ModelCreator::Build (GtkTreeStore *treestore)
{
m_treestore = treestore;
m_iters.push_back (0);
Iterate ();
NS_ASSERT (m_iters.size () == 1);
}
void
ModelCreator::Add (ModelNode *node)
{
GtkTreeIter *parent = m_iters.back ();
GtkTreeIter *current = g_new (GtkTreeIter, 1);
gtk_tree_store_append (m_treestore, current, parent);
gtk_tree_store_set (m_treestore, current,
COL_NODE, node,
-1);
m_iters.push_back (current);
}
void
ModelCreator::Remove (void)
{
GtkTreeIter *iter = m_iters.back ();
g_free (iter);
m_iters.pop_back ();
}
void
ModelCreator::DoVisitAttribute (Ptr<Object> object, std::string name)
{
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_ATTRIBUTE;
node->object = object;
node->name = name;
Add (node);
Remove ();
}
void
ModelCreator::DoStartVisitObject (Ptr<Object> object)
{
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_OBJECT;
node->object = object;
Add (node);
}
void
ModelCreator::DoEndVisitObject (void)
{
Remove ();
}
void
ModelCreator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value)
{
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_POINTER;
node->object = object;
node->name = name;
Add (node);
}
void
ModelCreator::DoEndVisitPointerAttribute (void)
{
Remove ();
}
void
ModelCreator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector)
{
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_VECTOR;
node->object = object;
node->name = name;
Add (node);
}
void
ModelCreator::DoEndVisitArrayAttribute (void)
{
Remove ();
}
void
ModelCreator::DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item)
{
GtkTreeIter *parent = m_iters.back ();
GtkTreeIter *current = g_new (GtkTreeIter, 1);
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_VECTOR_ITEM;
node->object = item;
node->index = index;
gtk_tree_store_append (m_treestore, current, parent);
gtk_tree_store_set (m_treestore, current,
COL_NODE, node,
-1);
m_iters.push_back (current);
}
void
ModelCreator::DoEndVisitArrayItem (void)
{
GtkTreeIter *iter = m_iters.back ();
g_free (iter);
m_iters.pop_back ();
}
static void
cell_data_function_col_1 (GtkTreeViewColumn *col,
GtkCellRenderer *renderer,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer user_data)
{
ModelNode *node;
gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
if (node->type == ModelNode::NODE_ATTRIBUTE)
{
StringValue str;
node->object->GetAttribute (node->name, str);
g_object_set(renderer, "text", str.Get ().c_str (), (char*)0);
g_object_set(renderer, "editable", TRUE, (char*)0);
}
else
{
g_object_set(renderer, "text", "", (char*)0);
g_object_set(renderer, "editable", FALSE, (char*)0);
}
}
static void
cell_data_function_col_0 (GtkTreeViewColumn *col,
GtkCellRenderer *renderer,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer user_data)
{
ModelNode *node;
gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
g_object_set (renderer, "editable", FALSE, (char*)0);
switch (node->type) {
case ModelNode::NODE_OBJECT:
g_object_set(renderer, "text", node->object->GetInstanceTypeId ().GetName ().c_str (), (char*)0);
break;
case ModelNode::NODE_POINTER:
g_object_set(renderer, "text", node->name.c_str (), (char*)0);
break;
case ModelNode::NODE_VECTOR:
g_object_set(renderer, "text", node->name.c_str (), (char*)0);
break;
case ModelNode::NODE_VECTOR_ITEM: {
std::stringstream oss;
oss << node->index;
g_object_set(renderer, "text", oss.str ().c_str (), (char*)0);
} break;
case ModelNode::NODE_ATTRIBUTE:
g_object_set(renderer, "text", node->name.c_str (), (char*)0);
break;
}
}
static void
cell_edited_callback (GtkCellRendererText *cell,
gchar *path_string,
gchar *new_text,
gpointer user_data)
{
GtkTreeModel *model = GTK_TREE_MODEL (user_data);
GtkTreeIter iter;
gtk_tree_model_get_iter_from_string (model, &iter, path_string);
ModelNode *node;
gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
NS_ASSERT (node->type == ModelNode::NODE_ATTRIBUTE);
node->object->SetAttribute (node->name, StringValue (new_text));
}
static int
get_col_number_from_tree_view_column (GtkTreeViewColumn *col)
{
GList *cols;
int num;
g_return_val_if_fail ( col != 0, -1 );
g_return_val_if_fail ( col->tree_view != 0, -1 );
cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(col->tree_view));
num = g_list_index(cols, (gpointer) col);
g_list_free(cols);
return num;
}
static gboolean
cell_tooltip_callback (GtkWidget *widget,
gint x,
gint y,
gboolean keyboard_tip,
GtkTooltip *tooltip,
gpointer user_data)
{
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeViewColumn * column;
if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget),
&x, &y, keyboard_tip,
&model, 0, &iter))
{
return FALSE;
}
if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
x, y, 0, &column, 0, 0))
{
return FALSE;
}
int col = get_col_number_from_tree_view_column (column);
ModelNode *node;
gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
switch (node->type) {
case ModelNode::NODE_OBJECT:
if (col == 0)
{
std::string tip = "This object is of type " + node->object->GetInstanceTypeId ().GetName ();
gtk_tooltip_set_text (tooltip, tip.c_str ());
return TRUE;
}
break;
case ModelNode::NODE_POINTER:
if (col == 0)
{
PointerValue ptr;
node->object->GetAttribute (node->name, ptr);
std::string tip = "This object is of type " + ptr.GetObject ()->GetInstanceTypeId ().GetName ();
gtk_tooltip_set_text (tooltip, tip.c_str ());
return TRUE;
}
break;
case ModelNode::NODE_VECTOR:
break;
case ModelNode::NODE_VECTOR_ITEM:
if (col == 0)
{
std::string tip = "This object is of type " + node->object->GetInstanceTypeId ().GetName ();
gtk_tooltip_set_text (tooltip, tip.c_str ());
return TRUE;
}
break;
case ModelNode::NODE_ATTRIBUTE: {
uint32_t attrIndex = 0;
TypeId tid;
for (tid = node->object->GetInstanceTypeId (); tid.HasParent (); tid = tid.GetParent ())
{
for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
{
if (tid.GetAttributeName (i) == node->name)
{
attrIndex = i;
goto out;
}
}
}
out:
if (col == 0)
{
std::string tip = tid.GetAttributeHelp (attrIndex);
gtk_tooltip_set_text (tooltip, tip.c_str ());
}
else
{
Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (attrIndex);
std::string tip;
tip = "This attribute is of type " + checker->GetValueTypeName ();
if (checker->HasUnderlyingTypeInformation ())
{
tip += " " + checker->GetUnderlyingTypeInformation ();
}
gtk_tooltip_set_text (tooltip, tip.c_str ());
}
return TRUE;
} break;
}
return FALSE;
}
static GtkWidget *
create_view (GtkTreeStore *model)
{
GtkTreeViewColumn *col;
GtkCellRenderer *renderer;
GtkWidget *view;
view = gtk_tree_view_new();
g_object_set (view, "has-tooltip", TRUE, (char*)0);
g_signal_connect (view, "query-tooltip", (GCallback) cell_tooltip_callback, 0);
gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
col = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col, "Object Attributes");
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start(col, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(col, renderer, cell_data_function_col_0, 0, 0);
g_object_set(renderer, "editable", FALSE, (char*)0);
col = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col, "Attribute Value");
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
renderer = gtk_cell_renderer_text_new();
g_signal_connect(renderer, "edited", (GCallback) cell_edited_callback, model);
gtk_tree_view_column_pack_start(col, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(col, renderer, cell_data_function_col_1, 0, 0);
gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL (model));
g_object_unref(model); /* destroy model automatically with view */
return view;
}
static void
save_clicked (GtkButton *button,
gpointer user_data)
{
GtkWidget *parent_window = GTK_WIDGET (user_data);
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("Save File",
GTK_WINDOW (parent_window),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
(char *)0);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "config.txt");
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
RawTextConfigSave config;
config.SetFilename (filename);
config.Attributes ();
g_free (filename);
}
gtk_widget_destroy (dialog);
}
static void
load_clicked (GtkButton *button,
gpointer user_data)
{
GtkWidget *parent_window = GTK_WIDGET (user_data);
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("Open File",
GTK_WINDOW (parent_window),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
(char *)0);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
RawTextConfigLoad config;
config.SetFilename (filename);
config.Attributes ();
}
gtk_widget_destroy (dialog);
}
static void
exit_clicked_callback (GtkButton *button,
gpointer user_data)
{
gtk_main_quit ();
gtk_widget_hide (GTK_WIDGET (user_data));
}
static gboolean
delete_event_callback (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
gtk_main_quit ();
gtk_widget_hide (GTK_WIDGET (user_data));
return TRUE;
}
static gboolean
clean_model_callback (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data)
{
ModelNode *node;
gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
COL_NODE, &node,
-1);
delete node;
gtk_tree_store_set (GTK_TREE_STORE (model), iter,
COL_NODE, (ModelNode*)0,
-1);
return FALSE;
}
GtkConfigStore::GtkConfigStore ()
{}
{
}
void
void
GtkConfigStore::ConfigureDefaults (void)
{}
{
//this function should be called before running the script to enable the user
//to configure the default values for the objects he wants to use
GtkWidget *window;
GtkWidget *view;
GtkWidget *scroll;
gtk_init (0, 0);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "ns-3 Default attributes.");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
g_signal_connect (window, "delete_event", (GCallback)delete_event_callback, window);
GtkTreeStore *model = gtk_tree_store_new (COL_LAST, G_TYPE_POINTER);
ModelTypeidCreator creator;
creator.Build (model);
view = create_view_config_default (model);
scroll = gtk_scrolled_window_new (0, 0);
gtk_container_add (GTK_CONTAINER (scroll), view);
GtkWidget *vbox = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 0);
GtkWidget *hbox = gtk_hbox_new (FALSE, 5);
gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
GtkWidget *save = gtk_button_new_with_label ("Save");
g_signal_connect (save, "clicked", (GCallback) save_clicked_default, window);
gtk_box_pack_end (GTK_BOX (hbox), save, FALSE, FALSE, 0);
GtkWidget *load = gtk_button_new_with_label ("Load");
g_signal_connect (load, "clicked", (GCallback) load_clicked_default, window);
gtk_box_pack_end (GTK_BOX (hbox), load, FALSE, FALSE, 0);
GtkWidget *exit = gtk_button_new_with_label ("Run Simulation");
g_signal_connect (exit, "clicked", (GCallback) exit_clicked_callback, window);
gtk_box_pack_end (GTK_BOX (hbox), exit, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show_all (window);
gtk_main ();
gtk_tree_model_foreach (GTK_TREE_MODEL (model),
clean_model_callback_config_default,
0);
gtk_widget_destroy (window);
}
void
GtkConfigStore::ConfigureAttributes (void)
@@ -494,7 +96,7 @@ GtkConfigStore::ConfigureAttributes (void)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "ns-3 Object attributes.");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
g_signal_connect (window, "delete_event", (GCallback)delete_event_callback, window);
@@ -528,8 +130,8 @@ GtkConfigStore::ConfigureAttributes (void)
gtk_main ();
gtk_tree_model_foreach (GTK_TREE_MODEL (model),
clean_model_callback,
0);
clean_model_callback,
0);
gtk_widget_destroy (window);
}

View File

@@ -1,3 +1,22 @@
/* -*- 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
*
* Authors: Faker Moatamri <faker.moatamri@sophia.inria.fr>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef GTK_CONFIG_STORE_H
#define GTK_CONFIG_STORE_H

View File

@@ -0,0 +1,130 @@
/* -*- 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
*
* Authors: Faker Moatamri <faker.moatamri@sophia.inria.fr>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "model-node-creator.h"
namespace ns3 {
ModelCreator::ModelCreator ()
{
}
void
ModelCreator::Build (GtkTreeStore *treestore)
{
m_treestore = treestore;
m_iters.push_back (0);
//this function will go through all the objects and call on them
//DoStartVisitObject, DoIterate and DoEndVisitObject
Iterate ();
NS_ASSERT (m_iters.size () == 1);
}
void
ModelCreator::Add (ModelNode *node)
{
GtkTreeIter *parent = m_iters.back ();
GtkTreeIter *current = g_new (GtkTreeIter, 1);
gtk_tree_store_append (m_treestore, current, parent);
gtk_tree_store_set (m_treestore, current,
COL_NODE, node, -1);
m_iters.push_back (current);
}
void
ModelCreator::Remove (void)
{
GtkTreeIter *iter = m_iters.back ();
g_free (iter);
m_iters.pop_back ();
}
void
ModelCreator::DoVisitAttribute (Ptr<Object> object, std::string name)
{
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_ATTRIBUTE;
node->object = object;
node->name = name;
Add (node);
Remove ();
}
void
ModelCreator::DoStartVisitObject (Ptr<Object> object)
{
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_OBJECT;
node->object = object;
Add (node);
}
void
ModelCreator::DoEndVisitObject (void)
{
Remove ();
}
void
ModelCreator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value)
{
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_POINTER;
node->object = object;
node->name = name;
Add (node);
}
void
ModelCreator::DoEndVisitPointerAttribute (void)
{
Remove ();
}
void
ModelCreator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector)
{
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_VECTOR;
node->object = object;
node->name = name;
Add (node);
}
void
ModelCreator::DoEndVisitArrayAttribute (void)
{
Remove ();
}
void
ModelCreator::DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item)
{
GtkTreeIter *parent = m_iters.back ();
GtkTreeIter *current = g_new (GtkTreeIter, 1);
ModelNode *node = new ModelNode ();
node->type = ModelNode::NODE_VECTOR_ITEM;
node->object = item;
node->index = index;
gtk_tree_store_append (m_treestore, current, parent);
gtk_tree_store_set (m_treestore, current,
COL_NODE, node,
-1);
m_iters.push_back (current);
}
void
ModelCreator::DoEndVisitArrayItem (void)
{
GtkTreeIter *iter = m_iters.back ();
g_free (iter);
m_iters.pop_back ();
}
}//end namespace ns3

View File

@@ -0,0 +1,73 @@
/* -*- 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
*
* Authors: Faker Moatamri <faker.moatamri@sophia.inria.fr>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "attribute-iterator.h"
#include <gtk/gtk.h>
namespace ns3
{
enum
{
COL_NODE = 0, COL_LAST
};
struct ModelNode
{
enum
{
// store object + attribute name
NODE_ATTRIBUTE,
// store object + attribute name
NODE_POINTER,
// store object + attribute name
NODE_VECTOR,
// store index + value (object)
NODE_VECTOR_ITEM,
// store object
NODE_OBJECT
} type;
std::string name;
Ptr<Object> object;
uint32_t index;
};
class ModelCreator : public AttributeIterator
{
public:
ModelCreator ();
void Build (GtkTreeStore *treestore);
private:
virtual void DoVisitAttribute (Ptr<Object> object, std::string name);
virtual void DoStartVisitObject (Ptr<Object> object);
virtual void DoEndVisitObject (void);
virtual void DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value);
virtual void DoEndVisitPointerAttribute (void);
virtual void DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector);
virtual void DoEndVisitArrayAttribute (void);
virtual void DoStartVisitArrayItem (const ObjectVectorValue &vector,
uint32_t index, Ptr<Object> item);
virtual void DoEndVisitArrayItem (void);
void Add (ModelNode *node);
void Remove (void);
GtkTreeStore *m_treestore;
std::vector<GtkTreeIter *> m_iters;
};
}

View File

@@ -0,0 +1,81 @@
/* -*- 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
*
* Author: Faker Moatamri <faker.moatamri@sophia.inria.fr>
*/
#include "model-typeid-creator.h"
namespace ns3 {
ModelTypeidCreator::ModelTypeidCreator ()
{
}
void
ModelTypeidCreator::Build (GtkTreeStore *treestore)
{
m_treestore = treestore;
m_iters.push_back (0);
Iterate ();
NS_ASSERT (m_iters.size () == 1);
}
void
ModelTypeidCreator::Add (ModelTypeid *node)
{
GtkTreeIter *parent = m_iters.back ();
GtkTreeIter *current = g_new (GtkTreeIter, 1);
gtk_tree_store_append (m_treestore, current, parent);
gtk_tree_store_set (m_treestore, current, COL_TYPEID, node, -1);
m_iters.push_back (current);
}
void
ModelTypeidCreator::Remove (void)
{
GtkTreeIter *iter = m_iters.back ();
g_free (iter);
m_iters.pop_back ();
}
void
ModelTypeidCreator::VisitAttribute (TypeId tid, std::string name, std::string defaultValue, uint32_t index)
{
ModelTypeid *node = new ModelTypeid ();
node->type = ModelTypeid::NODE_ATTRIBUTE;
node->tid = tid;
node->name = name;
node->defaultValue = defaultValue;
node->index = index;
Add (node);
Remove ();
}
void
ModelTypeidCreator::StartVisitTypeId (std::string name)
{
ModelTypeid *node = new ModelTypeid ();
node->type = ModelTypeid::NODE_TYPEID;
node->tid = TypeId::LookupByName (name);
Add (node);
}
void
ModelTypeidCreator::EndVisitTypeId (void)
{
Remove ();
}
}//end namespace ns3

View File

@@ -0,0 +1,82 @@
/* -*- 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
*
* Author: Moatamri Faker <faker.moatamri@sophia.inria.fr>
*/
#include "attribute-default-iterator.h"
#include "ns3/type-id.h"
#include <gtk/gtk.h>
#include <vector>
namespace ns3 {
enum
{
COL_TYPEID = 0, COL_LASTID
};
struct ModelTypeid
{
enum
{
// store TypeId + attribute name +defaultValue and index
NODE_ATTRIBUTE,
// store TypeId
NODE_TYPEID
} type;
std::string name;
std::string defaultValue;
//The TypeId object and if it is an attribute, it's the TypeId object of the attribute
TypeId tid;
//stores the index of the attribute in list of attributes for a given TypeId
uint32_t index;
};
class ModelTypeidCreator : public AttributeDefaultIterator
{
public:
ModelTypeidCreator ();
/**
* \brief This method will iterate on typeIds having default attributes and create a model
* for them, this model will be used by the view.
*/
void Build (GtkTreeStore *treestore);
private:
/**
* \brief This method will add a ModelTypeid to the GtkTreeIterator
*/
virtual void VisitAttribute (TypeId tid, std::string name, std::string defaultValue, uint32_t index);
/**
* \brief Add a node for the new TypeId object
*/
virtual void StartVisitTypeId (std::string name);
/**
* \brief Remove the last gtk tree iterator
*/
virtual void EndVisitTypeId (void);
/**
* \brief Adds a treestore iterator to m_treestore model
*/
void Add (ModelTypeid *node);
/**
* Removes the last GtkTreeIterator from m_iters
*/
void Remove (void);
//this is the TreeStore model corresponding to the view
GtkTreeStore *m_treestore;
//This contains a vector of iterators used to build the TreeStore
std::vector<GtkTreeIter *> m_iters;
};
}

View File

@@ -41,7 +41,7 @@ RawTextConfigSave::Default (void)
virtual void StartVisitTypeId (std::string name) {
m_typeId = name;
}
virtual void VisitAttribute (std::string name, std::string defaultValue) {
virtual void DoVisitAttribute (std::string name, std::string defaultValue) {
*m_os << "default " << m_typeId << "::" << name << " \"" << defaultValue << "\"" << std::endl;
}
std::string m_typeId;

View File

@@ -47,7 +47,11 @@ def build(bld):
if bld.env['ENABLE_GTK_CONFIG_STORE']:
headers.source.append ('gtk-config-store.h')
module.source.append ('gtk-config-store.cc')
module.source.extend (['gtk-config-store.cc',
'model-node-creator.cc',
'model-typeid-creator.cc',
'display-functions.cc',
])
module.uselib = 'GTK_CONFIG_STORE'
if bld.env['ENABLE_LIBXML2']:

View File

@@ -90,7 +90,7 @@ XmlConfigSave::Default (void)
virtual void StartVisitTypeId (std::string name) {
m_typeid = name;
}
virtual void VisitAttribute (std::string name, std::string defaultValue) {
virtual void DoVisitAttribute (std::string name, std::string defaultValue) {
int rc;
rc = xmlTextWriterStartElement(m_writer, BAD_CAST "default");
if (rc < 0)

View File

@@ -272,6 +272,14 @@ EmuNetDevice::StartDevice (void)
Ptr<RealtimeSimulatorImpl> impl = DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ());
m_rtImpl = GetPointer (impl);
//
// A similar story exists for the node ID. We can't just naively do a
// GetNode ()->GetId () since GetNode is going to give us a Ptr<Node> which
// is reference counted. We need to stash away the node ID for use in the
// read thread.
//
m_nodeId = GetNode ()->GetId ();
NS_LOG_LOGIC ("Creating socket");
//
@@ -757,10 +765,10 @@ EmuNetDevice::ReadThread (void)
return;
}
NS_LOG_INFO ("EmuNetDevice::ReadThread(): Received packet");
NS_LOG_INFO ("EmuNetDevice::EmuNetDevice(): Received packet on node " << m_nodeId);
NS_LOG_INFO ("EmuNetDevice::ReadThread(): Scheduling handler");
NS_ASSERT_MSG (m_rtImpl, "EmuNetDevice::ReadThread(): Realtime simulator implementation pointer not set");
m_rtImpl->ScheduleRealtimeNowWithContext (GetNode ()->GetId (), MakeEvent (&EmuNetDevice::ForwardUp, this, buf, len));
m_rtImpl->ScheduleRealtimeNowWithContext (m_nodeId, MakeEvent (&EmuNetDevice::ForwardUp, this, buf, len));
buf = 0;
}
}

View File

@@ -513,6 +513,13 @@ private:
* Never free this pointer!
*/
RealtimeSimulatorImpl *m_rtImpl;
/*
* a copy of the node id so the read thread doesn't have to GetNode() in
* in order to find the node ID. Thread unsafe reference counting in
* multithreaded apps is not a good thing.
*/
uint32_t m_nodeId;
};
} // namespace ns3

View File

@@ -205,6 +205,14 @@ TapBridge::StartTapDevice (void)
Ptr<RealtimeSimulatorImpl> impl = DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ());
m_rtImpl = GetPointer (impl);
//
// A similar story exists for the node ID. We can't just naively do a
// GetNode ()->GetId () since GetNode is going to give us a Ptr<Node> which
// is reference counted. We need to stash away the node ID for use in the
// read thread.
//
m_nodeId = GetNode ()->GetId ();
//
// Spin up the tap bridge and start receiving packets.
//
@@ -648,11 +656,10 @@ TapBridge::ReadThread (void)
return;
}
NS_LOG_INFO ("TapBridge::ReadThread(): Received packet on node " << m_node->GetId ());
NS_LOG_INFO ("TapBridge::ReadThread(): Received packet on node " << m_nodeId);
NS_LOG_INFO ("TapBridge::ReadThread(): Scheduling handler");
NS_ASSERT_MSG (m_rtImpl, "EmuNetDevice::ReadThread(): Realtime simulator implementation pointer not set");
m_rtImpl->ScheduleRealtimeNowWithContext (GetNode ()->GetId (),
MakeEvent (&TapBridge::ForwardToBridgedDevice, this, buf, len));
m_rtImpl->ScheduleRealtimeNowWithContext (m_nodeId, MakeEvent (&TapBridge::ForwardToBridgedDevice, this, buf, len));
buf = 0;
}
}

View File

@@ -457,6 +457,13 @@ private:
* Never free this pointer!
*/
RealtimeSimulatorImpl *m_rtImpl;
/*
* a copy of the node id so the read thread doesn't have to GetNode() in
* in order to find the node ID. Thread unsafe reference counting in
* multithreaded apps is not a good thing.
*/
uint32_t m_nodeId;
};
} // namespace ns3

View File

@@ -109,6 +109,7 @@ public:
/**
* \param packet Packet to store.
* \param hdr 802.11 header for packet.
* \param tStamp time stamp for packet
*
* Stores <i>packet</i> for a possible future retransmission. Retransmission occurs
* if the packet, in a block ack frame, is indicated by recipient as not received.
@@ -156,6 +157,7 @@ public:
/**
* \param recipient Address of peer station involved in block ack mechanism.
* \param tid Traffic ID of transmitted packet.
* \param startingSeq starting sequence field
*
* Puts corresponding agreement in established state and updates number of packets
* and starting sequence field. Invoked typically after a block ack refresh.
@@ -205,7 +207,8 @@ public:
*/
void TearDownBlockAck (Mac48Address recipient, uint8_t tid);
/**
* \param Sequence number of the packet which fragment is part of.
* \param sequenceNumber Sequence number of the packet which fragment is
* part of.
*
* Returns true if another fragment with sequence number <i>sequenceNumber</i> is scheduled
* for retransmission.

View File

@@ -37,7 +37,7 @@
NS_LOG_COMPONENT_DEFINE ("DcaTxop");
#undef NS_LOG_APPEND_CONTEXT
#define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_low->GetAddress () << "] ";
#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
namespace ns3 {

View File

@@ -38,7 +38,7 @@
NS_LOG_COMPONENT_DEFINE ("EdcaTxopN");
#undef NS_LOG_APPEND_CONTEXT
#define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_low->GetAddress () << "] ";
#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
namespace ns3 {

View File

@@ -32,7 +32,7 @@ public:
MsduStandardAggregator ();
~MsduStandardAggregator ();
/**
* \param packet Packet we have to insert into </i>aggregatedPacket</i>.
* \param packet Packet we have to insert into <i>aggregatedPacket</i>.
* \param aggregatedPacket Packet that will contain <i>packet</i>, if aggregation is possible,
* \param src Source address of <i>packet</i>.
* \param dest Destination address of <i>packet</i>.

View File

@@ -137,7 +137,7 @@ public:
* \param lrx lower right x value
* \param lry lower right y value
*/
void BoundingBox (double, double, double, double);
void BoundingBox (double ulx, double uly, double lrx, double lry);
private:
NodeContainer m_leftLeaf;

View File

@@ -90,6 +90,7 @@ public:
* \param daddr The destination Ipv4Address
* \param sport The source port number
* \param dport The destination port number
* \param oif The output interface bound. Defaults to null (unspecified).
*/
void Send (Ptr<Packet> packet,
Ipv4Address saddr, Ipv4Address daddr,

View File

@@ -35,8 +35,8 @@ class Waypoint
{
public:
/**
* \param _time time of waypoint.
* \param _position position of waypoint corresponding to the given time.
* \param waypointTime time of waypoint.
* \param waypointPosition position of waypoint corresponding to the given time.
*
* Create a waypoint.
*/

View File

@@ -67,7 +67,7 @@ public:
/**
* \brief Specify application start time
* \param startTime Start time for this application,
* \param start Start time for this application,
* relative to the current simulation time.
*
* Applications start at various times in the simulation scenario.
@@ -80,7 +80,7 @@ public:
/**
* \brief Specify application stop time
* \param stopTime Stop time for this application, relative to the
* \param stop Stop time for this application, relative to the
* current simulation time.
*
* Once an application has started, it is sometimes useful

View File

@@ -529,7 +529,7 @@ public:
* is also possible to bind to mismatching device and address, even if
* the socket can not receive any packets as a result.
*
* \param Netdevice Pointer to Netdevice of desired interface
* \param netdevice Pointer to Netdevice of desired interface
* \returns nothing
*/
virtual void BindToNetDevice (Ptr<NetDevice> netdevice);

View File

@@ -39,10 +39,19 @@ TypeHeader::TypeHeader (MessageType t) :
{
}
TypeId
TypeHeader::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::aodv::TypeHeader")
.SetParent<Header> ()
;
return tid;
}
TypeId
TypeHeader::GetInstanceTypeId () const
{
return TypeId ();
return GetTypeId ();
}
uint32_t
@@ -134,10 +143,20 @@ RreqHeader::RreqHeader (uint8_t flags, uint8_t reserved, uint8_t hopCount, uint3
{
}
TypeId
RreqHeader::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::aodv::RreqHeader")
.SetParent<Header> ()
.AddConstructor<RreqHeader> ()
;
return tid;
}
TypeId
RreqHeader::GetInstanceTypeId () const
{
return TypeId ();
return GetTypeId ();
}
uint32_t
@@ -261,10 +280,20 @@ RrepHeader::RrepHeader (uint8_t prefixSize, uint8_t hopCount, Ipv4Address dst,
m_lifeTime = uint32_t (lifeTime.GetMilliSeconds ());
}
TypeId
RrepHeader::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::aodv::RrepHeader")
.SetParent<Header> ()
.AddConstructor<RrepHeader> ()
;
return tid;
}
TypeId
RrepHeader::GetInstanceTypeId () const
{
return TypeId ();
return GetTypeId ();
}
uint32_t
@@ -392,10 +421,20 @@ RrepAckHeader::RrepAckHeader () :
{
}
TypeId
RrepAckHeader::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::aodv::RrepAckHeader")
.SetParent<Header> ()
.AddConstructor<RrepAckHeader> ()
;
return tid;
}
TypeId
RrepAckHeader::GetInstanceTypeId () const
{
return TypeId ();
return GetTypeId ();
}
uint32_t
@@ -446,10 +485,20 @@ RerrHeader::RerrHeader () :
{
}
TypeId
RerrHeader::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::aodv::RerrHeader")
.SetParent<Header> ()
.AddConstructor<RerrHeader> ()
;
return tid;
}
TypeId
RerrHeader::GetInstanceTypeId () const
{
return TypeId ();
return GetTypeId ();
}
uint32_t

View File

@@ -58,6 +58,7 @@ public:
///\name Header serialization/deserialization
//\{
static TypeId GetTypeId ();
TypeId GetInstanceTypeId () const;
uint32_t GetSerializedSize () const;
void Serialize (Buffer::Iterator start) const;
@@ -109,6 +110,7 @@ public:
///\name Header serialization/deserialization
//\{
static TypeId GetTypeId ();
TypeId GetInstanceTypeId () const;
uint32_t GetSerializedSize () const;
void Serialize (Buffer::Iterator start) const;
@@ -184,6 +186,7 @@ public:
Ipv4Address (), Time lifetime = MilliSeconds (0));
///\name Header serialization/deserialization
//\{
static TypeId GetTypeId ();
TypeId GetInstanceTypeId () const;
uint32_t GetSerializedSize () const;
void Serialize (Buffer::Iterator start) const;
@@ -248,6 +251,7 @@ public:
///\name Header serialization/deserialization
//\{
static TypeId GetTypeId ();
TypeId GetInstanceTypeId () const;
uint32_t GetSerializedSize () const;
void Serialize (Buffer::Iterator start) const;
@@ -289,6 +293,7 @@ public:
///\name Header serialization/deserialization
//\{
static TypeId GetTypeId ();
TypeId GetInstanceTypeId () const;
uint32_t GetSerializedSize () const;
void Serialize (Buffer::Iterator i) const;

View File

@@ -53,7 +53,7 @@ class Ipv4NixVectorRouting : public Ipv4RoutingProtocol
*
* @param node Node pointer
*/
void SetNode (Ptr<Node>);
void SetNode (Ptr<Node> node);
/**
* @brief Called when run-time link topology change occurs

View File

@@ -336,7 +336,6 @@ Simulator::GetMaximumSimulationTime (void)
uint32_t
Simulator::GetContext (void)
{
NS_LOG_FUNCTION_NOARGS ();
return GetImpl ()->GetContext ();
}

View File

@@ -85,13 +85,14 @@ def configure(conf):
def create_ns3_module(bld, name, dependencies=()):
module = bld.new_task_gen('cxx')
module = bld.new_task_gen('cxx', 'cc')
module.name = 'ns3-' + name
module.target = module.name
module.add_objects = ['ns3-' + dep for dep in dependencies]
module.module_deps = list(dependencies)
if not module.env['ENABLE_STATIC_NS3']:
module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
module.env.append_value('CCFLAGS', module.env['shlib_CXXFLAGS'])
elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \
os.uname()[4] == 'x86_64' and \
module.env['ENABLE_PYTHON_BINDINGS']:
@@ -99,8 +100,10 @@ def create_ns3_module(bld, name, dependencies=()):
# when gcc is present and only when we want python bindings
# (it's more efficient to not use this option if we can avoid it)
module.env.append_value('CXXFLAGS', '-mcmodel=large')
module.env.append_value('CCFLAGS', '-mcmodel=large')
module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION")
module.env.append_value('CCDEFINES', "NS3_MODULE_COMPILATION")
return module
def create_obj(bld, *args):

BIN
waf vendored

Binary file not shown.

View File

@@ -31,6 +31,17 @@ if sys.platform == 'win32':
else:
dev_null = open("/dev/null", "w")
fcntl = fd = fl = None
try:
import fcntl
except ImportError:
pass
else:
fd = dev_null.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFD)
fcntl.fcntl(fd, fcntl.F_SETFD, fl | fcntl.FD_CLOEXEC)
del fcntl, fd, fl
def _open_out_file(filename):
if filename in ['NUL:', '/dev/null']:
return dev_null

View File

@@ -112,6 +112,7 @@ def dist_hook():
def set_options(opt):
# options provided by the modules
opt.tool_options('compiler_cc')
opt.tool_options('compiler_cxx')
opt.tool_options('cflags')
@@ -236,6 +237,7 @@ def configure(conf):
conf.env['NS3_OPTIONAL_FEATURES'] = []
conf.env['NS3_BUILDDIR'] = conf.blddir
conf.check_tool('compiler_cc')
conf.check_tool('compiler_cxx')
conf.check_tool('cflags')
try:
@@ -277,8 +279,6 @@ def configure(conf):
conf.setenv(variant_name)
env = variant_env
env.append_value('CXXDEFINES', 'RUN_SELF_TESTS')
if env['COMPILER_CXX'] == 'g++' and 'CXXFLAGS' not in os.environ:
if conf.check_compilation_flag('-Wno-error=deprecated-declarations'):
env.append_value('CXXFLAGS', '-Wno-error=deprecated-declarations')
@@ -388,6 +388,10 @@ def configure(conf):
conf.env.append_value('CXXDEFINES', "ENABLE_GSL")
conf.env.append_value('CCDEFINES', "ENABLE_GSL")
# for compiling C code, copy over the CXX* flags
conf.env.append_value('CCFLAGS', conf.env['CXXFLAGS'])
conf.env.append_value('CCDEFINES', conf.env['CXXDEFINES'])
# append user defined flags after all our ones
for (confvar, envvar) in [['CCFLAGS', 'CCFLAGS_EXTRA'],
['CXXFLAGS', 'CXXFLAGS_EXTRA'],