2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
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.
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.
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/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19 # Julien Tribino <julien.tribino@inria.fr>
22 from nepi.util.timefuncs import tnow
23 from nepi.execution.resource import ResourceManager, clsinit_copy, \
24 ResourceState, reschedule_delay
25 from nepi.execution.attribute import Attribute, Flags
27 from nepi.resources.omf.node import OMFNode, confirmation_counter, reschedule_check
28 from nepi.resources.omf.omf_resource import ResourceGateway, OMFResource
29 from nepi.resources.omf.channel import OMFChannel
30 from nepi.resources.omf.omf_api_factory import OMFAPIFactory
33 class OMFWifiInterface(OMFResource):
35 .. class:: Class Args :
37 :param ec: The Experiment controller
38 :type ec: ExperimentController
39 :param guid: guid of the RM
43 _rtype = "OMFWifiInterface"
44 _authorized_connections = ["OMFNode" , "OMFChannel", "WilabtSfaNode"]
47 def _register_attributes(cls):
48 """Register the attributes of an OMF interface
51 name = Attribute("name","Alias of the interface : wlan0, wlan1, ..", default = "wlan0")
52 mode = Attribute("mode","Mode of the interface")
53 hw_mode = Attribute("hw_mode","Choose between : a, b, g, n")
54 essid = Attribute("essid","Essid of the interface")
55 ip = Attribute("ip","IP of the interface")
56 cls._register_attribute(name)
57 cls._register_attribute(mode)
58 cls._register_attribute(hw_mode)
59 cls._register_attribute(essid)
60 cls._register_attribute(ip)
62 def __init__(self, ec, guid):
64 :param ec: The Experiment controller
65 :type ec: ExperimentController
66 :param guid: guid of the RM
68 :param creds: Credentials to communicate with the rm (XmppClient for OMF)
72 super(OMFWifiInterface, self).__init__(ec, guid)
80 self.release_id = None
82 self._topic_iface = None
86 # For performance tests
88 self.begin_deploy_time = None
90 def valid_connection(self, guid):
91 """ Check if the connection with the guid in parameter is possible.
92 Only meaningful connections are allowed.
94 :param guid: Guid of the current RM
99 rm = self.ec.get_resource(guid)
100 if rm.get_rtype() in self._authorized_connections:
101 msg = "Connection between %s %s and %s %s accepted" % \
102 (self.get_rtype(), self._guid, rm.get_rtype(), guid)
106 msg = "Connection between %s %s and %s %s refused" % \
107 (self.get_rtype(), self._guid, rm.get_rtype(), guid)
113 return self.ec.exp_id
117 rm_list = self.get_connected(OMFNode.get_rtype())
118 if rm_list: return rm_list[0]
123 rm_list = self.get_connected(OMFChannel.get_rtype())
124 if rm_list: return rm_list[0]
127 def configure_iface(self):
128 """ Configure the interface without the ip
131 if self.node.state < ResourceState.READY:
132 self.ec.schedule(reschedule_delay, self.deploy)
135 for attrname in ["mode", "type", "essid"]:
136 if attrname == "type" :
139 attrval = self.get(attrname)
140 attrname = "net/%s/%s" % (self.alias, attrname)
141 self._omf_api.configure(self.node.get('hostname'), attrname,
144 super(OMFWifiInterface, self).do_provision()
147 def configure_ip(self):
148 """ Configure the ip of the interface
150 .. note : The ip is separated from the others parameters to avoid
151 CELL ID shraing problem. By putting th ip at the end of the configuration,
152 each node use the same channel and can then share the same CELL ID.
153 In the second case, the channel is defined at the end and the node don't
154 share a common CELL ID and can not communicate.
157 if self.channel.state < ResourceState.READY:
158 self.ec.schedule(reschedule_delay, self.deploy)
161 attrval = self.get("ip")
163 attrval,mask = attrval.split('/')
164 attrname = "net/%s/%s" % (self.alias, "ip")
165 self._omf_api.configure(self.node.get('hostname'), attrname,
170 def configure_on_omf5(self):
171 """ Method to configure the wifi interface when OMF 5.4 is used.
175 self._type = self.get('hw_mode')
176 if self.get('name') == "wlan0" or "eth0":
181 if self.state < ResourceState.PROVISIONED:
182 if self._conf == False:
183 self._conf = self.configure_iface()
184 if self._conf == True:
185 res = self.configure_ip()
188 def check_deploy(self, cid):
189 """ Check, through the mail box in the parser,
190 if the confirmation of the creation has been received
192 :param cid: the id of the original message
196 uid = self._omf_api.check_mailbox("create", cid)
202 """ Deploy the RM. It means : Get the xmpp client and send messages
203 using OMF 5.4 or 6 protocol to configure the interface.
206 if not self.node or self.node.state < ResourceState.READY:
207 self.debug("---- RESCHEDULING DEPLOY ---- node state %s "
209 self.ec.schedule(reschedule_delay, self.deploy)
212 if not self.channel or self.channel.state < ResourceState.READY:
213 self.debug("---- RESCHEDULING DEPLOY ---- channel state %s "
214 % self.channel.state )
215 self.ec.schedule(reschedule_delay, self.deploy)
218 ## For performance test
220 self.begin_deploy_time = tnow()
223 self.set('xmppUser',self.node.get('xmppUser'))
224 self.set('xmppServer',self.node.get('xmppServer'))
225 self.set('xmppPort',self.node.get('xmppPort'))
226 self.set('xmppPassword',self.node.get('xmppPassword'))
227 self.set('version',self.node.get('version'))
229 if not self.get('xmppServer'):
230 msg = "XmppServer is not initialzed. XMPP Connections impossible"
232 raise RuntimeError, msg
234 if not (self.get('xmppUser') or self.get('xmppPort')
235 or self.get('xmppPassword')):
236 msg = "Credentials are not all initialzed. Default values will be used"
239 if not self._omf_api :
240 self._omf_api = OMFAPIFactory.get_api(self.get('version'),
241 self.get('xmppServer'), self.get('xmppUser'), self.get('xmppPort'),
242 self.get('xmppPassword'), exp_id = self.exp_id)
244 if not (self.get('name')):
245 msg = "Interface's name is not initialized"
247 raise RuntimeError, msg
249 if not (self.get('mode') and self.get('essid') \
250 and self.get('hw_mode') and self.get('ip')):
251 msg = "Interface's variable are not initialized"
253 raise RuntimeError, msg
255 if self.get('version') == "5":
256 res = self.configure_on_omf5()
259 res = self.configure_on_omf6()
262 super(OMFWifiInterface, self).do_deploy()
264 def configure_on_omf6(self):
265 """ Method to configure the wifi interface when OMF 6 is used.
268 if not self.create_id :
270 props['wlan:if_name'] = self.get('name')
271 props['wlan:mode'] = {
272 "mode": self.get('mode'),
273 "hw_mode" : self.get('hw_mode'),
274 "channel" : self.channel.get('channel'),
275 "essid" : self.get('essid'),
276 "ip_addr" : self.get('ip'),
277 "frequency" : self.channel.frequency,
280 props['wlan:hrn'] = self.get('name')
281 props['wlan:type'] = "wlan"
283 self.create_id = os.urandom(16).encode('hex')
284 self._omf_api.frcp_create( self.create_id, self.node.get('hostname'), "wlan", props = props)
286 if self._create_cnt > confirmation_counter:
287 msg = "Couldn't retrieve the confirmation of the creation"
289 raise RuntimeError, msg
291 uid = self.check_deploy(self.create_id)
294 self.ec.schedule(reschedule_check, self.deploy)
297 self._topic_iface = uid
298 self._omf_api.enroll_topic(self._topic_iface)
301 def check_release(self, cid):
302 """ Check, through the mail box in the parser,
303 if the confirmation of the release has been received
305 :param cid: the id of the original message
309 res = self._omf_api.check_mailbox("release", cid)
314 def do_release(self):
315 """ Clean the RM at the end of the experiment and release the API
319 if self.get('version') == "6" and self._topic_iface :
320 if not self.release_id:
321 self.release_id = os.urandom(16).encode('hex')
322 self._omf_api.frcp_release( self.release_id, self.node.get('hostname'),self._topic_iface, res_id=self._topic_iface)
324 if self._release_cnt < confirmation_counter:
325 cid = self.check_release(self.release_id)
327 self._release_cnt +=1
328 self.ec.schedule(reschedule_check, self.release)
331 msg = "Couldn't retrieve the confirmation of the release"
335 OMFAPIFactory.release_api(self.get('version'),
336 self.get('xmppServer'), self.get('xmppUser'), self.get('xmppPort'),
337 self.get('xmppPassword'), exp_id = self.exp_id)
339 super(OMFWifiInterface, self).do_release()