Custom Nodes and Multiple Wifi Networks

488 views
Skip to first unread message

Tim Tolbert

unread,
Jun 30, 2016, 1:06:45 AM6/30/16
to ns-3-users
Hello all,

I'm currently undertaking a research project and one of my first tasks is to create a visualization of a working ontological model.

I would like to make custom nodes to represent not just devices, but also specific apps on those devices as well as the people that are using said devices.

I'm also trying to show multiple separate WiFi / computer networks in one simulation and see how a node might communicate between them.  Example:  Alice is in one network location and Bob is in a separate network location but there's still correspondence between them in the form of location tracking or basic data communication.  Ideally I would like to have Alice as a node, who has a cellular device (another node), which uses specific applications (another/more node(s)) that are connecting to Bob in his separately located network.  PointToPoint nodes alone don't quite seem able to cut it.

Specifically, my questions are:  how would I create custom nodes to adequately represent all of these entities at play further than just their individual IP/MAC addresses?  Can I give my nodes custom names (like Alice and Bob, or Alice's Phone, etc.)  And how would I represent multiple separate networks that have nodes that periodically communicate with one or more nodes from other networks in the simulation?

Hints or pointers to specific documentation (as it is quite lengthy) that might be relevant would be extremely helpful.  I have also made an attempt at creating a simple multiple network visualization based on the original wifi-olsr-flowmon.py script included in the examples, but I'm having an issue I wouldn't expect.  I'll post that in a follow up reply to this post.

Tim Tolbert

unread,
Jun 30, 2016, 1:26:01 AM6/30/16
to ns-3-users
Starting from wifi-olsr-flowmon.py, I changed NUM_NODES_SIDE = 2 and DISTANCE = 75.  From there I wanted to create 2 networks of 4 nodes each, which I tried to do as follows:

    for xi in range(num_nodes_side):
       
for yi in range(num_nodes_side):


            node
= ns.network.Node()
            work_nodes
.append(node)


            internet
.Install(ns.network.NodeContainer(node))


            mobility
= ns.mobility.ConstantPositionMobilityModel()
            mobility
.SetPosition(ns.core.Vector(xi*DISTANCE, yi*DISTANCE, 0))
            node
.AggregateObject(mobility)


            devices
= wifi.Install(wifiPhy, wifiMac, node)
            ipv4_interfaces
= ipv4Addresses.Assign(devices)
            work_addresses
.append(ipv4_interfaces.GetAddress(0))


   
for i, node in enumerate(work_nodes):
        destaddr
= work_addresses[(len(work_addresses) - 1 - i) % len(work_addresses)]
       
#print i, destaddr
        onOffHelper
.SetAttribute("Remote", ns.network.AddressValue(ns.network.InetSocketAddress(destaddr, port)))
        app
= onOffHelper.Install(ns.network.NodeContainer(node))
        urv
= ns.core.UniformRandomVariable()
        app
.Start(ns.core.Seconds(urv.GetValue(20, 30)))


   
for xii in range(num_nodes_side):
       
for yii in range(num_nodes_side):


           
#create node
            node
= ns.network.Node()
           
#append node to home_nodes array
            home_nodes
.append(node)


           
#"install" internet protocols on node
            internet
.Install(ns.network.NodeContainer(node))


           
#set node positions
            mobility
= ns.mobility.ConstantPositionMobilityModel()
            mobility
.SetPosition(ns.core.Vector(xii*DISTANCE+150, yii*DISTANCE, 0))
            node
.AggregrateObject(mobility)


            devices
= wifi.Install(wifiPhy, wifiMac, node)
            ipv4_interfaces
= ipv4Addresses.Assign(devices)
            home_addresses
.append(ipv4_interfaces.GetAddress(0))


   
for i, node in enumerate(home_nodes):
        destaddr
= home_addresses[(len(home_addresses) - 1 - i) % len(home_addresses)]
       
#print i, destaddr
        onOffHelper
.SetAttribute("Remote", ns.network.AddressValue(ns.network.InetSocketAddress(destaddr, port)))
        app
= onOffHelper.Install(ns.network.NodeContainer(node))
        urv
= ns.core.UniformRandomVariable()
        app
.Start(ns.core.Seconds(urv.GetValue(20, 30)))

But when the compiler comes to the second node.AggregateObject line for home_nodes, I get an error saying AttributeError: 'network.Node' object has no attribute 'AggregrateObject'.  Yet, this works just fine for my first network's work_nodes.  Not sure what I'm missing.  I was just trying to create two identical, separate networks that communicated among themselves for starters.  Why can't I do it like this?

Thanks in advance for any assistance you can provide. 

pdbarnes

unread,
Jun 30, 2016, 8:58:39 AM6/30/16
to ns-3-users
It sounds like you're thinking in terms of a graph. Since "node" has a very specific meaning in ns-3 I suggest you use "vertex" for the graph notion.

While network nodes and the applications running on them are already represented explicitly in ns-3, there isn't a notion of a person or user. This would be useful to capture the notion of one user manipulating multiple devices, such as a computer and a phone. (Two-factor authentication, anyone?). I think I would just create my own Agent class derived from Object and put the smarts there.

As for naming, look at the Names interface:
https://www.nsnam.org/docs/release/3.25/doxygen/classns3_1_1_names.html

Peter

Tim Tolbert

unread,
Jun 30, 2016, 4:55:04 PM6/30/16
to ns-3-users
Thank you for your reply, Peter.  

I'm trying to create a real-time simulation (via ns3's visualizer and the --viz command).  Can I actually do that from the perspective of a "graph"?  I was under the assumption that in order to visualize the data transfer between devices that they would have to be created as nodes with the proper internet protocols in order to demonstrate that exchange of information with the visualizer.  Please correct me if I'm wrong.  I'm still pretty new to working with ns3, and I'm far from being the world's greatest coder.

