How to build communication between mesh node and general 802.11 wifi node?

167 views
Skip to first unread message

辛文飞

unread,
May 1, 2017, 8:31:30 AM5/1/17
to ns-3-users
I have writen a program modeling the mesh.cc in the folder src/mesh/examples/, the source code has been uploaded as attachment. I have created extra two nodes as station node, and install the wifi netdevice on them. Then, I have also added one 802.11n wifi netdevice to two mesh nodes respectively for communicating with two station nodes respectively. You can download this attachment for a clear comprehension. But it failed to build communication between them. I don't know how to realize it. Hope someone can help me. And in my code, I have raised another two questions (1, MeshHelper::Install() install two netdevice? Or it is a bug?  2, The last pointer(which points to netdevice) of index is invalid, I don't know why it returns four when I use the function node::GetNDevices()  )as annotations.

I write it with ns3.26 on LinuxMint 18.1.

PS: If you want to run this program on your computer, you need to create to folders: pcap and xml, the same level as the scratch folder. Or you can modify the code.

#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mesh-module.h"
#include "ns3/mobility-module.h"
#include "ns3/mesh-helper.h"
#include "ns3/netanim-module.h"

#include <iostream>
#include <sstream>
#include <fstream>

/*
* The topology is displayed as following
* Nodes in rectangle are mesh nodes
* sta0 and sta1 are general station nodes
* The program is to send data from sta0
 * to sta1 nodes transmiting by mesh nodes
*
*    sta0
*        *  
*         -----------
*   ap0-->|*   *   *|
*         |         |
*         |*   *   *|
*         |         |
*         |*   *   *|<--ap1
*         -----------
 *                    *
*                  sta1
*/

using namespace ns3;

NS_LOG_COMPONENT_DEFINE("MeshScript");

