diff --git a/examples/wifi-wired-bridging.cc b/examples/wifi-wired-bridging.cc new file mode 100644 index 000000000..ad40448f6 --- /dev/null +++ b/examples/wifi-wired-bridging.cc @@ -0,0 +1,162 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ + +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/mobility-module.h" +#include "ns3/helper-module.h" +#include "ns3/wifi-module.h" +#include "ns3/node-module.h" +#include "ns3/global-route-manager.h" +#include +#include +#include + +using namespace ns3; + +Ptr +CreateChannel (void) +{ + Ptr channel = CreateObject (); + channel->SetPropagationDelayModel (CreateObject ()); + Ptr log = CreateObject (); + log->SetReferenceModel (CreateObject ()); + channel->SetPropagationLossModel (log); + return channel; +} + +int main (int argc, char *argv[]) +{ + uint32_t nWifis = 2; + uint32_t nStas = 2; + bool sendIp = true; + + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + + CommandLine cmd; + cmd.AddValue ("nWifis", "Number of wifi networks", nWifis); + cmd.AddValue ("nStas", "Number of stations per wifi network", nStas); + cmd.AddValue ("SendIp", "Send Ipv4 or raw packets", sendIp); + cmd.Parse (argc, argv); + + NodeContainer backboneNodes; + NetDeviceContainer backboneDevices; + Ipv4InterfaceContainer backboneInterfaces; + std::vector staNodes; + std::vector staDevices; + std::vector apDevices; + std::vector staInterfaces; + std::vector apInterfaces; + + InternetStackHelper stack; + CsmaHelper csma; + Ipv4AddressHelper ip; + ip.SetBase ("192.168.0.0", "255.255.255.0"); + + backboneNodes.Create (nWifis); + stack.Install (backboneNodes); + + backboneDevices = csma.Install (backboneNodes); + backboneInterfaces = ip.Assign (backboneDevices); + + double wifiX = 0.0; + for (uint32_t i = 0; i < nWifis; ++i) + { + // calculate ssid for wifi subnetwork + std::ostringstream oss; + oss << "wifi-default-" << i; + Ssid ssid = Ssid (oss.str ()); + + NodeContainer sta; + NetDeviceContainer staDev; + NetDeviceContainer apDev; + Ipv4InterfaceContainer staInterface; + Ipv4InterfaceContainer apInterface; + MobilityHelper mobility; + BridgeHelper bridge; + WifiHelper wifi; + Ptr channel; + + sta.Create (nStas); + wifi.SetPhy ("ns3::WifiPhy"); + channel = CreateChannel (); + ip.NewNetwork (); + mobility.SetPositionAllocator ("ns3::GridPositionAllocator", + "MinX", DoubleValue (wifiX), + "MinY", DoubleValue (0.0), + "DeltaX", DoubleValue (5.0), + "DeltaY", DoubleValue (5.0), + "GridWidth", UintegerValue (1), + "LayoutType", StringValue ("RowFirst")); + + + // setup the AP. + mobility.SetMobilityModel ("ns3::StaticMobilityModel"); + mobility.Install (backboneNodes.Get (i)); + wifi.SetMac ("ns3::NqapWifiMac", + "Ssid", SsidValue (ssid), + "BeaconGeneration", BooleanValue (true), + "BeaconInterval", TimeValue (Seconds (2.5))); + apDev = wifi.Install (backboneNodes.Get (i), channel); + apInterface = ip.Assign (apDev); + bridge.Install (backboneNodes.Get (i), NetDeviceContainer (apDev, backboneDevices.Get (i))); + + // setup the STAs + stack.Install (sta); + mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel", + "Mode", StringValue ("Time"), + "Time", StringValue ("2s"), + "Speed", StringValue ("Constant:1.0"), + "Bounds", RectangleValue (Rectangle (wifiX, wifiX+5.0,0.0, (nStas+1)*5.0))); + mobility.Install (sta); + wifi.SetMac ("ns3::NqstaWifiMac", + "Ssid", SsidValue (ssid), + "ActiveProbing", BooleanValue (false)); + staDev = wifi.Install (sta, channel); + staInterface = ip.Assign (staDev); + + // save everything in containers. + staNodes.push_back (sta); + apDevices.push_back (apDev); + apInterfaces.push_back (apInterface); + staDevices.push_back (staDev); + staInterfaces.push_back (staInterface); + + wifiX += 20.0; + } + + GlobalRouteManager::PopulateRoutingTables (); + + Address dest; + std::string protocol; + if (sendIp) + { + dest = InetSocketAddress (staInterfaces[1].GetAddress (1), 1025); + protocol = "ns3::UdpSocketFactory"; + } + else + { + PacketSocketAddress tmp; + tmp.SetSingleDevice (staDevices[0].Get (0)->GetIfIndex ()); + tmp.SetPhysicalAddress (staDevices[1].Get (0)->GetAddress ()); + tmp.SetProtocol (0x807); + dest = tmp; + protocol = "ns3::PacketSocketFactory"; + } + OnOffHelper onoff = OnOffHelper (protocol, dest); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + ApplicationContainer apps = onoff.Install (staNodes[0].Get (0)); + apps.Start (Seconds (0.5)); + apps.Stop (Seconds (3.0)); + + + WifiHelper::EnablePcap ("wifi-wire-bridging", staNodes[1].Get (1)); + WifiHelper::EnablePcap ("wifi-wire-bridging", staNodes[0].Get (0)); + std::ofstream os; + os.open ("wifi-wire-bridging.mob"); + MobilityHelper::EnableAsciiAll (os); + + Simulator::Stop (Seconds (100.0)); + Simulator::Run (); + +} diff --git a/examples/wscript b/examples/wscript index 199a5566b..c4a8c7c81 100644 --- a/examples/wscript +++ b/examples/wscript @@ -85,3 +85,8 @@ def build(bld): obj.source = 'wifi-ap.cc' bld.add_subdirs('stats') + + obj = bld.create_ns3_program('wifi-wired-bridging', + ['core', 'simulator', 'mobility', 'wifi', + 'csma', 'helper', 'bridge']) + obj.source = 'wifi-wired-bridging.cc' diff --git a/src/helper/net-device-container.cc b/src/helper/net-device-container.cc index e2a963e84..bcdae3b97 100644 --- a/src/helper/net-device-container.cc +++ b/src/helper/net-device-container.cc @@ -21,6 +21,19 @@ namespace ns3 { +NetDeviceContainer::NetDeviceContainer () +{} +NetDeviceContainer::NetDeviceContainer (Ptr dev) +{ + m_devices.push_back (dev); +} +NetDeviceContainer::NetDeviceContainer (const NetDeviceContainer &a, const NetDeviceContainer &b) +{ + *this = a; + Add (b); +} + + NetDeviceContainer::Iterator NetDeviceContainer::Begin (void) const { diff --git a/src/helper/net-device-container.h b/src/helper/net-device-container.h index 477da54a6..e3357ee9d 100644 --- a/src/helper/net-device-container.h +++ b/src/helper/net-device-container.h @@ -35,6 +35,33 @@ class NetDeviceContainer public: typedef std::vector >::const_iterator Iterator; + /** + * Create an empty NetDeviceContainer. + */ + NetDeviceContainer (); + /** + * \param dev a device to add to the container + * + * Create a NetDeviceContainer with exactly one device + */ + NetDeviceContainer (Ptr dev); + /** + * \param a a device container + * \param b another device container + * + * Create a device container which is a concatenation of the two input + * NetDeviceContainers. + * + * \note A frequently seen idiom that uses these constructors involves the + * implicit conversion by constructor of Ptr. When used, two + * Ptr will be passed to this constructor instead of NetDeviceContainer&. + * C++ will notice the implicit conversion path that goes through the + * NetDeviceContainer (Ptr dev) constructor above. Using this conversion + * one may provide optionally provide arguments of Ptr to these + * constructors. + */ + NetDeviceContainer (const NetDeviceContainer &a, const NetDeviceContainer &b); + /** * \returns an iterator which points to the start of the array of pointers. */ diff --git a/wscript b/wscript index eb8ae49ca..52a70d2d8 100644 --- a/wscript +++ b/wscript @@ -425,13 +425,16 @@ def build(bld): if env['NSC_ENABLED'] == 'yes': nsc_build(bld) -def get_command_template(): +def get_command_template(arguments): if Params.g_options.valgrind: if Params.g_options.command_template: Params.fatal("Options --command-template and --valgrind are conflicting") - return "valgrind --leak-check=full %s" + cmd = "valgrind --leak-check=full %s" else: - return (Params.g_options.command_template or '%s') + cmd = Params.g_options.command_template or '%s' + for arg in arguments: + cmd = cmd + " " + arg + return cmd def shutdown(): @@ -821,7 +824,7 @@ class Regression(object): env = Params.g_build.env_of_name('default') self.diff = env['DIFF'] - def run_test(self, verbose, generate, refDirName, testName): + def run_test(self, verbose, generate, refDirName, testName, *arguments): refTestDirName = os.path.join(refDirName, (testName + ".ref")) if not os.path.exists(refDirName): @@ -834,7 +837,10 @@ class Regression(object): os.mkdir(refTestDirName) Params.g_options.cwd_launch = refTestDirName - run_program(testName) + tmpl = "%s" + for arg in arguments: + tmpl = tmpl + " " + arg + run_program(testName, tmpl) print "Remember to commit " + refTestDirName return 0 @@ -849,7 +855,7 @@ class Regression(object): #os.system("./waf --cwd regression/traces --run " + # testName + " > /dev/null 2>&1") Params.g_options.cwd_launch = "traces" - run_program(testName, command_template=get_command_template()) + run_program(testName, command_template=get_command_template(arguments)) if verbose: #diffCmd = "diff traces " + refTestDirName + " | head"