Synchronize Nodes in ns-3

398 views
Skip to first unread message

Peshal Nayak

unread,
May 18, 2015, 6:24:08 PM5/18/15
to ns-3-...@googlegroups.com
I'm trying to simulate the following:

I have four nodes, say A, B, C, D talking to E, F, G, H over point to point links. A, B, C, D could be receiving open loop or closed loop traffic but whether its open or closed its the same for all the four nodes. I want to design a mechanism by which A, B, C, D transmit packets at the exact same time to their corresponding receivers and this has to be true for every single packet that they receive. They won't be receiving the packets at the exact same time, but they would buffer the packets and then transmit when all four of them have a packet. Does any one have any suggestions or ideas for this? I'm not familiar with the source code of ns-3 and so I don't have a starting point.

Thank you.

Best,
Peshal

pdbarnes

unread,
May 18, 2015, 8:39:20 PM5/18/15
to ns-3-...@googlegroups.com
So you have four parallel networks:
-> A -- p2p --> E
-> B -- p2p --> F
-> C -- p2p --> G
-> D -- p2p --> H

You want to synchronize packet sends from A-D.

How would you do this in a real network? You'd probably need some communication between then, and a synchronization protocol. You'd have to consider the amount of jitter you can tolerate. Network sync and standard OS will only get you so far.
Once you've designed your system, then tackle implementing it in ns-3.
P

Peshal Nayak

unread,
May 21, 2015, 2:28:50 PM5/21/15
to ns-3-...@googlegroups.com
Assuming the hardware was ready, what modules in ns-3 would need to be modified?

pdbarnes

unread,
May 22, 2015, 1:18:22 AM5/22/15
to ns-3-...@googlegroups.com
What? You haven't stated how you would do it in real life, so how can anyone figure out how to do it in a simulation? If you've got a hardware solution in mind, please describe it, especially how you go from hardware trigger to packet transmission. Then we can start brainstorming how to simulate it.

Peter

Peshal Nayak

unread,
May 28, 2015, 7:45:43 PM5/28/15
to ns-3-...@googlegroups.com
I guess a fundamental question I'm trying to address right now is what makes a node transmit in ns-3. Is there a function that gets called and if yes, who calls it? If I can figure that out, I could possible use it to make multiple nodes transmit at the same time. The point of doing this simulation is because its not possible in hardware as of now and so its difficult to study different issues that I'm trying to look at in my research.

I've tried reading the documentation to figure this out and I wasn't able to come up with anything useful.

Best,
Peshal

Tommaso Pecorella

unread,
May 29, 2015, 4:54:28 AM5/29/15
to ns-3-...@googlegroups.com
Hi,

try reading the code, it's easier. A good IDE with a "who's calling this function" feature helps.
Suggestions:
1) Start with something "easy", like UdpSocketImpl::Send (). Follow the calls to other classes and you'll reach the NetDevice one.
2) Get acquainted with the callbacks, the manual will help you.
3) Mind that the NetDevice will be the one responsible for sending the packets. Additional delays could be added by those.

If you're searching for exact time synchronization (e.g., a TDMA), you'd better study some NetDevice. Start with something simple (e.g., CSMA) and move to more complex ones, with LTE and Wi-Fi being extremely complex.

Hope this helps,

T.

Peshal Nayak

unread,
Jun 13, 2015, 12:34:26 AM6/13/15
to ns-3-...@googlegroups.com
Thank you for your reply. I'm able to understand the transmit chain, but I'm stuck a little bit in the receive part. I started by taking a look at point-to-point net device as it looked like the simplest one available. In netdevice.h, there is the following line of code:

typedef Callback<bool,Ptr<NetDevice>,Ptr<const Packet>,uint16_t,const Address &> ReceiveCallback;

In point-to-point-net-device.h, there is this line of code:
NetDevice::ReceiveCallback m_rxCallback;

and in point-to-point-net-device.cc, there's this line of code in the Receive() function:

m_rxCallback (this, packet, protocol, GetRemote ());

