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
14 class VlcWirelessNetnsNs3Example(object):
16 usage = "usage: %prog -m movie -u user"
17 parser = OptionParser(usage=usage)
18 parser.add_option("-u", "--user", dest="user", help="Valid linux system user (not root).", type="str")
19 parser.add_option("-m", "--movie", dest="movie", help="Path to movie file to play", type="str")
20 (options, args) = parser.parse_args()
22 parser.error("Missing 'movie' option.")
23 if options.user == 'root':
24 parser.error("Missing or invalid 'user' option.")
26 self.user = options.user if options.user else os.getlogin()
27 self.movie = options.movie
28 self.root_dir = tempfile.mkdtemp()
30 def add_netns_tap(self, node, netns_desc):
31 tap = netns_desc.create("TapNodeInterface")
32 tap.set_attribute_value("up", True)
33 node.connector("devs").connect(tap.connector("node"))
36 def add_ns3_fdnd(self, node, ns3_desc):
37 fdnd = ns3_desc.create("ns3::FileDescriptorNetDevice")
38 node.connector("devs").connect(fdnd.connector("node"))
39 fdnd.enable_trace("FileDescriptorPcapTrace")
42 def add_ns3_node(self, ns3_desc):
43 node = ns3_desc.create("ns3::Node")
44 ipv4 = ns3_desc.create("ns3::Ipv4L3Protocol")
45 arp = ns3_desc.create("ns3::ArpL3Protocol")
46 icmp = ns3_desc.create("ns3::Icmpv4L4Protocol")
47 udp = ns3_desc.create("ns3::UdpL4Protocol")
48 node.connector("protos").connect(ipv4.connector("node"))
49 node.connector("protos").connect(arp.connector("node"))
50 node.connector("protos").connect(icmp.connector("node"))
51 node.connector("protos").connect(udp.connector("node"))
54 def add_ns3_wifi(self, node, ns3_desc, access_point = False):
55 wifi = ns3_desc.create("ns3::WifiNetDevice")
56 node.connector("devs").connect(wifi.connector("node"))
58 phy = ns3_desc.create("ns3::YansWifiPhy")
59 error = ns3_desc.create("ns3::NistErrorRateModel")
60 manager = ns3_desc.create("ns3::ArfWifiManager")
62 mac = ns3_desc.create("ns3::QapWifiMac")
64 mac = ns3_desc.create("ns3::QstaWifiMac")
66 phy.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
67 mac.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
68 phy.connector("err").connect(error.connector("phy"))
69 wifi.connector("phy").connect(phy.connector("dev"))
70 wifi.connector("mac").connect(mac.connector("dev"))
71 wifi.connector("manager").connect(manager.connector("dev"))
73 phy.enable_trace("YansWifiPhyPcapTrace")
76 def add_ns3_random_mobility(self, node, ns3_desc, x, y, z, speed,
77 bounds_width, bounds_height):
78 position = "%d:%d:%d" % (x, y, z)
79 bounds = "0|%d|0|%d" % (bounds_width, bounds_height)
80 speed = "Constant:%d" % speed
81 mobility = ns3_desc.create("ns3::RandomDirection2dMobilityModel")
82 mobility.set_attribute_value("Position", position)
83 mobility.set_attribute_value("Bounds", bounds)
84 mobility.set_attribute_value("Speed", speed)
85 mobility.set_attribute_value("Pause", "Constant:1")
86 node.connector("mobility").connect(mobility.connector("node"))
89 def add_ns3_constant_mobility(self, node, ns3_desc, x, y, z):
90 mobility = ns3_desc.create("ns3::ConstantPositionMobilityModel")
91 position = "%d:%d:%d" % (x, y, z)
92 mobility.set_attribute_value("Position", position)
93 node.connector("mobility").connect(mobility.connector("node"))
96 def add_ns3_wifi_channel(self, ns3_desc):
97 channel = ns3_desc.create("ns3::YansWifiChannel")
98 delay = ns3_desc.create("ns3::ConstantSpeedPropagationDelayModel")
99 loss = ns3_desc.create("ns3::LogDistancePropagationLossModel")
100 channel.connector("delay").connect(delay.connector("chan"))
101 channel.connector("loss").connect(loss.connector("prev"))
104 def add_ip_address(self, iface, address):
105 ip = iface.add_address()
106 ip.set_attribute_value("Address", address)
108 def add_route(self, node, destination, netprefix, nexthop):
109 route = node.add_route()
110 route.set_attribute_value("Destination", destination)
111 route.set_attribute_value("NetPrefix", netprefix)
112 route.set_attribute_value("NextHop", nexthop)
115 bounds_width = bounds_height = 200
119 exp_desc = ExperimentDescription()
121 ## NS3 Testbed instance description ##
122 testbed_version = "3_9_RC3"
124 ns3_provider = FactoriesProvider(testbed_id, testbed_version)
125 ns3_desc = exp_desc.add_testbed_description(ns3_provider)
126 ns3_desc.set_attribute_value("homeDirectory", self.root_dir)
127 ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
128 ns3_desc.set_attribute_value("ChecksumEnabled", True)
130 node1 = self.add_ns3_node(ns3_desc)
131 mobility1 = self.add_ns3_constant_mobility(node1, ns3_desc, x, y, 0)
132 wifi1, phy1 = self.add_ns3_wifi(node1, ns3_desc, access_point = False)
133 self.add_ip_address(wifi1, "10.0.1.1")
134 fdnd1 = self.add_ns3_fdnd(node1, ns3_desc)
135 self.add_ip_address(fdnd1, "10.0.0.1")
137 node2 = self.add_ns3_node(ns3_desc)
138 mobility2 = self.add_ns3_random_mobility(node2, ns3_desc, x, y, 0,
139 speed, bounds_width, bounds_height)
140 wifi2, phy2 = self.add_ns3_wifi(node2, ns3_desc, access_point = True)
141 self.add_ip_address(wifi2, "10.0.1.2")
142 fdnd2 = self.add_ns3_fdnd(node2, ns3_desc)
143 self.add_ip_address(fdnd2, "10.0.2.1")
144 # interconnect nodes with a wifi channel
145 wifichan = self.add_ns3_wifi_channel(ns3_desc)
146 phy1.connector("chan").connect(wifichan.connector("phys"))
147 phy2.connector("chan").connect(wifichan.connector("phys"))
149 ## NETNS testbed description 1 ##
150 testbed_version = "01"
152 netns_provider = FactoriesProvider(testbed_id, testbed_version)
153 netns_desc1 = exp_desc.add_testbed_description(netns_provider)
154 netns_desc1.set_attribute_value("homeDirectory", self.root_dir)
155 #netns_desc1.set_attribute_value("enableDebug", True
157 node3 = netns_desc1.create("Node")
158 node3.set_attribute_value("forward_X11", True)
159 tap1 = self.add_netns_tap(node3, netns_desc1)
160 self.add_ip_address(tap1, "10.0.0.2")
162 # DEBUG!! target = "{#[vlc_client].addr[0].[Address]#}"
164 command = "vlc -I dummy -vvv %s --sout '#rtp{dst=%s,port=5004,mux=ts}' vlc:quit" \
165 % (self.movie, target)
166 vlc_server = netns_desc1.create("Application")
167 vlc_server.set_attribute_value("command", command)
168 vlc_server.set_attribute_value("user", self.user)
169 vlc_server.connector("node").connect(node3.connector("apps"))
172 #xterm1 = netns_desc1.create("Application")
173 #xterm1.set_attribute_value("command", command)
174 #xterm1.set_attribute_value("user", self.user)
175 #xterm1.connector("node").connect(node3.connector("apps"))
177 ## NETNS testbed description 2 ##
178 netns_desc2 = exp_desc.add_testbed_description(netns_provider)
179 netns_desc2.set_attribute_value("homeDirectory", self.root_dir)
180 #netns_desc2.set_attribute_value("enableDebug", True)
182 node4 = netns_desc2.create("Node")
183 node4.set_attribute_value("forward_X11", True)
184 node4.set_attribute_value("label", "vlc_client")
185 tap2 = self.add_netns_tap(node4, netns_desc2)
186 self.add_ip_address(tap2, "10.0.2.2")
188 vlc_client = netns_desc2.create("Application")
189 command = "vlc rtp://%s:5004/test.ts" % target
190 vlc_client.set_attribute_value("command", command)
191 vlc_client.set_attribute_value("user", self.user)
192 vlc_client.connector("node").connect(node4.connector("apps"))
193 #vlc_trace = vlc_server.get_trace("StderrTrace")
194 #vlc_trace.get_attribute("Filename").value = "vlc_server.err"
198 #xterm2 = netns_desc2.create("Application")
199 #xterm2.set_attribute_value("command", command)
200 #xterm2.set_attribute_value("user", self.user)
201 #xterm2.connector("node").connect(node4.connector("apps"))
203 ## testbed_interconnection
204 fdnd1.connector("->fd").connect(tap1.connector("fd->"))
205 fdnd2.connector("->fd").connect(tap2.connector("fd->"))
207 self.add_route(node4, "10.0.0.0", 24, "10.0.2.1")
208 self.add_route(node4, "10.0.1.0", 24, "10.0.2.1")
209 self.add_route(node3, "10.0.2.0", 24, "10.0.0.1")
210 self.add_route(node3, "10.0.1.0", 24, "10.0.0.1")
212 self.add_route(node2, "10.0.0.0", 24, "10.0.1.1")
213 self.add_route(node1, "10.0.2.0", 24, "10.0.1.2")
215 xml = exp_desc.to_xml()
216 controller = ExperimentController(xml, self.root_dir)
218 while not controller.is_finished(vlc_server.guid):
221 controller.shutdown()
224 shutil.rmtree(self.root_dir)
226 if __name__ == '__main__':
227 example = VlcWirelessNetnsNs3Example()