int main(int argc, char* argv[])
{
   uint16_t rowNodes = 3;
   uint16_t colNodes = 3;
   double   distance = 50;// meter
   double   totalTime = 100;//seconds
   double   pktInterval = 0.1; //second
   uint16_t pktSize  = 1024;
    uint32_t nIntf    = 1;
   bool     pcap     = true;
   bool     log      = true;
   double   randomStart = 0.1;
   uint16_t staNum   = 2;// numbers of station nodes
   double   nodeWidth = 5.0;
   double   nodeHeight = 5.0;
   std::string phyMode = "HtMcs0";

    CommandLine cmd;
   cmd.AddValue("rowN", "Number of nodes in a row", rowNodes);
   cmd.AddValue("colN", "Number of nodes in a column", colNodes);
   cmd.AddValue("dis",  "Distance between two nodes", distance);
   cmd.AddValue("time", "Sum simulation time", totalTime);
   cmd.AddValue("interval", "Interval between sending two pakcets", pktInterval);
   cmd.AddValue("intfN","Number of radio interfaces used by each mesh point.[0.001s]", nIntf);
   cmd.AddValue("pcap", "Enable pcap trace on interfaces.[true]", pcap);
   cmd.AddValue("log",  "Enable log info when running", log);

    if(log){
       LogComponentEnable("MeshScript", LOG_LEVEL_INFO);
       //LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
       //LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
   }
   NS_LOG_INFO("Grid: "<<rowNodes<<"*"<<colNodes);
   NS_LOG_INFO("Simulation time: "<<totalTime<<" s.");

    YansWifiPhyHelper phy = YansWifiPhyHelper::Default();
   YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
   phy.SetChannel (channel.Create());

    MeshHelper mesh = MeshHelper::Default();
   std::string stack = "ns3::Dot11sStack";
   std::string root  = "ff:ff:ff:ff:ff:ff";
   mesh.SetStackInstaller(stack);
   mesh.SetSpreadInterfaceChannels(MeshHelper::SPREAD_CHANNELS);
   mesh.SetMacType("RandomStart", TimeValue(Seconds(randomStart)));
   mesh.SetNumberOfInterfaces(nIntf);

    NodeContainer meshNC;
   meshNC.Create(rowNodes*colNodes);

    NetDeviceContainer meshDevices = mesh.Install(phy, meshNC);

    MobilityHelper mobility;
   mobility.SetPositionAllocator("ns3::GridPositionAllocator",
           "MinX", DoubleValue(50.0),
           "MinY", DoubleValue(50.0),
           "DeltaX", DoubleValue(distance),
           "DeltaY", DoubleValue(distance),
           "GridWidth", UintegerValue(rowNodes),
           "LayoutType", StringValue("RowFirst"));
   mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
   mobility.Install(meshNC);
    NodeContainer staNC;
   staNC.Create(staNum);

    WifiHelper wifi;
   wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
           "DataMode",StringValue(phyMode),
           "ControlMode",StringValue(phyMode));
   wifi.SetStandard(WIFI_PHY_STANDARD_80211n_2_4GHZ);
   //wifi.SetStandard(WIFI_PHY_STANDARD_80211g);

    Ssid ssid = Ssid("ap");
   NqosWifiMacHelper mac;
   mac.SetType("ns3::StaWifiMac","Ssid", SsidValue(ssid));
   NetDeviceContainer staDevices;
   staDevices = wifi.Install(phy, mac, staNC);

    NodeContainer apNC;
   apNC.Add(meshNC.Get(0));
   apNC.Add(meshNC.Get(rowNodes*colNodes-1));

    mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
   NetDeviceContainer apDevices;
   apDevices = wifi.Install(phy, mac, apNC);

    //std::cout<<"Ap 1's mac address: "<<Mac48Address::ConvertFrom( apDevices.Get(0)->GetAddress() )<<std::endl;
   //std::cout<<"Ap 2's mac address: "<<Mac48Address::ConvertFrom( apDevices.Get(1)->GetAddress() )<<std::endl;

    //Mesh nodes have two netdevice in default.
   //for(int i = 0; i < meshNC.GetN(); ++i){
   //    std::cout<<meshNC.Get(i)->GetNDevices()<<std::endl;
   //}
   
   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
   positionAlloc->Add (Vector (0.0, 0.0, 0.0));
   positionAlloc->Add (Vector ((rowNodes+1)*50.0, (colNodes+1)*50.0, 0.0));
   mobility.SetPositionAllocator(positionAlloc);
   mobility.Install(staNC);

   if(pcap)
       phy.EnablePcapAll(std::string("pcap/stamesh"));

    InternetStackHelper istack;
   istack.Install(meshNC);
   istack.Install(staNC);
   Ipv4AddressHelper address;
   address.SetBase("10.1.1.0", "255.255.255.0");
   Ipv4InterfaceContainer intf = address.Assign(staDevices.Get(0));
   intf.Add( address.Assign(apDevices.Get(0)) );
   intf.Add( address.Assign(meshDevices) );
   intf.Add( address.Assign(apDevices.Get(1)) );
   intf.Add( address.Assign(staDevices.Get(1)) );

    for(uint16_t i = 0; i < staNC.GetN(); i++){
       Ptr<NetDevice> ptr_netdev = staNC.Get(i)->GetDevice(0);
       Ptr<WifiNetDevice> ptr_wifi_netdev = DynamicCast<WifiNetDevice>(ptr_netdev);
       Ptr<WifiMac> ptr_wifimac = ptr_wifi_netdev->GetMac();
       std::cout<<"staNode "<<i<<"'s(id:"<<staNC.Get(i)->GetId()<<") mac address: "<<ptr_wifimac->GetAddress()<<std::endl;
   }

    for(uint16_t i = 0; i < apNC.GetN(); i++){
       uint16_t ndevs = apNC.Get(i)->GetNDevices();
       //This is strange that ndevs is four as strange as
       //the reresult: apNC.Get(0)->GetN() = 3 after I installed the
       //wifi netdevice.
       //The last index(j) cannot return a valid pointer that
       //point to netdevice, at the same time, return values of
       //index(j) one and two are the same, I think the function of
       //MeshHelper::Install() has installed two netdevices, the
       //first one is MeshPointDevice, and the second one is
        //WifiNetDevice. but the value of ndevs of apnode is four, this
       //still makes me puzzled.
       //
       //std::cout<<ndevs<<std::endl;
       for(uint16_t j = 1; j < ndevs - 1; j++){
           Ptr<NetDevice> ptr_netdev = apNC.Get(i)->GetDevice(j);
           //only the first is the mesh point device
           //I don't want to see the repeated value, therefore, I
           //make the j begin from one.
           if(j == 0){
               Ptr<MeshPointDevice> ptr_mesh_netdev = DynamicCast<MeshPointDevice>(ptr_netdev);
               //Using mesh wifi interface mac to output the mac address
               //std::vector< Ptr<NetDevice> > vec = ptr_mesh_netdev->GetInterfaces();
               //for(std::vector<Ptr<NetDevice> >::const_iterator k = vec.begin(); k != vec.end(); ++k){
               //    Ptr<WifiNetDevice> device = (*k)->GetObject<WifiNetDevice>();
               //    Ptr<MeshWifiInterfaceMac> ptr_meshmac = device->GetMac()->GetObject<MeshWifiInterfaceMac>();
               //    std::cout<<"apNode "<<i<<"'s "<<j<<"'s device mac address: "<<ptr_meshmac->GetMeshPointAddress()<<std::endl;
               //}
               std::cout<<"apNode "<<i<<"'s "<<j<<"'s device mac address: "<<Mac48Address::ConvertFrom( ptr_mesh_netdev->GetAddress() )<<std::endl;
           }else{
               Ptr<WifiNetDevice> ptr_wifi_netdev = DynamicCast<WifiNetDevice>(ptr_netdev);
               Ptr<WifiMac> ptr_wifimac = ptr_wifi_netdev->GetMac();
               std::cout<<"apNode "<<i<<"'s "<<j<<"'s device mac address: "<<ptr_wifimac->GetAddress()<<std::endl;
           }
       }
   }

    UdpEchoServerHelper echoServer(9);
   ApplicationContainer serverApp = echoServer.Install(staNC.Get(1));
   serverApp.Start(Seconds(0.0));
   serverApp.Stop(Seconds(totalTime));
   UdpEchoClientHelper echoClient(intf.GetAddress(0), 9);
   echoClient.SetAttribute("MaxPackets", UintegerValue(100));
   echoClient.SetAttribute("Interval", TimeValue(Seconds(pktInterval)));
   echoClient.SetAttribute("PacketSize", UintegerValue(pktSize));
   ApplicationContainer clientApp = echoClient.Install(staNC.Get(0));
   clientApp.Start(Seconds(0.0));
   clientApp.Stop(Seconds(totalTime));

    AnimationInterface anim("xml/stamesh.xml");
   anim.UpdateNodeColor(staNC.Get(0), 0, 255, 0);
   anim.UpdateNodeSize (staNC.Get(0)->GetId(), nodeWidth, nodeHeight);
   anim.UpdateNodeColor(staNC.Get(1), 255, 0, 0);
   anim.UpdateNodeSize (staNC.Get(1)->GetId(), nodeWidth, nodeHeight);
   for(int i = 0; i < rowNodes*colNodes; i++){
       anim.UpdateNodeColor(meshNC.Get(i), 0, 0, 255);
       anim.UpdateNodeSize(meshNC.Get(i)->GetId(), nodeWidth, nodeHeight);
   }

    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

    Simulator::Stop(Seconds(totalTime));
   Simulator::Run();
   Simulator::Destroy();

    return 0;

}



