applied the except and raise fixers to the master branch to close the gap with py3
[nepi.git] / src / nepi / resources / ns3 / ns3node.py
1 #
2 #    NEPI, a framework to manage network experiments
3 #    Copyright (C) 2014 INRIA
4 #
5 #    This program is free software: you can redistribute it and/or modify
6 #    it under the terms of the GNU General Public License version 2 as
7 #    published by the Free Software Foundation;
8 #
9 #    This program is distributed in the hope that it will be useful,
10 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #    GNU General Public License for more details.
13 #
14 #    You should have received a copy of the GNU General Public License
15 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 #
17 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
18
19 from nepi.execution.attribute import Attribute, Flags, Types
20 from nepi.execution.resource import clsinit_copy
21 from nepi.resources.ns3.ns3base import NS3Base
22
23 @clsinit_copy
24 class NS3BaseNode(NS3Base):
25     _rtype = "abstract::ns3::Node"
26
27     def __init__(self, ec, guid):
28         super(NS3BaseNode, self).__init__(ec, guid)
29         self._simulation = None
30         self._node_id = None
31         self._ipv4 = None
32         self._arp = None
33         self._mobility = None
34         self._devices = None
35         self._dceapplications = None
36
37     @classmethod
38     def _register_attributes(cls):
39         enablestack = Attribute("enableStack", 
40                 "Install network stack in Node, including: ARP, "
41                 "IP4, ICMP, UDP and TCP ",
42                 type = Types.Bool,
43                 default = False,
44                 flags = Flags.Design)
45
46         cls._register_attribute(enablestack)
47
48     @property
49     def simulation(self):
50         if not self._simulation:
51             from nepi.resources.ns3.ns3simulation import NS3Simulation
52             for guid in self.connections:
53                 rm = self.ec.get_resource(guid)
54                 if isinstance(rm, NS3Simulation):
55                     self._simulation = rm
56             
57             if not self._simulation:
58                 msg = "Node not connected to simulation"
59                 self.error(msg)
60                 raise RuntimeError(msg)
61
62         return self._simulation
63          
64     @property
65     def ipv4(self):
66         if not self._ipv4:
67             from nepi.resources.ns3.ns3ipv4l3protocol import NS3BaseIpv4L3Protocol
68             ipv4s = self.get_connected(NS3BaseIpv4L3Protocol.get_rtype())
69             if ipv4s: 
70                 self._ipv4 = ipv4s[0]
71         
72         return self._ipv4
73
74     @property
75     def arp(self):
76         if not self._arp:
77             from nepi.resources.ns3.ns3arpl3protocol import NS3BaseArpL3Protocol
78             arps = self.get_connected(NS3BaseArpL3Protocol.get_rtype())
79             if arps: 
80                 self._arp = arps[0]
81
82         return self._arp
83
84     @property
85     def mobility(self):
86         if not self._mobility:
87             from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel
88             mobility = self.get_connected(NS3BaseMobilityModel.get_rtype())
89             if mobility: 
90                 self._mobility = mobility[0]
91
92         return self._mobility
93
94     @property
95     def devices(self):
96         if not self._devices:
97             from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice
98             devices = self.get_connected(NS3BaseNetDevice.get_rtype())
99
100             if not devices: 
101                 msg = "Node not connected to devices"
102                 self.error(msg)
103                 raise RuntimeError(msg)
104
105             self._devices = devices
106
107         return self._devices
108
109     @property
110     def node_id(self):
111         return self._node_id
112
113     @property
114     def dceapplications(self):
115         if not self._dceapplications:
116             from nepi.resources.ns3.ns3dceapplication import NS3BaseDceApplication
117             self._dceapplications = self.get_connected(NS3BaseDceApplication.get_rtype())
118
119         return self._dceapplications
120
121     @property
122     def _rms_to_wait(self):
123         rms = set([self.simulation])
124
125         if self.ipv4:
126             rms.add(self.ipv4)
127
128         if self.arp:
129             rms.add(self.arp)
130
131         if self.mobility:
132             rms.add(self.mobility)
133
134         return rms
135
136     def _configure_object(self):
137         if self.get("enableStack"):
138             uuid_stack_helper = self.simulation.create("InternetStackHelper")
139             self.simulation.invoke(uuid_stack_helper, "Install", self.uuid)
140
141             # Retrieve IPV4 object
142             ipv4_uuid = self.simulation.invoke(self.uuid, "retrieveObject",
143                     "ns3::Ipv4L3Protocol")
144             
145             # Add IPv4 RM to the node
146             ipv4 = self.ec.register_resource("ns3::Ipv4L3Protocol")
147             self.ec.register_connection(self.guid, ipv4)
148             ipv4rm = self.ec.get_resource(ipv4)
149             ipv4rm._uuid = ipv4_uuid
150             ipv4rm.set_started()
151         else:
152             ### node.AggregateObject(PacketSocketFactory())
153             uuid_packet_socket_factory = self.simulation.create("PacketSocketFactory")
154             self.simulation.invoke(self.uuid, "AggregateObject", uuid_packet_socket_factory)
155
156         self._node_id = self.simulation.invoke(self.uuid, "GetId")
157         
158         dceapplications = self.dceapplications
159         if dceapplications:
160             self._add_dce(dceapplications)
161
162     def _connect_object(self):
163         if not self.get("enableStack"):
164             ipv4 = self.ipv4
165             if ipv4:
166                 self.simulation.invoke(self.uuid, "AggregateObject", ipv4.uuid)
167                 self._connected.add(ipv4.uuid)
168                 ipv4._connected.add(self.uuid)
169
170             arp = self.arp
171             if arp:
172                 self.simulation.invoke(self.uuid, "AggregateObject", arp.uuid)
173                 self._connected.add(arp.uuid)
174                 arp._connected.add(self.uuid)
175
176         mobility = self.mobility
177         if mobility:
178             self.simulation.invoke(self.uuid, "AggregateObject", mobility.uuid)
179             self._connected.add(mobility.uuid)
180             mobility._connected.add(self.uuid)
181
182     def _add_dce(self, dceapplications):
183         dceapp = dceapplications[0]
184
185         container_uuid = self.simulation.create("NodeContainer")
186         self.simulation.invoke(container_uuid, "Add", self.uuid)
187         
188         dce_helper = self.simulation.dce_helper
189
190         with dce_helper.dce_manager_lock:
191             dce_manager_uuid = dce_helper.dce_manager_uuid
192
193             self.simulation.invoke(dce_manager_uuid, "Install", container_uuid)
194