2 # -*- coding: utf-8 -*-
4 from nepi.core.design import ExperimentDescription, FactoriesProvider
5 from nepi.core.execute import ExperimentController
6 from optparse import OptionParser, SUPPRESS_HELP
7 from nepi.util import proxy
8 from nepi.util.constants import DeploymentConfiguration as DC
16 -----------------------------------------------------------------------
19 | +-----+ +-----+ +-----+ +-----+ +------+ |
20 | |node1| |node2| |node3| |node4 | |server| |
21 | +-----+ +-----+ +-----+ +-----+ +------+ |
22 | 65/30 69/30 33/30 37/30 226/30 |
23 | ------- ------- ------- ------- -------- |
25 |---------------------------------------------------------------------|
27 | ------- ------- ------- ------- | |
28 | 66/30 30/30 34/30 38/30 | |
29 | +-----+ +-----+ +-----+ +-----+ | |
30 | |sta0 | |sta1 | |sta2 | |sta3 | | |
31 | +-----+ +-----+ +-----+ +-----+ | |
32 | 34/27 35/27 36/27 37/27 | |
33 | ------- -------- ------- ------- | |
34 | ((*)) ((*)) ((*)) ((*)) | |
41 | | AP | 225/30 |-------------------- |
45 -----------------------------------------------------------------------
49 class WirelessOverlay(object):
51 usage = "usage: %prog -n number_sta -m movie -u user"
52 parser = OptionParser(usage=usage)
53 parser.add_option("-u", "--user", dest="user", help="Valid linux system user (not root).", type="str")
54 parser.add_option("-m", "--movie", dest="movie", help="Path to movie file to play", type="str")
55 parser.add_option("-n", "--nsta", dest="nsta", help="Number of wifi stations", type="int")
56 parser.add_option("-a", "--base_addr", dest="base_addr", help="Base address segment for the experiment", type="str")
57 (options, args) = parser.parse_args()
58 #if not options.movie:
59 # parser.error("Missing 'movie' option.")
60 if options.user == 'root':
61 parser.error("Missing or invalid 'user' option.")
62 if options.user == 'root':
63 parser.error("Missing or invalid 'user' option.")
64 if options.nsta and options.nsta > 8:
65 parser.error("Try a number of stations under 9.")
67 self.user = options.user if options.user else os.getlogin()
68 #self.movie = options.movie
69 self.nsta = options.nsta if options.nsta else 2
70 base = options.base_addr if options.base_addr else "192.168.4"
71 self.base_addr = base + ".%d"
72 self.root_dir = tempfile.mkdtemp()
74 def add_netns_tap(self, netns_desc, node):
75 tap = netns_desc.create("TapNodeInterface")
76 tap.set_attribute_value("up", True)
77 node.connector("devs").connect(tap.connector("node"))
80 def add_ns3_fdnd(self, ns3_desc, node):
81 fdnd = ns3_desc.create("ns3::FdNetDevice")
82 node.connector("devs").connect(fdnd.connector("node"))
83 fdnd.enable_trace("FdPcapTrace")
86 def add_ns3_node(self, ns3_desc):
87 node = ns3_desc.create("ns3::Node")
88 ipv4 = ns3_desc.create("ns3::Ipv4L3Protocol")
89 arp = ns3_desc.create("ns3::ArpL3Protocol")
90 icmp = ns3_desc.create("ns3::Icmpv4L4Protocol")
91 udp = ns3_desc.create("ns3::UdpL4Protocol")
92 node.connector("protos").connect(ipv4.connector("node"))
93 node.connector("protos").connect(arp.connector("node"))
94 node.connector("protos").connect(icmp.connector("node"))
95 node.connector("protos").connect(udp.connector("node"))
98 def add_ns3_wifi(self, ns3_desc, node, access_point = False):
99 wifi = ns3_desc.create("ns3::WifiNetDevice")
100 node.connector("devs").connect(wifi.connector("node"))
102 phy = ns3_desc.create("ns3::YansWifiPhy")
103 error = ns3_desc.create("ns3::NistErrorRateModel")
104 manager = ns3_desc.create("ns3::ArfWifiManager")
106 mac = ns3_desc.create("ns3::ApWifiMac")
108 mac = ns3_desc.create("ns3::StaWifiMac")
110 phy.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
111 mac.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
112 phy.connector("err").connect(error.connector("phy"))
113 wifi.connector("phy").connect(phy.connector("dev"))
114 wifi.connector("mac").connect(mac.connector("dev"))
115 wifi.connector("manager").connect(manager.connector("dev"))
117 phy.enable_trace("YansWifiPhyPcapTrace")
120 def add_ns3_constant_mobility(self, ns3_desc, node, x, y, z):
121 mobility = ns3_desc.create("ns3::ConstantPositionMobilityModel")
122 position = "%d:%d:%d" % (x, y, z)
123 mobility.set_attribute_value("Position", position)
124 node.connector("mobility").connect(mobility.connector("node"))
127 def add_ns3_wifi_channel(self, ns3_desc):
128 channel = ns3_desc.create("ns3::YansWifiChannel")
129 delay = ns3_desc.create("ns3::ConstantSpeedPropagationDelayModel")
130 loss = ns3_desc.create("ns3::LogDistancePropagationLossModel")
131 channel.connector("delay").connect(delay.connector("chan"))
132 channel.connector("loss").connect(loss.connector("prev"))
135 def add_ip_address(self, iface, address, netprefix):
136 ip = iface.add_address()
137 ip.set_attribute_value("Address", address)
138 ip.set_attribute_value("NetPrefix", netprefix)
140 def add_route(self, node, destination, netprefix, nexthop):
141 route = node.add_route()
142 route.set_attribute_value("Destination", destination)
143 route.set_attribute_value("NetPrefix", netprefix)
144 route.set_attribute_value("NextHop", nexthop)
147 exp_desc = ExperimentDescription()
151 ns3_provider = FactoriesProvider("ns3")
152 ns3_desc = exp_desc.add_testbed_description(ns3_provider)
153 ns3_desc.set_attribute_value("homeDirectory", self.root_dir)
154 ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
155 ns3_desc.set_attribute_value("ChecksumEnabled", True)
157 ## NS3 wifi network 32/27
159 wifi_chan = self.add_ns3_wifi_channel(ns3_desc)
162 ap = self.add_ns3_node(ns3_desc)
163 self.add_ns3_constant_mobility(ns3_desc, ap, r, r, 0)
165 wifi_ap, phy_ap = self.add_ns3_wifi(ns3_desc, ap, access_point = True)
166 self.add_ip_address(wifi_ap, (self.base_addr%33), 27)
167 phy_ap.connector("chan").connect(wifi_chan.connector("phys"))
172 for i in xrange(0, self.nsta):
173 stai = self.add_ns3_node(ns3_desc)
174 angi = (360/self.nsta)*i
175 xi = r*math.cos(angi)
176 yi = r*math.sin(angi)
177 self.add_ns3_constant_mobility(ns3_desc, stai, xi, yi, 0)
178 wifi, phy= self.add_ns3_wifi(ns3_desc, stai, access_point = False)
179 wifi_addr = self.base_addr%(34 + i)
180 self.add_ip_address(wifi, wifi_addr, 27)
181 phy.connector("chan").connect(wifi_chan.connector("phys"))
182 sta_nodes.append((stai, wifi_addr))
186 netns_provider = FactoriesProvider("netns")
187 netns_desc = exp_desc.add_testbed_description(netns_provider)
188 netns_desc.set_attribute_value("homeDirectory", self.root_dir)
189 netns_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
190 netns_root_dir = os.path.join(self.root_dir, "netns_instance")
191 os.mkdir(netns_root_dir)
192 netns_desc.set_attribute_value(DC.ROOT_DIRECTORY, netns_root_dir)
193 netns_desc.set_attribute_value(DC.LOG_LEVEL, DC.DEBUG_LEVEL)
194 netns_desc.set_attribute_value(DC.USE_SUDO, True)
196 server = netns_desc.create("Node")
197 server.set_attribute_value("forward_X11", True)
200 app = netns_desc.create("Application")
201 app.set_attribute_value("command", command)
202 app.set_attribute_value("user", self.user)
203 app.connector("node").connect(server.connector("apps"))
205 # INTERCONNECTION NETNS/NS3
207 tap = self.add_netns_tap(netns_desc, server)
208 fdnd_ap = self.add_ns3_fdnd(ns3_desc, ap)
209 fdnd_ap.connector("->fd").connect(tap.connector("fd->"))
210 ## net NS3::fdnd/NETNS::tap 224/30
211 self.add_ip_address(fdnd_ap, (self.base_addr%225), 30)
212 self.add_ip_address(tap, (self.base_addr%226), 30)
215 self.add_route(server, (self.base_addr%32), 27, (self.base_addr%225))
218 for (stai, wifi_addr) in sta_nodes:
220 nodei = netns_desc.create("Node")
221 nodei.set_attribute_value("forward_X11", True)
222 tapi = self.add_netns_tap(netns_desc, nodei)
223 fdndi = self.add_ns3_fdnd(ns3_desc, stai)
224 fdndi.connector("->fd").connect(tapi.connector("fd->"))
226 ## net NS3::fdnd/NETNS::tap subnets of 64/27
228 self.add_ip_address(tapi, (self.base_addr%(net + 1)), 30)
229 self.add_ip_address(fdndi, (self.base_addr%(net + 2)), 30)
231 print i, " ", stai, " ", net
233 self.add_route(nodei, (self.base_addr%32), 27, (self.base_addr%(net+2)))
234 self.add_route(nodei, (self.base_addr%224), 30, (self.base_addr%(net+2)))
235 self.add_route(stai, (self.base_addr%224), 30, (self.base_addr%33))
237 self.add_route(ap, (self.base_addr%net), 30, wifi_addr)
238 self.add_route(server, (self.base_addr%net), 30, (self.base_addr%225))
242 xml = exp_desc.to_xml()
243 controller = ExperimentController(xml, self.root_dir)
245 while not controller.is_finished(app.guid):
249 controller.shutdown()
252 shutil.rmtree(self.root_dir)
254 if __name__ == '__main__':
255 example = WirelessOverlay()