stamesh.cc

Tommaso Pecorella

unread,
May 1, 2017, 6:07:48 PM5/1/17
to ns-3-users
Hi,

I'll be short, but just because the answer doesn't need to be long.

1) You need to use a BrigeNetDevice to bridge the Mesh and the Wi-Fi infrastructure interfaces.
2) The extra NetDevice you see is the bottom Wi-Fi NetDevice. A mesh net device is made by two NetDevices: a MeshNetDevice (upper) and a WifiNetDevice (lower).
2a) If you need to do an operation on the mesh device, you have to do a DynamicCast and check if it failed.

BR,

T.

辛文飞

unread,
May 1, 2017, 9:03:33 PM5/1/17
to ns-3-users
1, Which node should I install the BridgeNetDevice? On an independent node or the AP node(aggregation of ap and mesh)?
2, As your explanation, there are two netdevices being installed when I install mesh net device, one is wifinetdevice(lower), another is meshnetdevice(upper). But in the for loop, when I call the function apNC.Get(i)->GetNDevices() ,it returns the value 4? Why? When I call the function apNC.Get(i)->GetDevice(j), the return value of last j is not an valid pointer.
3. I think this suggestion is very good and practical, I will do this in my following coding work, once, I have wasted much time when I checked the error due to the NULL Pointer that I didn't make a verification before using it, this happened twice, and the compiler also didn't tell me that. It should make me careful.

