fixed shebangs in non executable .py files
[nepi.git] / examples / vlc_wireless_netns_ns3.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
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 import os
9 import shutil
10 import tempfile
11 import test_util
12 import time
13
14 class VlcWirelessNetnsNs3Example(object):
15     def __init__(self):
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()
21         if not options.movie:
22             parser.error("Missing 'movie' option.")
23         if options.user == 'root':
24             parser.error("Missing or invalid 'user' option.")
25
26         self.user = options.user if options.user else os.getlogin()
27         self.movie =  options.movie
28         self.root_dir = tempfile.mkdtemp()
29
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"))
34         return tap
35
36     def add_ns3_fdnd(self, node, ns3_desc):
37         fdnd = ns3_desc.create("ns3::FdNetDevice")
38         node.connector("devs").connect(fdnd.connector("node"))
39         fdnd.enable_trace("FdPcapTrace")
40         return fdnd
41
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"))
52         return node
53
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"))
57
58         phy = ns3_desc.create("ns3::YansWifiPhy")
59         error = ns3_desc.create("ns3::NistErrorRateModel")
60         manager = ns3_desc.create("ns3::ArfWifiManager")
61         if access_point:
62             mac = ns3_desc.create("ns3::ApWifiMac")
63         else:
64             mac = ns3_desc.create("ns3::StaWifiMac")
65
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"))
72
73         phy.enable_trace("YansWifiPhyPcapTrace")
74         return wifi, phy
75
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"))
87         return mobility
88
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"))
94         return mobility
95
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"))
102         return channel
103
104     def add_ip_address(self, iface, address):
105         ip = iface.add_address()
106         ip.set_attribute_value("Address", address)
107
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)
113
114     def run(self):
115         bounds_width = bounds_height = 200
116         x = y = 100
117         speed = 7
118
119         exp_desc = ExperimentDescription()
120
121         ## NS3 Testbed instance description ##
122         testbed_id = "ns3"
123         ns3_provider = FactoriesProvider(testbed_id)
124         ns3_desc = exp_desc.add_testbed_description(ns3_provider)
125         ns3_desc.set_attribute_value("homeDirectory", self.root_dir)
126         ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
127         ns3_desc.set_attribute_value("ChecksumEnabled", True)
128         # create node 1
129         node1 = self.add_ns3_node(ns3_desc)
130         mobility1 = self.add_ns3_constant_mobility(node1, ns3_desc, x, y, 0)
131         wifi1, phy1 = self.add_ns3_wifi(node1, ns3_desc, access_point = False)
132         self.add_ip_address(wifi1, "10.0.1.1")
133         fdnd1 = self.add_ns3_fdnd(node1, ns3_desc)
134         self.add_ip_address(fdnd1, "10.0.0.1")
135         # create node 2
136         node2 = self.add_ns3_node(ns3_desc)
137         mobility2 = self.add_ns3_random_mobility(node2, ns3_desc, x, y, 0, 
138                 speed, bounds_width, bounds_height)
139         wifi2, phy2 = self.add_ns3_wifi(node2, ns3_desc, access_point = True)
140         self.add_ip_address(wifi2, "10.0.1.2")
141         fdnd2 = self.add_ns3_fdnd(node2, ns3_desc)
142         self.add_ip_address(fdnd2, "10.0.2.1")
143         # interconnect nodes with a wifi channel
144         wifichan = self.add_ns3_wifi_channel(ns3_desc)
145         phy1.connector("chan").connect(wifichan.connector("phys"))
146         phy2.connector("chan").connect(wifichan.connector("phys"))
147
148         ## NETNS testbed description 1 ##
149         testbed_id = "netns"
150         netns_provider = FactoriesProvider(testbed_id)
151         netns_desc1 = exp_desc.add_testbed_description(netns_provider)
152         netns_desc1.set_attribute_value("homeDirectory", self.root_dir)
153         #netns_desc1.set_attribute_value("enableDebug", True)
154         # create node 3
155         node3 = netns_desc1.create("Node")
156         node3.set_attribute_value("forward_X11", True)
157         tap1 = self.add_netns_tap(node3, netns_desc1)
158         self.add_ip_address(tap1, "10.0.0.2")
159         # create vlc server
160         # DEBUG!! target = "{#[vlc_client].addr[0].[Address]#}"
161         target = "10.0.2.2" 
162         command = "vlc -I dummy %s --sout '#rtp{dst=%s,port=5004,mux=ts}' vlc://quit" \
163                 % (self.movie, target)
164         vlc_server = netns_desc1.create("Application")
165         vlc_server.set_attribute_value("command", command)
166         vlc_server.set_attribute_value("user", self.user)
167         vlc_server.connector("node").connect(node3.connector("apps"))
168
169         #command = "xterm"
170         #xterm1 = netns_desc1.create("Application")
171         #xterm1.set_attribute_value("command", command)
172         #xterm1.set_attribute_value("user", self.user)
173         #xterm1.connector("node").connect(node3.connector("apps"))
174
175         ## NETNS testbed description 2 ##
176         netns_desc2 = exp_desc.add_testbed_description(netns_provider)
177         netns_desc2.set_attribute_value("homeDirectory", self.root_dir)
178         #netns_desc2.set_attribute_value("enableDebug", True)
179         # create node 4
180         node4 = netns_desc2.create("Node")
181         node4.set_attribute_value("forward_X11", True)
182         node4.set_attribute_value("label", "vlc_client")
183         tap2 = self.add_netns_tap(node4, netns_desc2)
184         self.add_ip_address(tap2, "10.0.2.2")
185         # create vlc client
186         vlc_client = netns_desc2.create("Application")
187         command = "vlc rtp://%s:5004/test.ts" % target
188         vlc_client.set_attribute_value("command", command)
189         vlc_client.set_attribute_value("user", self.user)
190         vlc_client.connector("node").connect(node4.connector("apps"))
191
192         #command = "xterm"
193         #xterm2 = netns_desc2.create("Application")
194         #xterm2.set_attribute_value("command", command)
195         #xterm2.set_attribute_value("user", self.user)
196         #xterm2.connector("node").connect(node4.connector("apps"))
197
198         ## testbed_interconnection
199         fdnd1.connector("->fd").connect(tap1.connector("fd->"))
200         fdnd2.connector("->fd").connect(tap2.connector("fd->"))
201       
202         self.add_route(node4, "10.0.0.0", 24, "10.0.2.1")
203         self.add_route(node4, "10.0.1.0", 24, "10.0.2.1")
204         self.add_route(node3, "10.0.2.0", 24, "10.0.0.1")
205         self.add_route(node3, "10.0.1.0", 24, "10.0.0.1")
206
207         self.add_route(node2, "10.0.0.0", 24, "10.0.1.1")
208         self.add_route(node1, "10.0.2.0", 24, "10.0.1.2")
209
210         xml = exp_desc.to_xml()
211         controller = ExperimentController(xml, self.root_dir)
212         controller.start()
213         while not controller.is_finished(vlc_server.guid) and \
214                 not controller.is_finished(vlc_client.guid):
215             time.sleep(0.5)
216         controller.stop()
217         controller.shutdown()
218
219     def clean(self):
220         shutil.rmtree(self.root_dir)
221
222 if __name__ == '__main__':
223     example = VlcWirelessNetnsNs3Example()
224     example.run()
225     example.clean()
226