As to Object, network nodes, and applications:  Are you referring to the modules ns3::Object, ns3::NetDevice, and ns3::Applications respectively?  And with my visualizer goals in mind, would you recommend just deriving a class from Object or would it be more advantageous to create another module to represent an Agent / User?  Obviously you couldn't install protocols on a human, but there must be some way to demonstrate Alice or Bob's physical state as detected by whatever intermediary mobile / network device.  This last part isn't important right now, but it is something that I will eventually need to expand to for the purposes of my project. 

Thank you for pointing me to Names, that definitely answered that particular question.

Tim

pdbarnes

unread,
Jun 30, 2016, 7:44:46 PM6/30/16
to ns-3-users
On Thursday, June 30, 2016 at 1:55:04 PM UTC-7, Tim Tolbert wrote:
I'm trying to create a real-time simulation (via ns3's visualizer and the --viz command).  Can I actually do that from the perspective of a "graph"?  I was under the assumption that in order to visualize the data transfer between devices that they would have to be created as nodes with the proper internet protocols in order to demonstrate that exchange of information with the visualizer.  

That is correct; the visualizations are expecting network communication.  If you create an overlay graph, possibly including objects which are not ns3::Nodes, the vizualizations won't know what to do (but keep reading).
 
As to Object, network nodes, and applications:  Are you referring to the modules ns3::Object, ns3::NetDevice, and ns3::Applications respectively?  

Almost:  ns3::Object, ns3::Node, and ns3::Application.
 
And with my visualizer goals in mind, would you recommend just deriving a class from Object or would it be more advantageous to create another module to represent an Agent / User?  

ns3::Object brings lots of useful functionality (Attributes for configuration being the big one), so one approach would create new classes derived from ns3::Object.
 
Obviously you couldn't install protocols on a human, but there must be some way to demonstrate Alice or Bob's physical state as detected by whatever intermediary mobile / network device.  

Visualizing an abstract agent's interaction with network nodes would be a challenge.  That being said, you could represent your people as network nodes, with point-to-point links (say) to the "real" network devices they control.  That would give you visualization of the agents and their actions (packets) controlling the "real" nodes.  IIRC one of the visualizers (was it NetAnim?) can support custom icons for specific nodes, so that would help distinguish the people from the real devices.


Thank you for pointing me to Names, that definitely answered that particular question.

