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 version 2 as
7 # published by the Free Software Foundation;
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.
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/>.
17 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
18 # Julien Tribino <julien.tribino@inria.fr>
21 from nepi.util.timefuncs import tnow
22 from nepi.execution.resource import ResourceManager, clsinit_copy, \
24 from nepi.execution.attribute import Attribute, Flags
26 from nepi.resources.omf.node import OMFNode, confirmation_counter, reschedule_check
27 from nepi.resources.omf.omf_resource import ResourceGateway, OMFResource
28 from nepi.resources.omf.channel import OMFChannel
29 from nepi.resources.omf.omf_api_factory import OMFAPIFactory
32 class OMFWifiInterface(OMFResource):
34 .. class:: Class Args :
36 :param ec: The Experiment controller
37 :type ec: ExperimentController
38 :param guid: guid of the RM
42 _rtype = "omf::WifiInterface"
43 _authorized_connections = ["omf::Node" , "omf::Channel", "wilabt::sfa::Node"]
46 def _register_attributes(cls):
47 """Register the attributes of an OMF interface
50 name = Attribute("name","Alias of the interface : wlan0, wlan1, ..", default = "wlan0")
51 mode = Attribute("mode","Mode of the interface")
52 hw_mode = Attribute("hw_mode","Choose between : a, b, g, n")
53 essid = Attribute("essid","Essid of the interface")
54 ip = Attribute("ip","IP of the interface")
55 cls._register_attribute(name)
56 cls._register_attribute(mode)
57 cls._register_attribute(hw_mode)
58 cls._register_attribute(essid)
59 cls._register_attribute(ip)
61 def __init__(self, ec, guid):
63 :param ec: The Experiment controller
64 :type ec: ExperimentController
65 :param guid: guid of the RM
67 :param creds: Credentials to communicate with the rm (XmppClient for OMF)
71 super(OMFWifiInterface, self).__init__(ec, guid)
79 self.release_id = None
81 self._topic_iface = None
85 # For performance tests
87 self.begin_deploy_time = None
89 def valid_connection(self, guid):
90 """ Check if the connection with the guid in parameter is possible.
91 Only meaningful connections are allowed.
93 :param guid: Guid of the current RM
98 rm = self.ec.get_resource(guid)
99 if rm.get_rtype() in self._authorized_connections:
100 msg = "Connection between %s %s and %s %s accepted" % \
101 (self.get_rtype(), self._guid, rm.get_rtype(), guid)
105 msg = "Connection between %s %s and %s %s refused" % \
106 (self.get_rtype(), self._guid, rm.get_rtype(), guid)
112 return self.ec.exp_id
116 rm_list = self.get_connected(OMFNode.get_rtype())
117 if rm_list: return rm_list[0]
122 rm_list = self.get_connected(OMFChannel.get_rtype())
123 if rm_list: return rm_list[0]
126 def configure_iface(self):
127 """ Configure the interface without the ip
130 if self.node.state < ResourceState.READY:
131 self.ec.schedule(self.reschedule_delay, self.deploy)
134 for attrname in ["mode", "type", "essid"]:
135 if attrname == "type" :
138 attrval = self.get(attrname)
139 attrname = "net/%s/%s" % (self.alias, attrname)
140 self._omf_api.configure(self.node.get('hostname'), attrname,
143 super(OMFWifiInterface, self).do_provision()
146 def configure_ip(self):
147 """ Configure the ip of the interface
149 .. note : The ip is separated from the others parameters to avoid
150 CELL ID shraing problem. By putting th ip at the end of the configuration,
151 each node use the same channel and can then share the same CELL ID.
152 In the second case, the channel is defined at the end and the node don't
153 share a common CELL ID and can not communicate.
156 if self.channel.state < ResourceState.READY:
157 self.ec.schedule(self.reschedule_delay, self.deploy)
160 attrval = self.get("ip")
162 attrval,mask = attrval.split('/')
163 attrname = "net/%s/%s" % (self.alias, "ip")
164 self._omf_api.configure(self.node.get('hostname'), attrname,
169 def configure_on_omf5(self):
170 """ Method to configure the wifi interface when OMF 5.4 is used.
174 self._type = self.get('hw_mode')
175 if self.get('name') == "wlan0" or "eth0":
180 if self.state < ResourceState.PROVISIONED:
181 if self._conf == False:
182 self._conf = self.configure_iface()
183 if self._conf == True:
184 res = self.configure_ip()
187 def check_deploy(self, cid):
188 """ Check, through the mail box in the parser,
189 if the confirmation of the creation has been received
191 :param cid: the id of the original message
195 uid = self._omf_api.check_mailbox("create", cid)
201 """ Deploy the RM. It means : Get the xmpp client and send messages
202 using OMF 5.4 or 6 protocol to configure the interface.
205 if not self.node or self.node.state < ResourceState.READY:
206 self.debug("---- RESCHEDULING DEPLOY ---- node state %s "
208 self.ec.schedule(self.reschedule_delay, self.deploy)
211 if not self.channel or self.channel.state < ResourceState.READY:
212 self.debug("---- RESCHEDULING DEPLOY ---- channel state %s "
213 % self.channel.state )
214 self.ec.schedule(self.reschedule_delay, self.deploy)
217 ## For performance test
219 self.begin_deploy_time = tnow()
222 self.set('xmppUser',self.node.get('xmppUser'))
223 self.set('xmppServer',self.node.get('xmppServer'))
224 self.set('xmppPort',self.node.get('xmppPort'))
225 self.set('xmppPassword',self.node.get('xmppPassword'))
226 self.set('version',self.node.get('version'))
228 if not self.get('xmppServer'):
229 msg = "XmppServer is not initialzed. XMPP Connections impossible"
231 raise RuntimeError(msg)
233 if not (self.get('xmppUser') or self.get('xmppPort')
234 or self.get('xmppPassword')):
235 msg = "Credentials are not all initialzed. Default values will be used"
238 if not self._omf_api :
239 self._omf_api = OMFAPIFactory.get_api(self.get('version'),
240 self.get('xmppServer'), self.get('xmppUser'), self.get('xmppPort'),
241 self.get('xmppPassword'), exp_id = self.exp_id)
243 if not (self.get('name')):
244 msg = "Interface's name is not initialized"
246 raise RuntimeError(msg)
248 if not (self.get('mode') and self.get('essid') \
249 and self.get('hw_mode') and self.get('ip')):
250 msg = "Interface's variable are not initialized"
252 raise RuntimeError(msg)
254 if self.get('version') == "5":
255 res = self.configure_on_omf5()
258 res = self.configure_on_omf6()
261 super(OMFWifiInterface, self).do_deploy()
263 def configure_on_omf6(self):
264 """ Method to configure the wifi interface when OMF 6 is used.
267 if not self.create_id :
269 props['wlan:if_name'] = self.get('name')
270 props['wlan:mode'] = {
271 "mode": self.get('mode'),
272 "hw_mode" : self.get('hw_mode'),
273 "channel" : self.channel.get('channel'),
274 "essid" : self.get('essid'),
275 "ip_addr" : self.get('ip'),
276 "frequency" : self.channel.frequency,
279 props['wlan:hrn'] = self.get('name')
280 props['wlan:type'] = "wlan"
282 self.create_id = os.urandom(16).encode('hex')
283 self._omf_api.frcp_create( self.create_id, self.node.get('hostname'), "wlan", props = props)
285 if self._create_cnt > confirmation_counter:
286 msg = "Couldn't retrieve the confirmation of the creation"
288 raise RuntimeError(msg)
290 uid = self.check_deploy(self.create_id)
293 self.ec.schedule(reschedule_check, self.deploy)
296 self._topic_iface = uid
297 self._omf_api.enroll_topic(self._topic_iface)
300 def check_release(self, cid):
301 """ Check, through the mail box in the parser,
302 if the confirmation of the release has been received
304 :param cid: the id of the original message
308 res = self._omf_api.check_mailbox("release", cid)
313 def do_release(self):
314 """ Clean the RM at the end of the experiment and release the API
318 if self.get('version') == "6" and self._topic_iface :
319 if not self.release_id:
320 self.release_id = os.urandom(16).encode('hex')
321 self._omf_api.frcp_release( self.release_id, self.node.get('hostname'),self._topic_iface, res_id=self._topic_iface)
323 if self._release_cnt < confirmation_counter:
324 cid = self.check_release(self.release_id)
326 self._release_cnt +=1
327 self.ec.schedule(reschedule_check, self.release)
330 msg = "Couldn't retrieve the confirmation of the release"
334 OMFAPIFactory.release_api(self.get('version'),
335 self.get('xmppServer'), self.get('xmppUser'), self.get('xmppPort'),
336 self.get('xmppPassword'), exp_id = self.exp_id)
338 super(OMFWifiInterface, self).do_release()