在 2017年5月2日星期二 UTC+8上午6:07:48,Tommaso Pecorella写道:

Tommaso Pecorella

unread,
May 1, 2017, 9:20:27 PM5/1/17
to ns-3-users
Answers in line.


On Tuesday, May 2, 2017 at 3:03:33 AM UTC+2, 辛文飞 wrote:
1, Which node should I install the BridgeNetDevice? On an independent node or the AP node(aggregation of ap and mesh)?

In the node that have BOTH the mesh device and the infrastructure Wi-Fi, as i told you.

2, As your explanation, there are two netdevices being installed when I install mesh net device, one is wifinetdevice(lower), another is meshnetdevice(upper). But in the for loop, when I call the function apNC.Get(i)->GetNDevices() ,it returns the value 4? Why? When I call the function apNC.Get(i)->GetDevice(j), the return value of last j is not an valid pointer.

After you install Internet there's also the LoopbackNetDevice - 4.
As for the last pointer being null, I have no idea, Your code runs without errors, so I'm inclined to think that you did check the "last" index in the wrong moment in time.

3. I think this suggestion is very good and practical, I will do this in my following coding work, once, I have wasted much time when I checked the error due to the NULL Pointer that I didn't make a verification before using it, this happened twice, and the compiler also didn't tell me that. It should make me careful.

As a general rule you should ALWAYS use DynamicCast and check its result. As an example, you're assuming that MeshNetDevice is at index 0, but this is right only if you have a precise order in the devices creation.

T.

辛文飞

unread,
May 2, 2017, 12:18:03 AM5/2/17
to ns-3-users
Just like your answer, I have installed the bridge into the nodes which have both mesh device and infrastructure Wi-Fi, but the error is 

msg="Device does not support SendFrom: cannot be added to bridge."



Following bold code snippet is that I have added about the bridge module. I also have uploaded the changed code as an attachment.

...


    mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
    NetDeviceContainer apDevices;
    apDevices = wifi.Install(phy, mac, apNC);

    BridgeHelper bridge;

    NetDeviceContainer bridgeNetDevs1;
    bridgeNetDevs1.Add(meshDevices.Get(0));
    bridgeNetDevs1.Add(apDevices.Get(0));
    bridge.Install(apNC.Get(0), bridgeNetDevs1);

    NetDeviceContainer bridgeNetDevs2;
    bridgeNetDevs2.Add(meshDevices.Get(rowNodes*colNodes - 1));
    bridgeNetDevs2.Add(apDevices.Get(1));
    bridge.Install(apNC.Get(1), bridgeNetDevs2);

    //std::cout<<"Ap 1's mac address: "<<Mac48Address::ConvertFrom( apDevices.Get(0)->GetAddress() )<<std::endl;
    //std::cout<<"Ap 2's mac address: "<<Mac48Address::ConvertFrom( apDevices.Get(1)->GetAddress() )<<std::endl;
...


