#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;
}
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)?
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.
...
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;
...
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?