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.execution.resource import ResourceManager, clsinit_copy, \
23 ResourceState, reschedule_delay
24 from nepi.execution.attribute import Attribute, Flags
26 from nepi.resources.omf.node import OMFNode
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 = "OMFWifiInterface"
43 _authorized_connections = ["OMFNode" , "OMFChannel"]
45 #alias2name = dict({'w0':'wlan0', 'w1':'wlan1'})
48 def _register_attributes(cls):
49 """Register the attributes of an OMF interface
52 alias = Attribute("alias","Alias of the interface", default = "w0")
53 type = Attribute("type","Choose between : a, b, g, n")
54 name = Attribute("name","Alias of the interface", default = "wlan0")
55 mode = Attribute("mode","Mode of the interface")
56 hw_mode = Attribute("hw_mode","Choose between : a, b, g, n")
57 essid = Attribute("essid","Essid of the interface")
58 ip = Attribute("ip","IP of the interface")
59 cls._register_attribute(alias)
60 cls._register_attribute(type)
61 cls._register_attribute(name)
62 cls._register_attribute(mode)
63 cls._register_attribute(hw_mode)
64 cls._register_attribute(essid)
65 cls._register_attribute(ip)
67 def __init__(self, ec, guid):
69 :param ec: The Experiment controller
70 :type ec: ExperimentController
71 :param guid: guid of the RM
73 :param creds: Credentials to communicate with the rm (XmppClient for OMF)
77 super(OMFWifiInterface, self).__init__(ec, guid)
81 self._alias = self.get('alias')
84 self.release_id = None
85 self._topic_iface = 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 attrval = self.get(attrname)
137 attrname = "net/%s/%s" % (self._alias, attrname)
138 self._omf_api.configure(self.node.get('hostname'), attrname,
141 super(OMFWifiInterface, self).do_provision()
144 def configure_ip(self):
145 """ Configure the ip of the interface
148 if self.channel.state < ResourceState.READY:
149 self.ec.schedule(reschedule_delay, self.deploy)
152 attrval = self.get("ip")
153 attrname = "net/%s/%s" % (self._alias, "ip")
154 self._omf_api.configure(self.node.get('hostname'), attrname,
159 def configure_on_omf5(self):
160 # Just for information
161 # self.debug(" " + self.get_rtype() + " ( Guid : " + str(self._guid) +") : " + \
162 # self.get('mode') + " : " + self.get('type') + " : " + \
163 # self.get('essid') + " : " + self.get('ip'))
164 if self.state < ResourceState.PROVISIONED:
165 if self._conf == False:
166 self._conf = self.configure_iface()
167 if self._conf == True:
173 """ Deploy the RM. It means : Get the xmpp client and send messages
174 using OMF 5.4 protocol to configure the interface.
175 It becomes DEPLOYED after sending messages to configure the interface
177 if not self.node or self.node.state < ResourceState.READY:
178 self.debug("---- RESCHEDULING DEPLOY ---- node state %s "
180 self.ec.schedule(reschedule_delay, self.deploy)
183 if not self.channel or self.channel.state < ResourceState.READY:
184 self.debug("---- RESCHEDULING DEPLOY ---- channel state %s "
185 % self.channel.state )
186 self.ec.schedule(reschedule_delay, self.deploy)
189 self.set('xmppUser',self.node.get('xmppUser'))
190 self.set('xmppServer',self.node.get('xmppServer'))
191 self.set('xmppPort',self.node.get('xmppPort'))
192 self.set('xmppPassword',self.node.get('xmppPassword'))
193 self.set('version',self.node.get('version'))
195 if not self.get('xmppServer'):
196 msg = "XmppServer is not initialzed. XMPP Connections impossible"
198 raise RuntimeError, msg
200 if not (self.get('xmppUser') or self.get('xmppPort')
201 or self.get('xmppPassword')):
202 msg = "Credentials are not all initialzed. Default values will be used"
205 if not self._omf_api :
206 self._omf_api = OMFAPIFactory.get_api(self.get('version'),
207 self.get('xmppServer'), self.get('xmppUser'), self.get('xmppPort'),
208 self.get('xmppPassword'), exp_id = self.exp_id)
210 if not (self.get('name') and self.get('mode') and self.get('essid') \
211 and self.get('hw_mode') and self.get('ip')):
212 msg = "Interface's variable are not initialized"
214 raise RuntimeError, msg
216 self.set('type',self.get('hw_mode'))
218 if self.get('version') == "5":
219 self.configure_on_omf5()
221 self.configure_on_omf6()
223 super(OMFWifiInterface, self).do_deploy()
225 def configure_on_omf6(self):
226 if not self.create_id :
228 props['wlan:if_name'] = self.get('name')
229 props['wlan:mode'] = {
230 "mode": self.get('mode'),
231 "hw_mode" : self.get('hw_mode'),
232 "channel" : self.channel.get('channel'),
233 "essid" : self.get('essid'),
234 "ip_addr" : self.get('ip'),
235 "frequency" : self.channel.frequency,
238 props['wlan:hrn'] = self.get('name')
239 props['wlan:type'] = "wlan"
241 self.create_id = os.urandom(16).encode('hex')
242 self._omf_api.frcp_create( self.create_id, self.node.get('hostname'), "wlan", props = props)
244 self.check_deploy(self.create_id)
245 self._omf_api.enroll_topic(self._topic_iface)
247 def check_deploy(self, cid):
250 uid = self._omf_api.check_mailbox("create", cid)
252 self._topic_iface = uid
258 msg = "Couldn't retrieve the confirmation of the creation"
260 raise RuntimeError, msg
262 def check_release(self, cid):
263 res = self._omf_api.check_mailbox("release", cid)
268 def do_release(self):
269 """ Clean the RM at the end of the experiment and release the API
272 if self.get('version') == "6":
273 if not self.release_id:
274 self.release_id = os.urandom(16).encode('hex')
275 self._omf_api.frcp_release( self.release_id, self.node.get('hostname'),self._topic_iface, res_id=self._topic_iface)
277 cid = self.check_release(self.release_id)
279 self.ec.schedule(reschedule_delay, self.release)
283 OMFAPIFactory.release_api(self.get('version'),
284 self.get('xmppServer'), self.get('xmppUser'), self.get('xmppPort'),
285 self.get('xmppPassword'), exp_id = self.exp_id)
287 super(OMFWifiInterface, self).do_release()