I have noticed the attention that the wifi net device must be set with Access Point mode if it includes wifi net device in offical API document. The mesh net device is supported by wifi infrastructure, but the mac type is set with "RandomStart". Does this should be the reason of the error?



在 2017年5月2日星期二 UTC+8上午9:20:27,Tommaso Pecorella写道:
在 2017年5月2日星期二 UTC+8上午9:20:27,Tommaso Pecorella写道:
在 2017年5月2日星期二 UTC+8上午9:20:27,Tommaso Pecorella写道:
在 2017年5月2日星期二 UTC+8上午9:20:27,Tommaso Pecorella写道:
在 2017年5月2日星期二 UTC+8上午9:20:27,Tommaso Pecorella写道:
stamesh2.cc

辛文飞

unread,
May 3, 2017, 3:57:19 AM5/3/17
to ns-3-users
Is anyone there can help me? I don't know how to make it effective in my code。I have read the example in the bridge module.

在 2017年5月2日星期二 UTC+8下午12:18:03,辛文飞写道:

Tommaso Pecorella

unread,
May 3, 2017, 6:56:26 PM5/3/17
to ns-3-users
Patience... we're not here every day.

It seems you're right. Bridge is not a solution.
I fear you'll have to use plain, old routing between themes network and the infrastructure part.

In this case you'll have 3 subnetworks, one for AP1-STA1, one for AP2-STA2 and one for the mesh part. Just don't forget to setup also the default routes in the network.

T.

辛文飞

unread,
May 7, 2017, 10:58:18 PM5/7/17
to ns-3-users
As you said, the bridge is not the solution, I have find the root cause of this in the file src/mesh/model/mesh-point-device.cc

The developers don't give any reason why the mesh point device can't be allowed to bridge. Whether the ns3 will go wrong, if the mesh point device enables bridge function.


If I modify the code to "return true", and then rebuild the ns3, will it work right?


And the second you said, I can't understand clearly, what is plain, old routing? I have tried to use static routing, but it doesn't work. And what's the infrastructure part indicates for?

I feel awful about this problem(Building the communication between mesh network and general wifi network), I don't know how to solve it, can you give me a clear advice or method? In this thread, the simulation scenario is pretty similar to mine, and he had builded the communication between the mesh network and an AP successfully, I had tried to contact with him, but there is no reply from him, maybe it was too long.

在 2017年5月4日星期四 UTC+8上午6:56:26,Tommaso Pecorella写道:

Tommaso Pecorella

unread,
May 8, 2017, 10:04:51 AM5/8/17
to ns-3-users
Hi,

changing SupportSendFrom will not work. If the mode is not supported, simply stating that it is won't change the fact that it isn't.
About "plain old routing", yes, I meant StaticRouting or similar. I don't know what you mean by "it's not working", so I can't give you advices.

T.

辛文飞

unread,
May 8, 2017, 3:19:52 PM5/8/17
to ns-3-users
"it's not working" means that even I have used the static routing to the mixed nodes, it still can't find the route. The communication is still limited to the  subnet. Now, I write a simple program that the network forms with csma and mesh network. The strange thing is that the csma network can get the mesh node's route broadcast packet, but it can't get the route. Hoping you can run this program and give me some advice. Thank you!

在 2017年5月8日星期一 UTC+8下午10:04:51,Tommaso Pecorella写道:
csma-mesh-0-0.pcap
csma-mesh-1-0.pcap
csma-mesh-1-3.pcap
csma-mesh-2-2.pcap
csmamesh.cc

Tommaso Pecorella

unread,
May 8, 2017, 4:50:53 PM5/8/17
to ns-3-users
Sorry, but I give up.
Please find a book and study how routing works, I can't honestly fix all the issues in the world - let alone re-explain for the zillionth time how IP routing works.
You have a router with the very same subnet on its two interfaces. It won't work. It can't work.
There are multiple examples of routing schemes and networks in ns-3.
There are infinte books and tutorials on the Internet.
Find, study, plan and only afterwards you'll be able to simulate.

T.
Reply all
Reply to author
Forward
0 new messages