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