a85ba0dc5b472242b84454c43a32a04e2bd83624
[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._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 dceapplications(self):
111         if not self._dceapplications:
112             from nepi.resources.ns3.ns3dceapplication import NS3BaseDceApplication
113             self._dceapplications = self.get_connected(NS3BaseDceApplication.get_rtype())
114
115         return self._dceapplications
116
117     @property
118     def _rms_to_wait(self):
119         rms = set()
120         rms.add(self.simulation)
121
122         ipv4 = self.ipv4
123         if ipv4:
124             rms.add(ipv4)
125
126         arp = self.arp
127         if arp:
128             rms.add(arp)
129
130         mobility = self.mobility
131         if mobility:
132             rms.add(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         dceapplications = self.dceapplications
157         if dceapplications:
158             self._add_dce(dceapplications)
159
160     def _connect_object(self):
161         if not self.get("enableStack"):
162             ipv4 = self.ipv4
163             if ipv4:
164                 self.simulation.invoke(self.uuid, "AggregateObject", ipv4.uuid)
165                 self._connected.add(ipv4.uuid)
166                 ipv4._connected.add(self.uuid)
167
168             arp = self.arp
169             if arp:
170                 self.simulation.invoke(self.uuid, "AggregateObject", arp.uuid)
171                 self._connected.add(arp.uuid)
172                 arp._connected.add(self.uuid)
173
174         mobility = self.mobility
175         if mobility:
176             self.simulation.invoke(self.uuid, "AggregateObject", mobility.uuid)
177             self._connected.add(mobility.uuid)
178             mobility._connected.add(self.uuid)
179
180     def _add_dce(self, dceapplications):
181         dceapp = dceapplications[0]
182
183         container_uuid = self.simulation.create("NodeContainer")
184         self.simulation.invoke(container_uuid, "Add", self.uuid)
185         with dceapp.dce_manager_lock:
186             self.simulation.invoke(dceapp.dce_manager_helper_uuid, 
187                     "Install", container_uuid)
188