My understanding is that the first line declares ReceiveCallback as pointer to a function with the specified signature i.e. input and output parameters. Then the second type creates an instance of this (maybe instance is not the best word but what I'm trying to say is that m_rxCallback is again a pointer to a function with the signature specified in the first line of code) while in the third line, some function is being called. Now this function is not in point-to-point-net-device.cc but in one of the above layers, I believe. But what part of the code specifies the class to which this function belongs to i.e. which specific function is being called? I want to know which specific function is being called so that I can see the rest of the receive chain. 

Also, I believe that "this" is pointing to the point-to-point-net-device. Is that correct?

Please let me know if my understanding is wrong. At this point I'm a bit stuck and need some help. I read the Callback section of the manual but it did not help answer this question.

Best,
Peshal 

Tommaso Pecorella

unread,
Jun 13, 2015, 6:12:37 AM6/13/15
to ns-3-...@googlegroups.com
Hi,

it's all perfect. Indeed, the Rx chain is the most complex, because it needs to do the demux, i.e., packets belonging to different protocols needs to be delivered to the right points.
Let's see it step by step.

You missed one thing in your analysis, as is where and who is setting m_rxCallback. This is done in this function:
void
PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
{
  m_rxCallback
= cb;
}

If you search for it, you'll not find any call to it. That's normal, as it's an overloaded virtual function: the callers are calling the base class function.
If you search who's calling NetDevice:: SetReceiveCallback, you'll find that it's used in the Node class:
uint32_t Node::AddDevice (Ptr<NetDevice> device)
{
  NS_LOG_FUNCTION
(this << device);
  uint32_t index
= m_devices.size ();
  m_devices
.push_back (device);
  device
->SetNode (this);
  device
->SetIfIndex (index);
  device
->SetReceiveCallback (MakeCallback (&Node::NonPromiscReceiveFromDevice, this));
 
Simulator::ScheduleWithContext (GetId (), Seconds (0.0),
                                 
&NetDevice::Initialize, device);
 
NotifyDeviceAdded (device);
 
return index;
}

In other terms, when a device is added, the m_rxCallback is set to point to Node::NonPromiscReceiveFromDevice (and to the instance "owning" that NetDevice).
That function will call another function that will iterate though all the protocols that did register themselves in the node as "willing to receive something". This is done (by the protocols) using "Node::RegisterProtocolHandler". This function also allows a protocol to specify a sort of filter to decide what packet types it wants to receive.

As an example, Ipv4L3protocol uses this:
  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this),
                                 
Ipv4L3Protocol::PROT_NUMBER, device);
More callbacks... but at the end, the packet will be delivered to Ipv4L3Protocol::Receive.

It may seems confusing, but at the end it all makes sense.

Hope this helps,

T.

PS: yes, "this" is the pointer to the current instance. It is passed as an argument to track what NetDevice did receive a packet.

pdbarnes

unread,
Jun 13, 2015, 10:42:21 AM6/13/15
to ns-3-...@googlegroups.com
Why does Node::AddDevice do this:

Simulator::ScheduleWithContext (GetId (), Seconds (0.0), &NetDevice::Initialize, device);

instead of just calling directly:

device->Initialize();

Tommaso Pecorella

unread,
Jun 13, 2015, 10:58:04 AM6/13/15
to ns-3-...@googlegroups.com
Woah, good question. This should be placed in the manual somewhere.

