9a5ae4c62ba20900915b4d585e7642ec9fd3df62
[nepi.git] / examples / vlc_wireless_netns_ns3.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 import getpass
5 from nepi.core.design import ExperimentDescription, FactoriesProvider
6 from nepi.core.execute import ExperimentController
7 from nepi.util import proxy
8 import os
9 import shutil
10 import tempfile
11 import test_util
12 import time
13 import unittest
14
15 class VlcWirelessNetnsNs3TestCase(unittest.TestCase):
16     def setUp(self):
17         self.root_dir = tempfile.mkdtemp()
18
19     def add_netns_tap(self, node, netns_desc):
20         tap = netns_desc.create("TapNodeInterface")
21         tap.set_attribute_value("up", True)
22         node.connector("devs").connect(tap.connector("node"))
23         return tap
24
25     def add_ns3_fdnd(self, node, ns3_desc):
26         fdnd = ns3_desc.create("ns3::FileDescriptorNetDevice")
27         node.connector("devs").connect(fdnd.connector("node"))
28         fdnd.enable_trace("FileDescriptorPcapTrace")
29         return fdnd
30
31     def add_ns3_node(self, ns3_desc):
32         node = ns3_desc.create("ns3::Node")
33         ipv4 = ns3_desc.create("ns3::Ipv4L3Protocol")
34         arp  = ns3_desc.create("ns3::ArpL3Protocol")
35         icmp = ns3_desc.create("ns3::Icmpv4L4Protocol")
36         udp = ns3_desc.create("ns3::UdpL4Protocol")
37         node.connector("protos").connect(ipv4.connector("node"))
38         node.connector("protos").connect(arp.connector("node"))
39         node.connector("protos").connect(icmp.connector("node"))
40         node.connector("protos").connect(udp.connector("node"))
41         return node
42
43     def add_ns3_wifi(self, node, ns3_desc, access_point = False):
44         wifi = ns3_desc.create("ns3::WifiNetDevice")
45         node.connector("devs").connect(wifi.connector("node"))
46
47         phy = ns3_desc.create("ns3::YansWifiPhy")
48         error = ns3_desc.create("ns3::NistErrorRateModel")
49         manager = ns3_desc.create("ns3::ArfWifiManager")
50         if access_point:
51             mac = ns3_desc.create("ns3::QapWifiMac")
52         else:
53             mac = ns3_desc.create("ns3::QstaWifiMac")
54
55         phy.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
56         mac.set_attribute_value("Standard", "WIFI_PHY_STANDARD_80211a")
57         phy.connector("err").connect(error.connector("phy"))
58         wifi.connector("phy").connect(phy.connector("dev"))
59         wifi.connector("mac").connect(mac.connector("dev"))
60         wifi.connector("manager").connect(manager.connector("dev"))
61
62         phy.enable_trace("YansWifiPhyPcapTrace")
63         return wifi, phy
64
65     def add_ns3_random_mobility(self, node, ns3_desc, x, y, z, speed, 
66             bounds_width, bounds_height):
67         position = "%d:%d:%d" % (x, y, z)
68         bounds = "0|%d|0|%d" % (bounds_width, bounds_height) 
69         speed = "Constant:%d" % speed
70         mobility = ns3_desc.create("ns3::RandomDirection2dMobilityModel")
71         mobility.set_attribute_value("Position", position)
72         mobility.set_attribute_value("Bounds", bounds)
73         mobility.set_attribute_value("Speed", speed)
74         mobility.set_attribute_value("Pause",  "Constant:1")
75         node.connector("mobility").connect(mobility.connector("node"))
76         return mobility
77
78     def add_ns3_constant_mobility(self, node, ns3_desc, x, y, z):
79         mobility = ns3_desc.create("ns3::ConstantPositionMobilityModel") 
80         position = "%d:%d:%d" % (x, y, z)
81         mobility.set_attribute_value("Position", position)
82         node.connector("mobility").connect(mobility.connector("node"))
83         return mobility
84
85     def add_ns3_wifi_channel(self, ns3_desc):
86         channel = ns3_desc.create("ns3::YansWifiChannel")
87         delay = ns3_desc.create("ns3::ConstantSpeedPropagationDelayModel")
88         loss  = ns3_desc.create("ns3::LogDistancePropagationLossModel")
89         channel.connector("delay").connect(delay.connector("chan"))
90         channel.connector("loss").connect(loss.connector("prev"))
91         return channel
92
93     def add_ip_address(self, iface, address):
94         ip = iface.add_address()
95         ip.set_attribute_value("Address", address)
96
97     def add_route(self, node, destination, netprefix, nexthop):
98         route = node.add_route()
99         route.set_attribute_value("Destination", destination)
100         route.set_attribute_value("NetPrefix", netprefix)
101         route.set_attribute_value("NextHop", nexthop)
102
103     @test_util.skipUnless(os.getuid() == 0, "Test requires root privileges")
104     def test_local(self):
105         bounds_width = bounds_height = 200
106         x = y = 100
107         speed = 1
108         user = "alina"
109         movie = "/tmp/test.ts"
110
111         exp_desc = ExperimentDescription()
112
113         ## NS3 Testbed instance description ##
114         testbed_version = "3_9_RC3"
115         testbed_id = "ns3"
116         ns3_provider = FactoriesProvider(testbed_id, testbed_version)
117         ns3_desc = exp_desc.add_testbed_description(ns3_provider)
118         ns3_desc.set_attribute_value("homeDirectory", self.root_dir)
119         ns3_desc.set_attribute_value("SimulatorImplementationType", "ns3::RealtimeSimulatorImpl")
120         ns3_desc.set_attribute_value("ChecksumEnabled", True)
121         # create node 1
122         node1 = self.add_ns3_node(ns3_desc)
123         mobility1 = self.add_ns3_constant_mobility(node1, ns3_desc, x, y, 0)
124         wifi1, phy1 = self.add_ns3_wifi(node1, ns3_desc, access_point = False)
125         self.add_ip_address(wifi1, "10.0.1.1")
126         fdnd1 = self.add_ns3_fdnd(node1, ns3_desc)
127         self.add_ip_address(fdnd1, "10.0.0.1")
128         # create node 2
129         node2 = self.add_ns3_node(ns3_desc)
130         mobility2 = self.add_ns3_random_mobility(node2, ns3_desc, 0, 0, 0, 
131                 speed, bounds_width, bounds_height)
132         wifi2, phy2 = self.add_ns3_wifi(node2, ns3_desc, access_point = True)
133         self.add_ip_address(wifi2, "10.0.1.2")
134         fdnd2 = self.add_ns3_fdnd(node2, ns3_desc)
135         self.add_ip_address(fdnd2, "10.0.2.1")
136         # interconnect nodes with a wifi channel
137         wifichan = self.add_ns3_wifi_channel(ns3_desc)
138         phy1.connector("chan").connect(wifichan.connector("phys"))
139         phy2.connector("chan").connect(wifichan.connector("phys"))
140
141         ## NETNS testbed description 1 ##
142         testbed_version = "01"
143         testbed_id = "netns"
144         netns_provider = FactoriesProvider(testbed_id, testbed_version)
145         netns_desc1 = exp_desc.add_testbed_description(netns_provider)
146         netns_desc1.set_attribute_value("homeDirectory", self.root_dir)
147         #netns_desc1.set_attribute_value("enableDebug", True
148         # create node 3
149         node3 = netns_desc1.create("Node")
150         node3.set_attribute_value("forward_X11", True)
151         tap1 = self.add_netns_tap(node3, netns_desc1)
152         self.add_ip_address(tap1, "10.0.0.2")
153         # create vlc server
154         # DEBUG!! target = "{#[vlc_client].addr[0].[Address]#}"
155         target = "10.0.2.2" 
156         command = "vlc -I dummy -vvv %s --sout '#rtp{dst=%s,port=5004,mux=ts}' vlc:quit" \
157                 % (movie, target)
158         vlc_server = netns_desc1.create("Application")
159         vlc_server.set_attribute_value("command", command)
160         vlc_server.set_attribute_value("user", user)
161         vlc_server.connector("node").connect(node3.connector("apps"))
162
163         #command = "xterm"
164         #xterm1 = netns_desc1.create("Application")
165         #xterm1.set_attribute_value("command", command)
166         #xterm1.set_attribute_value("user", user)
167         #xterm1.connector("node").connect(node3.connector("apps"))
168
169         ## NETNS testbed description 2 ##
170         netns_desc2 = exp_desc.add_testbed_description(netns_provider)
171         netns_desc2.set_attribute_value("homeDirectory", self.root_dir)
172         #netns_desc2.set_attribute_value("enableDebug", True)
173         # create node 4
174         node4 = netns_desc2.create("Node")
175         node4.set_attribute_value("forward_X11", True)
176         node4.set_attribute_value("label", "vlc_client")
177         tap2 = self.add_netns_tap(node4, netns_desc2)
178         self.add_ip_address(tap2, "10.0.2.2")
179         # create vlc client
180         vlc_client = netns_desc2.create("Application")
181         command = "vlc rtp://%s:5004/test.ts" % target
182         vlc_client.set_attribute_value("command", command)
183         vlc_client.set_attribute_value("user", user)
184         vlc_client.connector("node").connect(node4.connector("apps"))
185         #vlc_trace = vlc_server.get_trace("StderrTrace")
186         #vlc_trace.get_attribute("Filename").value = "vlc_server.err"
187         #vlc_trace.enable()        
188
189         #command = "xterm"
190         #xterm2 = netns_desc2.create("Application")
191         #xterm2.set_attribute_value("command", command)
192         #xterm2.set_attribute_value("user", user)
193         #xterm2.connector("node").connect(node4.connector("apps"))
194
195         ## testbed_interconnection
196         fdnd1.connector("fd").connect(tap1.connector("fd"))
197         fdnd2.connector("fd").connect(tap2.connector("fd"))
198       
199         self.add_route(node4, "10.0.0.0", 24, "10.0.2.1")
200         self.add_route(node4, "10.0.1.0", 24, "10.0.2.1")
201         self.add_route(node3, "10.0.2.0", 24, "10.0.0.1")
202         self.add_route(node3, "10.0.1.0", 24, "10.0.0.1")
203
204         self.add_route(node2, "10.0.0.0", 24, "10.0.1.1")
205         self.add_route(node1, "10.0.2.0", 24, "10.0.1.2")
206
207
208         xml = exp_desc.to_xml()
209         controller = ExperimentController(xml, self.root_dir)
210         controller.start()
211         while not controller.is_finished(vlc_server.guid):
212             time.sleep(0.5)
213         controller.stop()
214         controller.shutdown()
215
216     def tearDown(self):
217         shutil.rmtree(self.root_dir)
218
219 if __name__ == '__main__':
220     unittest.main()