1 # -*- coding: utf-8 -*-
3 # (c) Copyright 2003-2009 Hewlett-Packard Development Company, L.P.
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 2 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, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # Author: Shunmugaraj.K
25 import xml.parsers.expat
30 from base import device, utils
32 http_result_pat = re.compile("""HTTP/\d.\d\s(\d+)""", re.I)
40 LEDM_WIFI_BASE_URI = "/IoMgmt/Adapters/"
42 adapterPowerXml = """<io:Adapters xmlns:io=\"http://www.hp.com/schemas/imaging/con/ledm/iomgmt/2008/11/30\" xmlns:dd=\"http://www.hp.com/schemas/imaging/con/dictionaries/1.0/\"><io:Adapter><io:HardwareConfig><dd:Power>%s</dd:Power></io:HardwareConfig></io:Adapter></io:Adapters>"""
44 passPhraseXml="""<io:Profile xmlns:io="http://www.hp.com/schemas/imaging/con/ledm/iomgmt/2008/11/30" xmlns:dd="http://www.hp.com/schemas/imaging/con/dictionaries/1.0/" xmlns:wifi="http://www.hp.com/schemas/imaging/con/wifi/2009/06/26" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.hp.com/schemas/imaging/con/ledm/iomgmt/2008/11/30 ../../schemas/IoMgmt.xsd http://www.hp.com/schemas/imaging/con/dictionaries/1.0/ ../../schemas/dd/DataDictionaryMasterLEDM.xsd"><io:AdapterProfile><io:WifiProfile><wifi:SSID>%s</wifi:SSID><wifi:CommunicationMode>%s</wifi:CommunicationMode><wifi:EncryptionType>%s</wifi:EncryptionType><wifi:AuthenticationMode>%s</wifi:AuthenticationMode></io:WifiProfile></io:AdapterProfile></io:Profile>"""
46 keyInfoXml = """<io:KeyInfo><io:WpaPassPhraseInfo><wifi:RsnEncryption>AESOrTKIP</wifi:RsnEncryption><wifi:RsnAuthorization>autoWPA</wifi:RsnAuthorization><wifi:PassPhrase>%s</wifi:PassPhrase></io:WpaPassPhraseInfo></io:KeyInfo>"""
48 def getAdaptorList(dev):
49 ret,params,elementCount,code ={},{},0,HTTP_ERROR
51 while max_tries < MAX_RETRIES:
53 URI = LEDM_WIFI_BASE_URI[0:len(LEDM_WIFI_BASE_URI)-1]# to remove "\" from the string
54 params,code,elementCount = readXmlDataFromURI(dev,URI,'<io:Adapters', '<io:Adapter>')
59 log.error("Request Failed With Response Code %d"%code)
62 ret['adaptorlistlength'] = elementCount
63 if params is not None:
66 ret['adaptorid-0' % a] = params['io:adapters-io:adapter-map:resourcenode-map:resourcelink-dd:resourceuri']
67 ret['adaptorname-0' % a] = params['io:adapters-io:adapter-io:hardwareconfig-dd:name']
68 ret['adaptorpresence-0' % a] = ''
69 ret['adaptorstate-0' % a] = ''
70 ret['adaptortype-0' % a] = params['io:adapters-io:adapter-io:hardwareconfig-dd:deviceconnectivityporttype']
72 log.error("Missing response key: %s" % e)
74 for a in xrange(elementCount):
76 ret['adaptorid-%d' % a] = params['io:adapters-io:adapter-map:resourcenode-map:resourcelink-dd:resourceuri-%d' % a]
77 ret['adaptorname-%d' % a] = params['io:adapters-io:adapter-io:hardwareconfig-dd:name-%d' % a]
78 ret['adaptorpresence-%d' % a] = ''
79 ret['adaptorstate-%d' % a] = ''
80 ret['adaptortype-%d' % a] = params['io:adapters-io:adapter-io:hardwareconfig-dd:deviceconnectivityporttype-%d' % a]
82 log.error("Missing response key: %s" % e)
86 def getWifiAdaptorID(dev):
89 ret = getAdaptorList(dev)
91 num_adaptors = ret['adaptorlistlength']
95 for n in xrange(num_adaptors):
97 name = ret['adaptortype-%d' % n]
101 if name.lower() in ('wifiembedded', 'wifiaccessory'):
102 params = ['adaptorid', 'adaptorname', 'adaptorstate', 'adaptorpresence']
106 x = ret[''.join([p, '-', str(n)])]
117 return -1, 'Unknown', 'Unknown', 'Unknown'
119 def setAdaptorPower(dev, adapterName, adaptor_id=0, power_state='on'):
120 ret,powerXml,URI,code = {},'','',HTTP_ERROR
121 URI = LEDM_WIFI_BASE_URI + adapterName
122 powerXml = adapterPowerXml %(power_state)
124 ret['errorreturn'] = writeXmlDataToURI(dev,URI,powerXml,10)
125 if not(ret['errorreturn'] == HTTP_OK or HTTP_NOCONTENT):
126 log.error("Request Failed With Response Code %d" %code)
130 def performScan(dev, adapterName, ssid=None):
134 URI = LEDM_WIFI_BASE_URI + adapterName + "/WifiNetworks"
136 URI = LEDM_WIFI_BASE_URI + adapterName + "/WifiNetworks/SSID="+ssid
139 params,code,elementCount = readXmlDataFromURI(dev,URI,'<io:WifiNetworks', '<io:WifiNetwork>',10)
140 if code == HTTP_ACCEPTED:
145 ret['numberofscanentries'] = elementCount
147 log.error("Request Failed With Response Code %d"%code)
150 if params is not None:
151 if elementCount == 1:
153 ssid = str(params['io:wifinetworks-io:wifinetwork-wifi:ssid']).decode("hex")
155 ret['ssid-0'] = u'(unknown)'
158 ret['bssid-0'] = str(params['io:wifinetworks-io:wifinetwork-wifi:bssid']).decode("hex")
159 ret['channel-0'] = params['io:wifinetworks-io:wifinetwork-wifi:channel']
160 ret['communicationmode-0'] = params['io:wifinetworks-io:wifinetwork-wifi:communicationmode']
161 ret['dbm-0'] = params['io:wifinetworks-io:wifinetwork-io:signalinfo-wifi:dbm']
162 ret['encryptiontype-0'] = params['io:wifinetworks-io:wifinetwork-wifi:encryptiontype']
163 ret['signalstrength-0'] = params['io:wifinetworks-io:wifinetwork-io:signalinfo-wifi:signalstrength']
165 log.error("Missing response key: %s" % e)
167 for a in xrange(elementCount):
169 ssid = str(params['io:wifinetworks-io:wifinetwork-wifi:ssid-%d' % a]).decode("hex")
171 ret['ssid-%d' % a] = u'(unknown)'
173 ret['ssid-%d' % a] = ssid
174 ret['bssid-%d' % a] = str(params['io:wifinetworks-io:wifinetwork-wifi:bssid-%d' % a]).decode("hex")
175 ret['channel-%d' % a] = params['io:wifinetworks-io:wifinetwork-wifi:channel-%d' % a]
176 ret['communicationmode-%d' % a] = params['io:wifinetworks-io:wifinetwork-wifi:communicationmode-%d' % a]
177 ret['dbm-%d' % a] = params['io:wifinetworks-io:wifinetwork-io:signalinfo-wifi:dbm-%d' % a]
178 ret['encryptiontype-%d' % a] = params['io:wifinetworks-io:wifinetwork-wifi:encryptiontype-%d' % a]
179 ret['signalstrength-%d' % a] = params['io:wifinetworks-io:wifinetwork-io:signalinfo-wifi:signalstrength-%d' % a]
182 log.error("Missing response key: %s" % e)
184 ret['signalstrengthmax'] = 5
185 ret['signalstrengthmin'] = 0
187 log.debug("Missing response key: %s" % e)
190 def getIPConfiguration(dev, adapterName):
191 ip, hostname, addressmode, subnetmask, gateway, pridns, sec_dns = \
192 '0.0.0.0', 'Unknown', 'Unknown', '0.0.0.0', '0.0.0.0', '0.0.0.0', '0.0.0.0'
194 URI = LEDM_WIFI_BASE_URI + adapterName + "/Protocols"
195 params,code,elementCount = {},HTTP_ERROR,0
198 while max_tries < MAX_RETRIES:
200 params,code,elementCount = readXmlDataFromURI(dev,URI,'<io:Protocol', '<io:Protocol')
205 log.error("Request Failed With Response Code %d" %code)
206 return ip, hostname, addressmode, subnetmask, gateway, pridns, sec_dns
208 if params is not None and code == HTTP_OK:
210 ip = params['io:protocols-io:protocol-io:addresses-io:ipv4addresses-io:ipv4address-dd:ipv4address']
211 subnetmask = params['io:protocols-io:protocol-io:addresses-io:ipv4addresses-io:ipv4address-dd:subnetmask']
212 gateway = params['io:protocols-io:protocol-io:addresses-io:ipv4addresses-io:ipv4address-dd:defaultgateway']
214 if 'DHCP' in params['io:protocols-io:protocol-io:addresses-io:ipv4addresses-io:ipv4address-dd:configmethod']:
217 addressmode = 'autoip'
219 pridns = params['io:protocols-io:protocol-dd:dnsserveripaddress']
220 sec_dns = params['io:protocols-io:protocol-dd:secondarydnsserveripaddress']
221 for a in xrange(elementCount):
222 if params['io:protocols-io:protocol-dd:dnsserveripaddress-%d' %a] !="::":
223 pridns = params['io:protocols-io:protocol-dd:dnsserveripaddress-%d' %a]
224 sec_dns = params['io:protocols-io:protocol-dd:secondarydnsserveripaddress-%d' %a]
227 log.error("Missing response key: %s" % str(e))
229 return ip, hostname, addressmode, subnetmask, gateway, pridns, sec_dns
232 def getCryptoSuite(dev, adapterName):
233 alg, mode, secretid = '', '', ''
234 parms,code,elementCount ={},HTTP_ERROR,0
235 URI = LEDM_WIFI_BASE_URI + adapterName + "/Profiles/Active"
238 while max_tries < MAX_RETRIES:
240 parms,code,elementCount = readXmlDataFromURI(dev,URI,'<io:Profile', '<io:Profile')
245 log.error("Request Failed With Response Code %d" %code)
246 return alg, mode, secretid
248 if parms is not None:
250 mode = parms['io:profile-io:adapterprofile-io:wifiprofile-wifi:communicationmode']
251 alg = parms['io:profile-io:adapterprofile-io:wifiprofile-wifi:encryptiontype']
252 secretid = parms['io:profile-io:adapterprofile-io:wifiprofile-wifi:bssid']
254 log.error("Missing response key: %s" % str(e))
256 return alg, mode, secretid
259 def associate(dev, adapterName, ssid, communication_mode, encryption_type, key):
260 ret,code = {},HTTP_ERROR
261 URI = LEDM_WIFI_BASE_URI + adapterName + "/Profiles/Active"
263 if encryption_type == 'none':
265 ppXml = passPhraseXml%(ssid.encode('hex'),communication_mode,encryption_type,authMode)
267 authMode = encryption_type
268 pos = passPhraseXml.find("</io:WifiProfile>",0,len(passPhraseXml))
269 ppXml = (passPhraseXml[:pos] + keyInfoXml + passPhraseXml[pos:])%(ssid.encode('hex'),communication_mode,encryption_type,\
270 authMode,key.encode('hex'))
272 code = writeXmlDataToURI(dev,URI,ppXml,10)
273 ret['errorreturn'] = code
274 if not(code == HTTP_OK or HTTP_NOCONTENT):
275 log.error("Request Failed With Response Code %d" % ret['errorreturn'])
280 def getVSACodes(dev, adapterName):
281 ret,params,code,elementCount = [],{},HTTP_ERROR,0
283 URI = LEDM_WIFI_BASE_URI + adapterName + "/VsaCodes.xml"
286 while max_tries < MAX_RETRIES:
288 params,code,elementCount = readXmlDataFromURI(dev,URI,"<io:VsaCodes","<io:VsaCodes",10)
293 log.error("Request Failed With Response Code %d"%code)
296 if params is not None:
298 severity= params['io:vsacodes-wifi:vsacode-dd:severity']
302 rule = params['io:vsacodes-wifi:vsacode-wifi:rulenumber']
303 # except KeyError, e:
304 # log.error("Missing response key: %s" % str(e))
307 ret.append((rule, severity))
311 def getHostname(dev):
313 URI = "/IoMgmt/IoConfig.xml"
316 while max_tries < MAX_RETRIES:
318 params,code,elementCount = readXmlDataFromURI(dev,URI,'<io:IoConfig', '<io:IoConfig')
323 log.error("Request failed with Response code %d"%code)
326 if params is not None:
328 hostName = params['io:ioconfig-io:iodeviceconfig-dd3:hostname']
330 log.error("Missing response key: %s" % e)
334 def getSignalStrength(dev, adapterName, ssid, adaptor_id=0):
335 ss_max, ss_min, ss_val, ss_dbm = 5, 0, 0, -200
336 params,code,elementCount = {},HTTP_ERROR,0
339 URI = LEDM_WIFI_BASE_URI + adapterName + "/WifiNetworks/SSID="+ssid
341 return ss_max, ss_min, ss_val, ss_dbm
344 params,code,elementCount = readXmlDataFromURI(dev,URI,'<io:WifiNetworks', '<io:WifiNetwork>',10)
345 if code == HTTP_ACCEPTED:
346 log.info("Got Response as HTTP_ACCEPTED, so retrying to get the actual result")
352 log.error("Request Failed With Response Code %d"%code)
353 return ss_max, ss_min, ss_val, ss_dbm
355 if params is not None:
356 if elementCount == 1:
358 ss_dbm = params['io:wifinetworks-io:wifinetwork-io:signalinfo-wifi:dbm']
359 ss_val = params['io:wifinetworks-io:wifinetwork-io:signalinfo-wifi:signalstrength']
361 log.error("Missing response key: %s" % e)
363 return ss_max, ss_min, ss_val, ss_dbm
366 def readXmlDataFromURI(dev,URI,xmlRootNode,xmlChildNode,timeout=5):
367 params,code,elementCount ={},HTTP_ERROR,0
369 data = format_http_get(URI,0,"")
371 response = cStringIO.StringIO()
372 if dev.openLEDM() == -1:
374 dev.writeEWS_LEDM(data)
376 while dev.readEWS_LEDM(1024, response, timeout):
380 log.error("Unable to read EWS_LEDM Channel")
384 #response = cStringIO.StringIO()
386 while dev.readLEDM(1024, response, timeout):
390 log.error("Unable to read LEDM Channel")
392 strResp = str(response.getvalue())
394 if strResp is not None:
395 code = get_error_code(strResp)
396 pos = strResp.find(xmlRootNode,0,len(strResp))
397 repstr = strResp[pos:].strip()
398 repstr = filter(lambda c: c not in "\r\t\n", repstr) # To remove formating characters from the received xml
399 repstr = repstr.rstrip('0') # To remove trailing zero from the received xml
400 elementCount = repstr.count(xmlChildNode)
402 params = utils.XMLToDictParser().parseXML(repstr)
403 except xml.parsers.expat.ExpatError, e:
404 log.error("XML parser failed: %s" % e)
406 return params,code,elementCount
409 def writeXmlDataToURI(dev,URI,xml,timeout=5):
412 data = format_http_put(URI,len(xml),xml)
413 response = cStringIO.StringIO()
415 if dev.openLEDM() == -1:
417 dev.writeEWS_LEDM(data)
419 while dev.readEWS_LEDM(1000, response, timeout):
423 log.error("Unable to read EWS_LEDM Channel")
427 #response = cStringIO.StringIO()
429 while dev.readLEDM(1000, response, timeout):
433 log.error("Unable to read LEDM Channel")
436 strResp = str(response.getvalue())
437 if strResp is not None:
438 code = get_error_code(strResp)
442 def get_error_code(ret):
443 if not ret: return HTTP_ERROR
444 match = http_result_pat.match(ret)
445 if match is None: return HTTP_ERROR
447 code = int(match.group(1))
448 except (ValueError, TypeError):
453 def format_http_get(requst, ledmlen, xmldata, content_type="text/xml; charset=utf-8"):
456 """GET $requst HTTP/1.1\r
458 User-Agent: hplip/3.0\r
459 Content-Type: $content_type\r
460 Content-Length: $ledmlen\r
465 def format_http_put(requst, ledmlen, xmldata, content_type="text/xml; charset=utf-8"):
468 """PUT $requst HTTP/1.1\r
470 User-Agent: hplip/3.0\r
471 Content-Type: $content_type\r
472 Content-Length: $ledmlen\r