The answer is a trick, and I have to bow to whoever did it (I didn't do it).
If you use a direct call, the function will be called immediately, and the objects status will be dependent on the order the function has been called.
If you use a scheduled function, the function will be called *after* the function it scheduled is completed. As a consequence, the object status can be "finalized".

Practically speaking, take these two functions:
  Simulator::ScheduleWithContext (GetId (), Seconds (0.0), &NetDevice::Initialize, device);

 
NotifyDeviceAdded (device);

In this case "NotifyDeviceAdded" is called before the device is intialized.
With a direct call it would be called after.
Inverting the two functions could seems trivial, but it isn't, as one should also consider all the calling functions (if any).

Summarizing, Scheduled events can be used to "clean up" the callers chain and have a known status in the objects.
The drawback is that the scheduler is slower than a direct call. As a consequence, it's wiser to use this trick for initialization or objects destruction.

Have fun,

T.

Peshal Nayak

unread,
Jun 14, 2015, 5:45:11 PM6/14/15
to ns-3-...@googlegroups.com
Hey Guys,

Also, I'm trying to get familiar with the concept of trace sources and sinks and how to make use of a trace source if it is already defined in a specific ns 3 class. I believe that as I start making modifications to ns 3 modules, this will be a useful skill to have.

After reading the manual, I decided to begin with a simple script. I'm using first.cc from examples/tutorials/ . This script sets up two point to point net devices on two nodes and transmits a packet from one node to the other. The class point-to-point-net-device.cc has a Trace source called "MacTx" which indicates that a packet has arrived for transmission. I was trying to print out a statement such as "Packet Arrived" whenever this happens. So in first.cc I added the following function:

void myfunc()
{
    std
::cout <<  "Packet arrived!" << std::endl;
}

Now in the main function after setting up the netdevices, I added this line Config... as shown below:

NetDeviceContainer devices;
devices
= pointToPoint.Install (nodes);
Config::ConnectWithoutContext("MacTx",MakeCallback(&myfunc));

My understanding is that whenever the trace source is fired, myfunc() should get called. I believe that makecallback will create a pointer to myfunc which will be used to call the function and when myfunc() is called the statement "Packet arrived!" should get printed.

However, I get this error message:

assert failed. cond="slash != std::string::npos", file=../src/core/model/config.cc, line=518
terminate called without an active exception
Command ['/home/rng/repos/ns-3-allinone/ns-3.20/build/scratch/first'] terminated with signal SIGIOT. Run it under a debugger to get more information (./waf --run <program> --command-template="gdb --args %s <args>").

So I tried to run it under a debugger based on the information provided here:
https://www.nsnam.org/wiki/HOWTO_understand_and_find_cause_of_terminated_with_signal_errors

However, it leads me to something called raise.c and I don't know what to do next. I've also tried to take a look at wifi-example-sim.cc and tcp-large-transfer.cc but they are a little more complicated and I'm trying to do something simple. Also, the Config::ConnectWithoutContext line is similar to the one in tcp-large-transfer.cc.

All I want to know is that if a trace source is already present in one of the ns 3 classes, how do I access/make use of it?

I suppose I couldn't write a simpler program than the one I'm trying to.

This might sound like a dumb thing, but if anyone can please correct me that would be great.

Thank you.

Best,
Peshal

--
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/xJiWTsfxtQo/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 http://groups.google.com/group/ns-3-users.
For more options, visit https://groups.google.com/d/optout.

Peter Barnes

unread,
Jun 15, 2015, 4:01:26 PM6/15/15
to ns-3-...@googlegroups.com
I think your config path is incomplete.  It should probably  by something like
"/NodeList/0/$PointToPointNetDevice/MacTx"

Peter

On Jun 14, 2015, at 2:45 PM, Peshal Nayak <pesha...@gmail.com> wrote:

NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
Config::ConnectWithoutContext("MacTx",MakeCallback(&myfunc));

My understanding is that whenever the trace source is fired, myfunc() should get called. I believe that makecallback will create a pointer to myfunc which will be used to call the function and when myfunc() is called the statement "Packet arrived!" should get printed.

However, I get this error message:

____________
Peter Barnes
pd...@mac.com

Peter Barnes

unread,
Jun 15, 2015, 4:01:45 PM6/15/15
to ns-3-...@googlegroups.com
I think your config path is incomplete.  It should probably  by something like
"/NodeList/0/$PointToPointNetDevice/MacTx"

Peter
On Jun 14, 2015, at 2:45 PM, Peshal Nayak <pesha...@gmail.com> wrote:

NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
Config::ConnectWithoutContext("MacTx",MakeCallback(&myfunc));

My understanding is that whenever the trace source is fired, myfunc() should get called. I believe that makecallback will create a pointer to myfunc which will be used to call the function and when myfunc() is called the statement "Packet arrived!" should get printed.

However, I get this error message:

____________
Peter Barnes
pd...@mac.com

Peshal Nayak

unread,
Jun 15, 2015, 4:34:58 PM6/15/15
to ns-3-...@googlegroups.com
Ok. Thanks. There's no error message now. But myfunc() is still not called. I tried rest of the trace sources as well such as PhyRxEnd, PhyTxBegin and so on but myfunc() is still not called.

Peshal

Peshal Nayak

unread,
Jun 18, 2015, 12:11:53 PM6/18/15
to ns-3-...@googlegroups.com
I'm still not able to figure out why this is happenning. Can anyone please help me out?

Peshal


On Monday, June 15, 2015 at 3:34:58 PM UTC-5, Peshal Nayak wrote:
Ok. Thanks. There's no error message now. But myfunc() is still not called. I tried rest of the trace sources as well such as PhyRxEnd, PhyTxBegin and so on but myfunc() is still not called.

Peshal
On Mon, Jun 15, 2015 at 3:01 PM, Peter Barnes <pd...@mac.com> wrote:
I think your config path is incomplete.  It should probably  by something like
"/NodeList/0/$PointToPointNetDevice/MacTx"

Peter

See the tutorial and manual sections:

On Jun 14, 2015, at 2:45 PM, Peshal Nayak <pesha...@gmail.com> wrote:

NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
Config::ConnectWithoutContext("MacTx",MakeCallback(&myfunc));

My understanding is that whenever the trace source is fired, myfunc() should get called. I believe that makecallback will create a pointer to myfunc which will be used to call the function and when myfunc() is called the statement "Packet arrived!" should get printed.

However, I get this error message:

____________
Peter Barnes
pd...@mac.com

--
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/xJiWTsfxtQo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ns-3-users+unsubscribe@googlegroups.com.

Tommaso Pecorella

unread,
Jun 18, 2015, 1:45:36 PM6/18/15
to ns-3-...@googlegroups.com
Hi,

the only thing I can say is that the function signature and the trace are different. Try using the right signature (i.e., the right arguments).
Other than this... no idea. Without the full code is hard to say.

As a side note, there's a missing part in the Connect call. Most probably it is:
"/NodeList/0/DeviceList/*/$PointToPointNetDevice/MacTx"

If you have more than one PointToPoint device on the node, you should change the "*" with an appropriate number, and the exact number depends on the order you added the devices on the node. Please remember that installing Internet add a LoopbackNetDevice on the node. This could have an effect on the device index in the above path.

Cheers,

T.



On Thursday, June 18, 2015 at 6:11:53 PM UTC+2, Peshal Nayak wrote:
I'm still not able to figure out why this is happenning. Can anyone please help me out?

Peshal

On Monday, June 15, 2015 at 3:34:58 PM UTC-5, Peshal Nayak wrote:
Ok. Thanks. There's no error message now. But myfunc() is still not called. I tried rest of the trace sources as well such as PhyRxEnd, PhyTxBegin and so on but myfunc() is still not called.

Peshal
On Mon, Jun 15, 2015 at 3:01 PM, Peter Barnes <pd...@mac.com> wrote:
I think your config path is incomplete.  It should probably  by something like
"/NodeList/0/$PointToPointNetDevice/MacTx"

Peter

See the tutorial and manual sections:

On Jun 14, 2015, at 2:45 PM, Peshal Nayak <pesha...@gmail.com> wrote:

NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
Config::ConnectWithoutContext("MacTx",MakeCallback(&myfunc));

My understanding is that whenever the trace source is fired, myfunc() should get called. I believe that makecallback will create a pointer to myfunc which will be used to call the function and when myfunc() is called the statement "Packet arrived!" should get printed.

However, I get this error message:

____________
Peter Barnes
pd...@mac.com

--
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/xJiWTsfxtQo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ns-3-users+...@googlegroups.com.

Peshal Nayak

unread,
Jun 19, 2015, 10:34:54 AM6/19/15
to ns-3-...@googlegroups.com
Hi Tommaso,

How do I find the right arguments for this function. Should it be a pointer to a packet? Also, the code is attached, apart from the function and the Config line, I haven't made any changes to first.cc. I have marked the two changes with a comment line.


Thank you.

Peshal
first.cc

Konstantinos

unread,
Jun 19, 2015, 10:45:28 AM6/19/15
to ns-3-...@googlegroups.com, pesha...@gmail.com
Hi Peshal,

The path you are using is not correct.
Check with the API:
  • "/NodeList/[i]/DeviceList/[i]/$ns3::PointToPointNetDevice"
You have missed the 'DeviceList' 

Regards,
K.
To unsubscribe from this group and all its topics, send an email to ns-3-users+unsubscribe@googlegroups.com.

Konstantinos

unread,
Jun 19, 2015, 10:49:45 AM6/19/15
to ns-3-...@googlegroups.com, dinos.k...@gmail.com, pesha...@gmail.com
As far as the arguments are concerned, again check with the API.

Peshal Nayak

unread,
Jun 19, 2015, 10:50:00 AM6/19/15
to ns-3-...@googlegroups.com
Hi Konstantinos,

I tried that too. Still doesn't work.

Peshal

Konstantinos

unread,
Jun 19, 2015, 10:59:02 AM6/19/15
to ns-3-...@googlegroups.com, pesha...@gmail.com
What do you mean it does not work?

I just run the script with the two modifications I mentioned (the DeviceList and the function signature) and this is the output

 ./waf --run scratch/ns3user

Waf: Entering directory `/Users/ntinos/ns3/ns-3.22/build'

Waf: Leaving directory `/Users/ntinos/ns3/ns-3.22/build'

'build' finished successfully (2.691s)

At time 2s client sent 1024 bytes to 10.1.1.2 port 9

At time 2.00369s server received 1024 bytes from 10.1.1.1 port 49153

At time 2.00369s server sent 1024 bytes to 10.1.1.1 port 49153

I was called

At time 2.00737s client received 1024 bytes from 10.1.1.2 port 9



As you can see, your function is called.

Regards,
K.
To unsubscribe from this group and all its topics, send an email to ns-3-users+unsubscribe@googlegroups.com.

To post to this group, send email to ns-3-...@googlegroups.com.
Visit this group at http://groups.google.com/group/ns-3-users.
For more options, visit https://groups.google.com/d/optout.

--
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/xJiWTsfxtQo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ns-3-users+unsubscribe@googlegroups.com.

Peshal Nayak

unread,
Jun 19, 2015, 11:19:23 AM6/19/15
to ns-3-...@googlegroups.com

Could you please attach the modified code? I need to check what I missed. I know this sounds stupid, but I need to be sure that I've set up everything in the right way. I'm not getting the output "I was called" when I run the code.

Peshal

Konstantinos

unread,
Jun 19, 2015, 11:21:51 AM6/19/15
to ns-3-...@googlegroups.com, pesha...@gmail.com
Here is the code. 
To unsubscribe from this group and all its topics, send an email to ns-3-users+unsubscribe@googlegroups.com.

To post to this group, send email to ns-3-...@googlegroups.com.
Visit this group at http://groups.google.com/group/ns-3-users.
For more options, visit https://groups.google.com/d/optout.

--
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/xJiWTsfxtQo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ns-3-users+unsubscribe@googlegroups.com.

To post to this group, send email to ns-3-...@googlegroups.com.
Visit this group at http://groups.google.com/group/ns-3-users.
For more options, visit https://groups.google.com/d/optout.

--
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/xJiWTsfxtQo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ns-3-users+unsubscribe@googlegroups.com.
ns3user.cc

Peshal Nayak

unread,
Jun 19, 2015, 11:52:25 AM6/19/15
to ns-3-...@googlegroups.com
Alright. This was really stupid:

In "/NodeList/[i]/DeviceList/[i]/$ns3::PointToPointNetDevice" I was simply replacing the i's with 0 and 1 while keeping the [ ]. With the brackets it doesn't give an error and myfunc() isn't called either. I took those brackets out and now I'm getting the output. Thanks for your help. I would have gone craze otherwise..

Peshal
Reply all
Reply to author
Forward
0 new messages