2d14b85635bb4e2020678b9253a0a2c209fccd57
[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()
125         rms.add(self.simulation)
126
127         ipv4 = self.ipv4
128         if ipv4:
129             rms.add(ipv4)
130
131         arp = self.arp
132         if arp:
133             rms.add(arp)
134
135         mobility = self.mobility
136         if mobility:
137             rms.add(mobility)
138
139         return rms
140
141     def _configure_object(self):
142         if self.get("enableStack"):
143             uuid_stack_helper = self.simulation.create("InternetStackHelper")
144             self.simulation.invoke(uuid_stack_helper, "Install", self.uuid)
145
146             # Retrieve IPV4 object
147             ipv4_uuid = self.simulation.invoke(self.uuid, "retrieveObject",
148                     "ns3::Ipv4L3Protocol")
149             
150             # Add IPv4 RM to the node
151             ipv4 = self.ec.register_resource("ns3::Ipv4L3Protocol")
152             self.ec.register_connection(self.guid, ipv4)
153             ipv4rm = self.ec.get_resource(ipv4)
154             ipv4rm._uuid = ipv4_uuid
155             ipv4rm.set_started()
156         else:
157             ### node.AggregateObject(PacketSocketFactory())
158             uuid_packet_socket_factory = self.simulation.create("PacketSocketFactory")
159             self.simulation.invoke(self.uuid, "AggregateObject", uuid_packet_socket_factory)
160
161         self._node_id = self.simulation.invoke(self.uuid, "GetId")
162         
163         dceapplications = self.dceapplications
164         if dceapplications:
165             self._add_dce(dceapplications)
166
167     def _connect_object(self):
168         if not self.get("enableStack"):
169             ipv4 = self.ipv4
170             if ipv4:
171                 self.simulation.invoke(self.uuid, "AggregateObject", ipv4.uuid)
172                 self._connected.add(ipv4.uuid)
173                 ipv4._connected.add(self.uuid)
174
175             arp = self.arp
176             if arp:
177                 self.simulation.invoke(self.uuid, "AggregateObject", arp.uuid)
178                 self._connected.add(arp.uuid)
179                 arp._connected.add(self.uuid)
180
181         mobility = self.mobility
182         if mobility:
183             self.simulation.invoke(self.uuid, "AggregateObject", mobility.uuid)
184             self._connected.add(mobility.uuid)
185             mobility._connected.add(self.uuid)
186
187     def _add_dce(self, dceapplications):
188         dceapp = dceapplications[0]
189
190         container_uuid = self.simulation.create("NodeContainer")
191         self.simulation.invoke(container_uuid, "Add", self.uuid)
192         with dceapp.dce_manager_lock:
193             self.simulation.invoke(dceapp.dce_manager_helper_uuid, 
194                     "Install", container_uuid)
195