ns3 metadata and design test in progress
[nepi.git] / src / nepi / testbeds / ns3 / execute.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 from constants import TESTBED_ID
5 from nepi.core import testbed_impl
6 from nepi.core.attributes import Attribute
7 from nepi.util.constants import AF_INET, AF_INET6
8 import os
9
10 class TestbedInstance(testbed_impl.TestbedInstance):
11     def __init__(self, testbed_version):
12         super(TestbedInstance, self).__init__(TESTBED_ID, testbed_version)
13         self._ns3 = None
14         self._home_directory = None
15         self._traces = dict()
16
17     @property
18     def home_directory(self):
19         return self._home_directory
20
21     @property
22     def ns3(self):
23         return self._ns3
24
25     def do_setup(self):
26         self._home_directory = self._attributes.\
27             get_attribute_value("homeDirectory")
28         self._ns3 = self._load_ns3_module()
29
30     def do_configure(self):
31         # configure addressess
32         for guid, addresses in self._add_address.iteritems():
33             element = self._elements[guid]
34             for address in addresses:
35                 (family, address, netprefix, broadcast) = address
36                 if family == AF_INET:
37                     pass
38                     # TODO!!!
39         # configure routes
40         for guid, routes in self._add_route.iteritems():
41             element = self._elements[guid]
42             for route in routes:
43                 (destination, netprefix, nexthop) = route
44                 # TODO!!
45         """
46         context = self.server.modules.ns3
47         ipv4 = self._object
48         for interface in self._interface2addr:
49             ifindex = ipv4.AddInterface(interface._object)
50             for addr in self._interface2addr[interface]:
51                 inaddr = context.Ipv4InterfaceAddress(
52                         context.Ipv4Address(
53                             addr.get_attribute("Address").value),
54                         context.Ipv4Mask(
55                             addr.get_attribute("NetPrefix").value))
56                 ipv4.AddAddress(ifindex, inaddr)
57                 ipv4.SetMetric(ifindex, 1)
58                 ipv4.SetUp(ifindex)
59                 self._interface_addrs[addr] = inaddr
60                 self._interfaces[interface] = ifindex
61         for entry in self.get_node().routing_table.get_entries(self._af):
62             self._rt_add(entry)
63
64         def _rt_add(self, entry):
65         # Called both at install-time (by NS3Ipv4Stack.post_install) and at
66         # run-time (by RoutingTable.add_entry).
67         context = self.server.modules.ns3
68         ifindex = self._interfaces[entry.interface]
69         prefixlen = entry.prefixlen
70         # print "rt_add %s %s %s %d"% (prefix, prefixlen, entry.nexthop, ifindex)        
71         if entry.nexthop:
72             self._static_routing.AddNetworkRouteTo(
73                     context.Ipv4Address(entry.prefix.address),
74                     context.Ipv4Mask(entry.mask.address),
75                     context.Ipv4Address(entry.nexthop.address),
76                     ifindex)
77         else:
78             self._static_routing.AddNetworkRouteTo(
79                     context.Ipv4Address(entry.prefix.address),
80                     context.Ipv4Mask(entry.mask.address),
81                     ifindex)
82         """
83
84     def set(self, time, guid, name, value):
85         super(TestbedInstance, self).set(time, guid, name, value)
86         # TODO: take on account schedule time for the task
87         factory_id = self._crerate[guid]
88         element = self._elements[guid]
89         TypeId = self.ns3.TypeId()
90         typeid = TypeId.LookupByName(factory_id)
91         info = TypeId.AttributeInfo()
92         if not typeid.LookupAttributeByName(name, info):
93             raise RuntimeError("Attribute %s doesn't belong to element %s" \
94                    % (name, factory_id))
95         value = str(value)
96         if isinstance(value, bool):
97             value = value.lower()
98         ns3_value = info.checker.Create()
99         ns3_value.DeserializeFromString(value, checker)
100         element.SetAttribute(name, ns3_value)
101
102     def get(self, time, guid, name):
103         # TODO: take on account schedule time for the task
104         TypeId = self.ns3.TypeId()
105         typeid = TypeId.LookupByName(factory_id)
106         info = TypeId.AttributeInfo()
107         if not typeid.LookupAttributeByName(name, info):
108             raise RuntimeError("Attribute %s doesn't belong to element %s" \
109                    % (name, factory_id))
110         checker = info.checker
111         ns3_value = checker.Create() 
112         element = self._elements[guid]
113         element.GetAttribute(name, ns3_value)
114         value = ns3_value.SerializeToString(checker)
115         factory_id = self._create[guid]
116         factory = self._factories[factory_id]
117         attr_type = factory.box_attributes.get_attribute_type(name)
118         if attr_type == Attribute.INTEGER:
119             return int(value)
120         if attr_type == Attribute.DOUBLE:
121             return float(value)
122         if attr_type == Attribute.BOOL:
123             return value == "true"
124         return value
125
126     def action(self, time, guid, action):
127         raise NotImplementedError
128
129     def trace(self, guid, trace_id):
130         fd = open("%s" % self.trace_filename(guid, trace_id), "r")
131         content = fd.read()
132         fd.close()
133         return content
134
135     def shutdown(self):
136         for element in self._elements.values():
137             element.destroy()
138
139     def trace_filename(self, guid, trace_id):
140         # TODO: Need to be defined inside a home!!!! with and experiment id_code
141         filename = self._trace_filenames[guid][trace_id]
142         return os.path.join(self.home_directory, filename)
143
144     def follow_trace(self, guid, trace_id, filename):
145         if guid not in self._traces:
146             self._traces[guid] = dict()
147         self._traces[guid][trace_id] = filename
148
149     def _load_ns3_module(self):
150         import ctypes
151         import imp
152
153         bindings = self._attributes.get_attribute_value("ns3Bindings")
154         libfile = self._attributes.get_attribute_value("ns3Library")
155         simu_impl_type = self._attributes.get_attribute_value(
156                 "SimulatorImplementationType")
157         checksum = self._attributes.get_attribute_value("ChecksumEnabled")
158
159         if libfile:
160             ctypes.CDLL(libfile, ctypes.RTLD_GLOBAL)
161
162         path = [ os.path.dirname(__file__) ] + sys.path
163         if bindings:
164             path = [ bindings ] + path
165
166         module = imp.find_module ('ns3', path)
167         mod = imp.load_module ('ns3', *module)
168     
169         if simu_impl_type:
170             value = mod.StringValue(simu_impl_type)
171             mod.GlobalValue.Bind ("SimulatorImplementationType", value)
172         if checksum:
173             value = mod.BooleanValue(checksum)
174             mod.GlobalValue.Bind ("ChecksumEnabled", value)
175         return mod
176
177     def _get_construct_parameters(self, guid):
178         params = self._get_parameters(guid)
179         construct_params = dict()
180         factory_id = self._create[guid]
181         TypeId = self.ns3.TypeId()
182         typeid = TypeId.LookupByName(factory_id)
183         for name, value in params:
184             info = self.ns3.TypeId.AttributeInfo()
185             typeid.LookupAttributeByName(name, info)
186             if info.flags & TypeId.ATTR_CONSTRUCT == TypeId.ATTR_CONSTRUCT:
187                 construct_params[name] = value
188         return construct_params
189