You are welcome,
Peter

Tim Tolbert

unread,
Jul 14, 2016, 5:55:18 PM7/14/16
to ns-3-...@googlegroups.com
Hello again,

Ok, so I have been working a bit on this lately based on your advice and right now I'm just trying to create a very basic, point-to-point node simulation to get me started in the right direction.  Right now I just want two custom users (derived from Node) as an exercise with making a custom node class and event scheduling.  

That being said, I've created two new classes:  Entity (inheriting from node) and User (inheriting from Entity).  

class Entity : public Node {...}
class User : public Entity {...}

...and then attempted to add nodes to the container using:

NodeContainer::Add(Ptr< User > alice);
NodeContainer::Add(Ptr< User > bob);


Each of these has it's own custom attributes, and setters for each attribute.  Working to modify the "first.cc" script included in the tutorial and including these new classes, I have tried to compile and run into a whole slew of errors.  None of which are exactly verbose:

Build failed
 -> task in 'myfirstcustom' failed (exit status 1): 
{task 139986151936528: cxx myfirstcustom.cc -> myfirstcustom.cc.8.o}

Am I approaching this the wrong way?  Should I not derive classes from Node?  I chose to go Node over Object because I figured it would be the best way to get closer to the simple simulation of packet exchange I'm trying to achieve.

Also, I'm trying to create a timestamp (one of the custom attributes of Entity) based on the time in the simulation.  What I did to do this was set int time = Time::NS; would this be the correct approach?  And would setting these attributes automatically display them in the simulation when I hover over the Node or are there extra steps I need to take to accomplish that?  

Sorry for all the newbie questions.  I really just need help with this basic stuff to give me a basic idea to build off of and I'm a tad overwhelmed here.  Guidance would be greatly appreciated.

Tim  

--
Posting to this group should follow these guidelines https://www.nsnam.org/wiki/Ns-3-users-guidelines-for-posting
---
You received this message because you are subscribed to a topic in the Google Groups "ns-3-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ns-3-users/lUtywF0qFQQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ns-3-users+...@googlegroups.com.
To post to this group, send email to ns-3-...@googlegroups.com.
Visit this group at https://groups.google.com/group/ns-3-users.
For more options, visit https://groups.google.com/d/optout.

Tommaso Pecorella

unread,
Jul 15, 2016, 6:17:41 AM7/15/16
to ns-3-users
Hi,

no idea what's wrong, but the error is (often) easy to read ... if you know where to look.
Take the statement:
Build failed
 -> task in 'myfirstcustom' failed (exit status 1): 
{task 139986151936528: cxx myfirstcustom.cc -> myfirstcustom.cc.8.o}

The error description is far above this line. This is just the last one stating (more or less) "... and I couldn't go further in the compilation". You need to look above to understand where the problem is.
Moreover, always look at the very first error (or warning), the others can be just a consequence of the first one.
E.g., "couldn't find this header" will raise a LOT of other errors, but all will be fixed when you fix the missing header.

Hope this helps,

T.

Tim Tolbert

unread,
Jul 21, 2016, 3:38:20 AM7/21/16
to ns-3-...@googlegroups.com
Alright so I followed the bread crumb trail of errors to a laundry list of new errors, many of which I was able to fix myself but I've still got a couple that I'm not quite sure what to do about.

One is in my default constructor where I try to add a timestamp as an attribute of Entity:

../../scratch/myfirstcustom.cc: In constructor ‘Entity::Entity()’:
../../scratch/myfirstcustom.cc:56:18: error: invalid use of non-static member function ‘double ns3::Time::GetSeconds() const’
     time = Time::GetSeconds;

And the others are where I'm trying to instantiate alice and bob Users in the main method:
 
../../scratch/myfirstcustom.cc: In function ‘int main(int, char**)’:
../../scratch/myfirstcustom.cc:116:25: error: conversion from ‘User*’ to non-scalar type ‘User’ requested
   User alice = new User(); 

../../scratch/myfirstcustom.cc:118:34: error: expected primary-expression before ‘alice’
   NodeContainer::Add(Ptr< User > alice);

And then I'm getting a whole host of other issues trying to install the nodes and the container, which I'm assuming is because I'm not instantiating them properly.  What exactly am I doing wrong?  I'm hoping it will be something obvious to someone with a bit more experience and fresh eyes.  What would be the proper way to have a dynamic timestamp as an attribute and to instantiate my User nodes?  My User class inherits from Entity, which inherits from Node.

Tim

Tim Tolbert

unread,
Jul 21, 2016, 3:37:03 PM7/21/16
to ns-3-users
I will create a fresh thread with a more relevant subject line.  Thanks for all your help up to this point Tommaso and pdbarnes.

Tommaso Pecorella

unread,
Jul 21, 2016, 4:10:26 PM7/21/16
to ns-3-users
Hints are in-line.


On Thursday, July 21, 2016 at 9:37:03 PM UTC+2, Tim Tolbert wrote:
I will create a fresh thread with a more relevant subject line.  Thanks for all your help up to this point Tommaso and pdbarnes.

On Thursday, July 21, 2016 at 3:38:20 AM UTC-4, Tim Tolbert wrote:
Alright so I followed the bread crumb trail of errors to a laundry list of new errors, many of which I was able to fix myself but I've still got a couple that I'm not quite sure what to do about.

One is in my default constructor where I try to add a timestamp as an attribute of Entity:

../../scratch/myfirstcustom.cc: In constructor ‘Entity::Entity()’:
../../scratch/myfirstcustom.cc:56:18: error: invalid use of non-static member function ‘double ns3::Time::GetSeconds() const’
     time = Time::GetSeconds;

GetSecond is not a class (static) function, it's a member function. You need a Time instance to use it.
 
And the others are where I'm trying to instantiate alice and bob Users in the main method:
 
../../scratch/myfirstcustom.cc: In function ‘int main(int, char**)’:
../../scratch/myfirstcustom.cc:116:25: error: conversion from ‘User*’ to non-scalar type ‘User’ requested
   User alice = new User(); 

You don't use New to instantiate a variable. In any case you don't use New in ns-3 you use other functions. Check the tutorial.
 
../../scratch/myfirstcustom.cc:118:34: error: expected primary-expression before ‘alice’
   NodeContainer::Add(Ptr< User > alice);

Err... what ?
"alice" is a Node, you can not convert a Node into a Ptr<Node>, that's... no ?

I don't want to be rude, but I'd strongly suggest to read the tutorial again with a good C++ primer at your side. Every time you don't understand something, find it in the manuals.

Cheers,

T.

Tim Tolbert

unread,
Jul 21, 2016, 5:23:38 PM7/21/16
to ns-3-...@googlegroups.com

Hello,

I appreciate your response.  I'm trying to figure out how to apply your hints to my code.  What do you mean by me needing a time instance?  I'm trying to create a dynamic time stamp as an attribute (in my Entity class).  Is it possible to do that in a default constructor?  So far I haven't found an example in the tutorials that would help me accomplish that task, so I'm kind of shooting in the dark.

As far as my "alice" node, I have it instantiated as a User (User alice;), which inherits from Entity(my two custom classes).  Entity inherits from Node.  I'm unable to Add to the NodeContainer using Add(Ptr <Node> alice) or by using just the name with Add(alice).

My custom classes are set up as:

class Entity : public Node {...}

and


class User : public Entity {...}

Shouldn't it be treated as a node since it inherits directly from it?  Or do I need to approach it differently?

Any extra resources you could point me to or tips you could give would be highly appreciated.  I do actually have a c++ tutorial open on some of my tabs as well, as I'm still learning the finer points of c++   with this project. I'll go back to the tutorials in the meantime and see if I can figure it out on my own.  Thanks again.

Tim

Tommaso Pecorella

unread,
Jul 21, 2016, 6:11:08 PM7/21/16
to ns-3-users
Hi,

please triple check that you have understood what is explained here: https://www.nsnam.org/docs/manual/html/object-model.html
If the concept of "pointer" is not clear to you, please search for a specific tutorial in Internet, you'll find a lot of them.

Cheers,

T.
Reply all
Reply to author
Forward
0 new messages