diff options
Diffstat (limited to 'dom/wifi')
42 files changed, 0 insertions, 14001 deletions
diff --git a/dom/wifi/DOMWifiManager.js b/dom/wifi/DOMWifiManager.js deleted file mode 100644 index 8bedfc398..000000000 --- a/dom/wifi/DOMWifiManager.js +++ /dev/null @@ -1,543 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); - -const DEBUG = false; // set to false to suppress debug messages - -const DOMWIFIMANAGER_CONTRACTID = "@mozilla.org/wifimanager;1"; -const DOMWIFIMANAGER_CID = Components.ID("{c9b5f09e-25d2-40ca-aef4-c4d13d93c706}"); - -function MozWifiNetwork() { -} - -MozWifiNetwork.prototype = { - - init: function(aWindow) { - this._window = aWindow; - }, - - __init: function(obj) { - for (let key in obj) { - this[key] = obj[key]; - } - }, - - classID: Components.ID("{c01fd751-43c0-460a-8b64-abf652ec7220}"), - contractID: "@mozilla.org/mozwifinetwork;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, - Ci.nsIDOMGlobalPropertyInitializer]) -}; - -function MozWifiConnection(obj) { - this.status = obj.status; - this.network = obj.network; -} - -MozWifiConnection.prototype = { - classID: Components.ID("{23579da4-201b-4319-bd42-9b7f337343ac}"), - contractID: "@mozilla.org/mozwificonnection;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) -}; - -function MozWifiConnectionInfo(obj) { - this.signalStrength = obj.signalStrength; - this.relSignalStrength = obj.relSignalStrength; - this.linkSpeed = obj.linkSpeed; - this.ipAddress = obj.ipAddress; -} - -MozWifiConnectionInfo.prototype = { - classID: Components.ID("{83670352-6ed4-4c35-8de9-402296a1959c}"), - contractID: "@mozilla.org/mozwificonnectioninfo;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) -} - -function MozWifiCapabilities(obj) { - this.security = obj.security; - this.eapMethod = obj.eapMethod; - this.eapPhase2 = obj.eapPhase2; - this.certificate = obj.certificate; -} - -MozWifiCapabilities.prototype = { - classID: Components.ID("08c88ece-8092-481b-863b-5515a52e411a"), - contractID: "@mozilla.org/mozwificapabilities;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) -} - -function DOMWifiManager() { - this.defineEventHandlerGetterSetter("onstatuschange"); - this.defineEventHandlerGetterSetter("onconnectioninfoupdate"); - this.defineEventHandlerGetterSetter("onenabled"); - this.defineEventHandlerGetterSetter("ondisabled"); - this.defineEventHandlerGetterSetter("onstationinfoupdate"); -} - -DOMWifiManager.prototype = { - __proto__: DOMRequestIpcHelper.prototype, - classDescription: "DOMWifiManager", - classID: DOMWIFIMANAGER_CID, - contractID: DOMWIFIMANAGER_CONTRACTID, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, - Ci.nsISupportsWeakReference, - Ci.nsIObserver]), - - // nsIDOMGlobalPropertyInitializer implementation - init: function(aWindow) { - // Maintain this state for synchronous APIs. - this._currentNetwork = null; - this._connectionStatus = "disconnected"; - this._enabled = false; - this._lastConnectionInfo = null; - this._capabilities = null; - this._stationNumber = 0; - - const messages = ["WifiManager:getNetworks:Return:OK", "WifiManager:getNetworks:Return:NO", - "WifiManager:getKnownNetworks:Return:OK", "WifiManager:getKnownNetworks:Return:NO", - "WifiManager:associate:Return:OK", "WifiManager:associate:Return:NO", - "WifiManager:forget:Return:OK", "WifiManager:forget:Return:NO", - "WifiManager:wps:Return:OK", "WifiManager:wps:Return:NO", - "WifiManager:setPowerSavingMode:Return:OK", "WifiManager:setPowerSavingMode:Return:NO", - "WifiManager:setHttpProxy:Return:OK", "WifiManager:setHttpProxy:Return:NO", - "WifiManager:setStaticIpMode:Return:OK", "WifiManager:setStaticIpMode:Return:NO", - "WifiManager:importCert:Return:OK", "WifiManager:importCert:Return:NO", - "WifiManager:getImportedCerts:Return:OK", "WifiManager:getImportedCerts:Return:NO", - "WifiManager:deleteCert:Return:OK", "WifiManager:deleteCert:Return:NO", - "WifiManager:setWifiEnabled:Return:OK", "WifiManager:setWifiEnabled:Return:NO", - "WifiManager:wifiDown", "WifiManager:wifiUp", - "WifiManager:onconnecting", "WifiManager:onassociate", - "WifiManager:onconnect", "WifiManager:ondisconnect", - "WifiManager:onwpstimeout", "WifiManager:onwpsfail", - "WifiManager:onwpsoverlap", "WifiManager:connectioninfoupdate", - "WifiManager:onauthenticating", "WifiManager:onconnectingfailed", - "WifiManager:stationinfoupdate"]; - this.initDOMRequestHelper(aWindow, messages); - this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender); - - var state = this._mm.sendSyncMessage("WifiManager:getState")[0]; - if (state) { - this._currentNetwork = this._convertWifiNetwork(state.network); - this._lastConnectionInfo = this._convertConnectionInfo(state.connectionInfo); - this._enabled = state.enabled; - this._connectionStatus = state.status; - this._macAddress = state.macAddress; - this._capabilities = this._convertWifiCapabilities(state.capabilities); - } else { - this._currentNetwork = null; - this._lastConnectionInfo = null; - this._enabled = false; - this._connectionStatus = "disconnected"; - this._macAddress = ""; - } - }, - - _convertWifiNetworkToJSON: function(aNetwork) { - let json = {}; - - for (let key in aNetwork) { - // In WifiWorker.js there are lots of check using "key in network". - // So if the value of any property of WifiNetwork is undefined, do not clone it. - if (aNetwork[key] != undefined) { - json[key] = aNetwork[key]; - } - } - return json; - }, - - _convertWifiNetwork: function(aNetwork) { - let network = aNetwork ? new this._window.MozWifiNetwork(aNetwork) : null; - return network; - }, - - _convertWifiNetworks: function(aNetworks) { - let networks = new this._window.Array(); - for (let i in aNetworks) { - networks.push(this._convertWifiNetwork(aNetworks[i])); - } - return networks; - }, - - _convertConnection: function(aConn) { - let conn = aConn ? new MozWifiConnection(aConn) : null; - return conn; - }, - - _convertConnectionInfo: function(aInfo) { - let info = aInfo ? new MozWifiConnectionInfo(aInfo) : null; - return info; - }, - - _convertWifiCapabilities: function(aCapabilities) { - let capabilities = aCapabilities ? - new MozWifiCapabilities(aCapabilities) : null; - return capabilities; - }, - - _sendMessageForRequest: function(name, data, request) { - let id = this.getRequestId(request); - this._mm.sendAsyncMessage(name, { data: data, rid: id, mid: this._id }); - }, - - receiveMessage: function(aMessage) { - let msg = aMessage.json; - if (msg.mid && msg.mid != this._id) - return; - - let request; - if (msg.rid) { - request = this.takeRequest(msg.rid); - if (!request) { - return; - } - } - - switch (aMessage.name) { - case "WifiManager:setWifiEnabled:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:setWifiEnabled:Return:NO": - Services.DOMRequest.fireError(request, "Unable to enable/disable Wifi"); - break; - - case "WifiManager:getNetworks:Return:OK": - Services.DOMRequest.fireSuccess(request, this._convertWifiNetworks(msg.data)); - break; - - case "WifiManager:getNetworks:Return:NO": - Services.DOMRequest.fireError(request, "Unable to scan for networks"); - break; - - case "WifiManager:getKnownNetworks:Return:OK": - Services.DOMRequest.fireSuccess(request, this._convertWifiNetworks(msg.data)); - break; - - case "WifiManager:getKnownNetworks:Return:NO": - Services.DOMRequest.fireError(request, "Unable to get known networks"); - break; - - case "WifiManager:associate:Return:OK": - Services.DOMRequest.fireSuccess(request, true); - break; - - case "WifiManager:associate:Return:NO": - Services.DOMRequest.fireError(request, "Unable to add the network"); - break; - - case "WifiManager:forget:Return:OK": - Services.DOMRequest.fireSuccess(request, true); - break; - - case "WifiManager:forget:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:wps:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:wps:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:setPowerSavingMode:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:setPowerSavingMode:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:setHttpProxy:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:setHttpProxy:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:setStaticIpMode:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:setStaticIpMode:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:importCert:Return:OK": - Services.DOMRequest.fireSuccess(request, Cu.cloneInto(msg.data, this._window)); - break; - - case "WifiManager:importCert:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:getImportedCerts:Return:OK": - Services.DOMRequest.fireSuccess(request, Cu.cloneInto(msg.data, this._window)); - break; - - case "WifiManager:getImportedCerts:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:deleteCert:Return:OK": - Services.DOMRequest.fireSuccess(request, msg.data); - break; - - case "WifiManager:deleteCert:Return:NO": - Services.DOMRequest.fireError(request, msg.data); - break; - - case "WifiManager:wifiDown": - this._enabled = false; - this._currentNetwork = null; - this._fireEnabledOrDisabled(false); - break; - - case "WifiManager:wifiUp": - this._enabled = true; - this._macAddress = msg.macAddress; - this._fireEnabledOrDisabled(true); - break; - - case "WifiManager:onconnecting": - this._currentNetwork = this._convertWifiNetwork(msg.network); - this._connectionStatus = "connecting"; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onassociate": - this._currentNetwork = this._convertWifiNetwork(msg.network); - this._connectionStatus = "associated"; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onconnect": - this._currentNetwork = this._convertWifiNetwork(msg.network); - this._connectionStatus = "connected"; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:ondisconnect": - this._currentNetwork = null; - this._connectionStatus = "disconnected"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onwpstimeout": - this._currentNetwork = null; - this._connectionStatus = "wps-timedout"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onwpsfail": - this._currentNetwork = null; - this._connectionStatus = "wps-failed"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:onwpsoverlap": - this._currentNetwork = null; - this._connectionStatus = "wps-overlapped"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - - case "WifiManager:connectioninfoupdate": - this._lastConnectionInfo = this._convertConnectionInfo(msg); - this._fireConnectionInfoUpdate(msg); - break; - case "WifiManager:onconnectingfailed": - this._currentNetwork = null; - this._connectionStatus = "connectingfailed"; - this._lastConnectionInfo = null; - this._fireStatusChangeEvent(msg.network); - break; - case "WifiManager:onauthenticating": - this._currentNetwork = this._convertWifiNetwork(msg.network); - this._connectionStatus = "authenticating"; - this._fireStatusChangeEvent(msg.network); - break; - case "WifiManager:stationinfoupdate": - this._stationNumber = msg.station; - this._fireStationInfoUpdate(msg); - break; - } - }, - - _fireStatusChangeEvent: function StatusChangeEvent(aNetwork) { - var event = new this._window.MozWifiStatusChangeEvent("statuschange", - { network: this._convertWifiNetwork(aNetwork), - status: this._connectionStatus - }); - this.__DOM_IMPL__.dispatchEvent(event); - }, - - _fireConnectionInfoUpdate: function onConnectionInfoUpdate(info) { - var evt = new this._window.MozWifiConnectionInfoEvent("connectioninfoupdate", - { network: this._currentNetwork, - signalStrength: info.signalStrength, - relSignalStrength: info.relSignalStrength, - linkSpeed: info.linkSpeed, - ipAddress: info.ipAddress, - }); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - _fireEnabledOrDisabled: function enabledDisabled(enabled) { - var evt = new this._window.Event(enabled ? "enabled" : "disabled"); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - _fireStationInfoUpdate: function onStationInfoUpdate(info) { - var evt = new this._window.MozWifiStationInfoEvent("stationinfoupdate", - { station: this._stationNumber} - ); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - setWifiEnabled: function setWifiEnabled(enabled) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:setWifiEnabled", enabled, request); - return request; - }, - - getNetworks: function getNetworks() { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:getNetworks", null, request); - return request; - }, - - getKnownNetworks: function getKnownNetworks() { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:getKnownNetworks", null, request); - return request; - }, - - associate: function associate(network) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:associate", - this._convertWifiNetworkToJSON(network), request); - return request; - }, - - forget: function forget(network) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:forget", - this._convertWifiNetworkToJSON(network), request); - return request; - }, - - wps: function wps(detail) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:wps", detail, request); - return request; - }, - - setPowerSavingMode: function setPowerSavingMode(enabled) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:setPowerSavingMode", enabled, request); - return request; - }, - - setHttpProxy: function setHttpProxy(network, info) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:setHttpProxy", - { network: this._convertWifiNetworkToJSON(network), info:info}, request); - return request; - }, - - setStaticIpMode: function setStaticIpMode(network, info) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:setStaticIpMode", - { network: this._convertWifiNetworkToJSON(network), info: info}, request); - return request; - }, - - importCert: function nsIDOMWifiManager_importCert(certBlob, certPassword, certNickname) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:importCert", - { - certBlob: certBlob, - certPassword: certPassword, - certNickname: certNickname - }, request); - return request; - }, - - getImportedCerts: function nsIDOMWifiManager_getImportedCerts() { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:getImportedCerts", null, request); - return request; - }, - - deleteCert: function nsIDOMWifiManager_deleteCert(certNickname) { - var request = this.createRequest(); - this._sendMessageForRequest("WifiManager:deleteCert", - { - certNickname: certNickname - }, request); - return request; - }, - - get enabled() { - return this._enabled; - }, - - get macAddress() { - return this._macAddress; - }, - - get connection() { - let _connection = this._convertConnection({ status: this._connectionStatus, - network: this._currentNetwork, - }); - return _connection; - }, - - get connectionInformation() { - return this._lastConnectionInfo; - }, - - get capabilities() { - return this._capabilities; - }, - - defineEventHandlerGetterSetter: function(name) { - Object.defineProperty(this, name, { - get: function() { - return this.__DOM_IMPL__.getEventHandler(name); - }, - set: function(handler) { - this.__DOM_IMPL__.setEventHandler(name, handler); - } - }); - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ - DOMWifiManager, MozWifiNetwork, MozWifiConnection, MozWifiCapabilities, - MozWifiConnectionInfo -]); - -var debug; -if (DEBUG) { - debug = function (s) { - dump("-*- DOMWifiManager component: " + s + "\n"); - }; -} else { - debug = function (s) {}; -} diff --git a/dom/wifi/DOMWifiManager.manifest b/dom/wifi/DOMWifiManager.manifest deleted file mode 100644 index 3ba83c1b2..000000000 --- a/dom/wifi/DOMWifiManager.manifest +++ /dev/null @@ -1,18 +0,0 @@ -# DOMWifiManager.js -component {c9b5f09e-25d2-40ca-aef4-c4d13d93c706} DOMWifiManager.js -contract @mozilla.org/wifimanager;1 {c9b5f09e-25d2-40ca-aef4-c4d13d93c706} - -component {c01fd751-43c0-460a-8b64-abf652ec7220} DOMWifiManager.js -contract @mozilla.org/mozwifinetwork;1 {c01fd751-43c0-460a-8b64-abf652ec7220} - -component {23579da4-201b-4319-bd42-9b7f337343ac} DOMWifiManager.js -contract @mozilla.org/mozwificonnection;1 {23579da4-201b-4319-bd42-9b7f337343ac} - -component {83670352-6ed4-4c35-8de9-402296a1959c} DOMWifiManager.js -contract @mozilla.org/mozwificonnectioninfo;1 {83670352-6ed4-4c35-8de9-402296a1959c} - -component {ad5c5295-85fb-4460-8e0c-e130d3f029ab} DOMWifiManager.js -contract @mozilla.org/mozwificertificateinfo;1 {ad5c5295-85fb-4460-8e0c-e130d3f029ab} - -component {08c88ece-8092-481b-863b-5515a52e411a} DOMWifiManager.js -contract @mozilla.org/mozwificapabilities;1 {08c88ece-8092-481b-863b-5515a52e411a} diff --git a/dom/wifi/DOMWifiP2pManager.js b/dom/wifi/DOMWifiP2pManager.js deleted file mode 100644 index 3a5637521..000000000 --- a/dom/wifi/DOMWifiP2pManager.js +++ /dev/null @@ -1,328 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); - -const DEBUG = false; - -// interface MozWifiP2pGroupOwner implementation. - -function MozWifiP2pGroupOwner(aGo) { - this.groupName = aGo.groupName; - this.macAddress = aGo.macAddress; - this.ipAddress = aGo.ipAddress; - this.passphrase = aGo.passphrase; - this.ssid = aGo.ssid; - this.wpsCapabilities = aGo.wpsCapabilities; - this.freq = aGo.freq; - this.isLocal = aGo.isLocal; -} - -MozWifiP2pGroupOwner.prototype = { - classID: Components.ID("{a9b81450-349d-11e3-aa6e-0800200c9a66}"), - contractID: "@mozilla.org/wifip2pgroupowner;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) -}; - -// interface MozWifiP2pManager implementation. - -const MOZ_WIFIP2PMANAGER_CONTRACTID = "@mozilla.org/wifip2pmanager;1"; -const MOZ_WIFIP2PMANAGER_CID = Components.ID("{8d9125a0-3498-11e3-aa6e-0800200c9a66}"); - -function MozWifiP2pManager() { - this.defineEventHandlerGetterSetter("onstatuschange"); - this.defineEventHandlerGetterSetter("onpeerinfoupdate"); - this.defineEventHandlerGetterSetter("onenabled"); - this.defineEventHandlerGetterSetter("ondisabled"); - - this.currentPeer = null; - this.enabled = false; - this.groupOwner = null; -} - -// For smaller, read-only APIs, we expose any property that doesn't begin with -// an underscore. -function exposeReadOnly(obj) { - let exposedProps = {}; - for (let i in obj) { - if (i[0] === "_") { - continue; - } - exposedProps[i] = "r"; - } - - obj.__exposedProps__ = exposedProps; - return obj; -} - -function debug(msg) { - if (DEBUG) { - dump('-------------- MozWifiP2pManager: ' + msg); - } -} - -MozWifiP2pManager.prototype = { - __proto__: DOMRequestIpcHelper.prototype, - - classID: MOZ_WIFIP2PMANAGER_CID, - contractID: MOZ_WIFIP2PMANAGER_CONTRACTID, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, - Ci.nsISupportsWeakReference, - Ci.nsIObserver, - Ci.nsISupports]), - - // - // nsIDOMGlobalPropertyInitializer implementation. - // - - init: function(aWindow) { - const messages = ["WifiP2pManager:setScanEnabled:Return:OK", - "WifiP2pManager:setScanEnabled:Return:NO", - "WifiP2pManager:getPeerList:Return:OK", - "WifiP2pManager:getPeerList:Return:NO", - "WifiP2pManager:connect:Return:OK", - "WifiP2pManager:connect:Return:NO", - "WifiP2pManager:disconnect:Return:OK", - "WifiP2pManager:disconnect:Return:NO", - "WifiP2pManager:setPairingConfirmation:Return", - "WifiP2pManager:setDeviceName:Return:OK", - "WifiP2pManager:setDeviceName:Return:NO", - - "WifiP2pManager:p2pDown", - "WifiP2pManager:p2pUp", - "WifiP2pManager:onconnecting", - "WifiP2pManager:onconnected", - "WifiP2pManager:ondisconnected", - "WifiP2pManager:ongroupnstop", - "WifiP2pManager:onconnectingfailed", - "WifiP2pManager:onwpstimeout", - "WifiP2pManager:onwpsfail", - "WifiP2pManager:onpeerinfoupdate", - ]; - - this.initDOMRequestHelper(aWindow, messages); - this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender); - - // Notify the internal a new DOM mananger is created. - let state = this._mm.sendSyncMessage("WifiP2pManager:getState")[0]; - if (state) { - debug('State: ' + JSON.stringify(state)); - this.enabled = state.enabled; - this.currentPeer = state.currentPeer; - if (state.groupOwner) { - this.groupOwner = new MozWifiP2pGroupOwner(state.groupOwner); - } - } else { - debug('Failed to get state'); - } - }, - - uninit: function() { - }, - - _sendMessageForRequest: function(name, data, request) { - let id = this.getRequestId(request); - this._mm.sendAsyncMessage(name, { data: data, rid: id, mid: this._id }); - }, - - receiveMessage: function(aMessage) { - let msg = aMessage.json; - if (msg.mid && msg.mid !== this._id) { - return; - } - - let request; - switch (aMessage.name) { - case "WifiP2pManager:setScanEnabled:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); - break; - - case "WifiP2pManager:setScanEnabled:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to enable/disable Wifi P2P peer discovery."); - break; - - case "WifiP2pManager:getPeerList:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, Cu.cloneInto(msg.data, this._window)); - break; - - case "WifiP2pManager:getPeerList:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to disable Wifi P2P peer discovery."); - break; - - case "WifiP2pManager:connect:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); - break; - - case "WifiP2pManager:connect:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to connect to Wifi P2P peer."); - break; - - case "WifiP2pManager:disconnect:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); - break; - - case "WifiP2pManager:disconnect:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to disconnect to Wifi P2P peer."); - break; - - case "WifiP2pManager:setDeviceName:Return:OK": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); - break; - - case "WifiP2pManager:setDeviceName:Return:NO": - request = this.takeRequest(msg.rid); - Services.DOMRequest.fireError(request, "Unable to set device name."); - break; - - case "WifiP2pManager:p2pDown": - this.enabled = false; - this.currentPeer = null; - this._fireEnabledOrDisabled(false); - break; - - case "WifiP2pManager:p2pUp": - this.enabled = true; - this._fireEnabledOrDisabled(true); - break; - - case "WifiP2pManager:onconnecting": - debug('onconnecting with peer: ' + JSON.stringify(msg.peer)); - this.currentPeer = msg.peer; - this._fireStatusChangeEvent(msg.peer.address); - break; - - case "WifiP2pManager:onconnected": - debug('onconnected with peer: ' + JSON.stringify(msg.peer)); - this.currentPeer = msg.peer; - this.groupOwner = new MozWifiP2pGroupOwner(msg.groupOwner); - this._fireStatusChangeEvent(msg.peer.address); - break; - - case "WifiP2pManager:ondisconnected": - debug('ondisconnected with peer: ' + JSON.stringify(msg.peer)); - this.currentPeer = null; - this.groupOwner = null; - this._fireStatusChangeEvent(msg.peer.address); - break; - - case "WifiP2pManager:onconnectingfailed": - this._fireStatusChangeEvent(null); - break; - - case "WifiP2pManager:onwpstimeout": - this._fireStatusChangeEvent(null); - break; - - case "WifiP2pManager:onwpsfail": - this._fireStatusChangeEvent(null); - break; - - case "WifiP2pManager:onpeerinfoupdate": - this._firePeerInfoUpdateEvent(); - break; - } - }, - - _firePeerInfoUpdateEvent: function PeerInfoUpdate() { - let evt = new this._window.Event("peerinfoupdate"); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - _fireStatusChangeEvent: function WifiP2pStatusChange(peerAddress) { - let evt = new this._window.MozWifiP2pStatusChangeEvent("statuschange", - { peerAddress: peerAddress }); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - _fireEnabledOrDisabled: function enabledDisabled(enabled) { - let evt = new this._window.Event(enabled ? "enabled" : "disabled"); - this.__DOM_IMPL__.dispatchEvent(evt); - }, - - // - // WifiP2pManager.webidl implementation. - // - - enableScan: function () { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:enableScan", null, request); - return request; - }, - - disableScan: function () { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:disableScan", null, request); - return request; - }, - - setScanEnabled: function(enabled) { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:setScanEnabled", enabled, request); - return request; - }, - - connect: function (address, wpsMethod, goIntent) { - let request = this.createRequest(); - let connectionInfo = { address: address, wpsMethod: wpsMethod, goIntent: goIntent }; - this._sendMessageForRequest("WifiP2pManager:connect", connectionInfo, request); - return request; - }, - - disconnect: function (address) { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:disconnect", address, request); - return request; - }, - - getPeerList: function () { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:getPeerList", null, request); - return request; - }, - - setPairingConfirmation: function (accepted, pin) { - let request = this.createRequest(); - let result = { accepted: accepted, pin: pin }; - this._sendMessageForRequest("WifiP2pManager:setPairingConfirmation", result, request); - return request; - }, - - setDeviceName: function(newDeviceName) { - let request = this.createRequest(); - this._sendMessageForRequest("WifiP2pManager:setDeviceName", newDeviceName, request); - return request; - }, - - // Helpers. - defineEventHandlerGetterSetter: function(event) { - Object.defineProperty(this, event, { - get: function() { - return this.__DOM_IMPL__.getEventHandler(event); - }, - - set: function(handler) { - this.__DOM_IMPL__.setEventHandler(event, handler); - } - }); - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozWifiP2pManager, MozWifiP2pGroupOwner]); diff --git a/dom/wifi/DOMWifiP2pManager.manifest b/dom/wifi/DOMWifiP2pManager.manifest deleted file mode 100644 index bc80efa48..000000000 --- a/dom/wifi/DOMWifiP2pManager.manifest +++ /dev/null @@ -1,6 +0,0 @@ -# DOMWifiP2pManager.js -component {8d9125a0-3498-11e3-aa6e-0800200c9a66} DOMWifiP2pManager.js -contract @mozilla.org/wifip2pmanager;1 {8d9125a0-3498-11e3-aa6e-0800200c9a66} - -component {a9b81450-349d-11e3-aa6e-0800200c9a66} DOMWifiP2pManager.js -contract @mozilla.org/wifip2pgroupowner;1 {a9b81450-349d-11e3-aa6e-0800200c9a66}
\ No newline at end of file diff --git a/dom/wifi/StateMachine.jsm b/dom/wifi/StateMachine.jsm deleted file mode 100644 index 94b876f82..000000000 --- a/dom/wifi/StateMachine.jsm +++ /dev/null @@ -1,205 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); - -this.EXPORTED_SYMBOLS = ["StateMachine"]; - -const DEBUG = false; - -this.StateMachine = function(aDebugTag) { - function debug(aMsg) { - dump('-------------- StateMachine:' + aDebugTag + ': ' + aMsg); - } - - var sm = {}; - - var _initialState; - var _curState; - var _prevState; - var _paused; - var _eventQueue = []; - var _deferredEventQueue = []; - var _defaultEventHandler; - - // Public interfaces. - - sm.setDefaultEventHandler = function(aDefaultEventHandler) { - _defaultEventHandler = aDefaultEventHandler; - }; - - sm.start = function(aInitialState) { - _initialState = aInitialState; - sm.gotoState(_initialState); - }; - - sm.sendEvent = function (aEvent) { - if (!_initialState) { - if (DEBUG) { - debug('StateMachine is not running. Call StateMachine.start() first.'); - } - return; - } - _eventQueue.push(aEvent); - asyncCall(handleFirstEvent); - }; - - sm.getPreviousState = function() { - return _prevState; - }; - - sm.getCurrentState = function() { - return _curState; - }; - - // State object maker. - // @param aName string for this state's name. - // @param aDelegate object: - // .handleEvent: required. - // .enter: called before entering this state (optional). - // .exit: called before exiting this state (optional). - sm.makeState = function (aName, aDelegate) { - if (!aDelegate.handleEvent) { - throw "handleEvent is a required delegate function."; - } - var nop = function() {}; - return { - name: aName, - enter: (aDelegate.enter || nop), - exit: (aDelegate.exit || nop), - handleEvent: aDelegate.handleEvent - }; - }; - - sm.deferEvent = function (aEvent) { - // The definition of a 'deferred event' is: - // We are not able to handle this event now but after receiving - // certain event or entering a new state, we might be able to handle - // it. For example, we couldn't handle CONNECT_EVENT in the - // diconnecting state. But once we finish doing "disconnecting", we - // could then handle CONNECT_EVENT! - // - // So, the deferred event may be handled in the following cases: - // 1. Once we entered a new state. - // 2. Once we handled a regular event. - if (DEBUG) { - debug('Deferring event: ' + JSON.stringify(aEvent)); - } - _deferredEventQueue.push(aEvent); - }; - - // Goto the new state. If the current state is null, the exit - // function won't be called. - sm.gotoState = function (aNewState) { - if (_curState) { - if (DEBUG) { - debug("exiting state: " + _curState.name); - } - _curState.exit(); - } - - _prevState = _curState; - _curState = aNewState; - - if (DEBUG) { - debug("entering state: " + _curState.name); - } - _curState.enter(); - - // We are in the new state now. We got a chance to handle the - // deferred events. - handleDeferredEvents(); - - sm.resume(); - }; - - // No incoming event will be handled after you call pause(). - // (But they will be queued.) - sm.pause = function() { - _paused = true; - }; - - // Continue to handle incoming events. - sm.resume = function() { - _paused = false; - asyncCall(handleFirstEvent); - }; - - //---------------------------------------------------------- - // Private stuff - //---------------------------------------------------------- - - function asyncCall(f) { - Services.tm.currentThread.dispatch(f, Ci.nsIThread.DISPATCH_NORMAL); - } - - function handleFirstEvent() { - var hadDeferredEvents; - - if (0 === _eventQueue.length) { - return; - } - - if (_paused) { - return; // The state machine is paused now. - } - - hadDeferredEvents = _deferredEventQueue.length > 0; - - handleOneEvent(_eventQueue.shift()); // The handler may defer this event. - - // We've handled one event. If we had deferred events before, now is - // a good chance to handle them. - if (hadDeferredEvents) { - handleDeferredEvents(); - } - - // Continue to handle the next regular event. - handleFirstEvent(); - } - - function handleDeferredEvents() { - if (_deferredEventQueue.length && DEBUG) { - debug('Handle deferred events: ' + _deferredEventQueue.length); - } - for (let i = 0; i < _deferredEventQueue.length; i++) { - handleOneEvent(_deferredEventQueue.shift()); - } - } - - function handleOneEvent(aEvent) - { - if (DEBUG) { - debug('Handling event: ' + JSON.stringify(aEvent)); - } - - var handled = _curState.handleEvent(aEvent); - - if (undefined === handled) { - throw "handleEvent returns undefined: " + _curState.name; - } - if (!handled) { - // Event is not handled in the current state. Try handleEventCommon(). - handled = (_defaultEventHandler ? _defaultEventHandler(aEvent) : handled); - } - if (undefined === handled) { - throw "handleEventCommon returns undefined: " + _curState.name; - } - if (!handled) { - if (DEBUG) { - debug('!!!!!!!!! FIXME !!!!!!!!! Event not handled: ' + JSON.stringify(aEvent)); - } - } - - return handled; - } - - return sm; -}; diff --git a/dom/wifi/WifiCertService.cpp b/dom/wifi/WifiCertService.cpp deleted file mode 100644 index 85e0d2f5b..000000000 --- a/dom/wifi/WifiCertService.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "WifiCertService.h" - -#include "mozilla/ClearOnShutdown.h" -#include "mozilla/EndianUtils.h" -#include "mozilla/ModuleUtils.h" -#include "mozilla/RefPtr.h" -#include "mozilla/dom/File.h" -#include "mozilla/dom/ToJSValue.h" -#include "cert.h" -#include "certdb.h" -#include "CryptoTask.h" -#include "nsIDOMBlob.h" -#include "nsIWifiService.h" -#include "nsNetUtil.h" -#include "nsIInputStream.h" -#include "nsServiceManagerUtils.h" -#include "nsXULAppAPI.h" -#include "ScopedNSSTypes.h" - -#define NS_WIFICERTSERVICE_CID \ - { 0x83585afd, 0x0e11, 0x43aa, {0x83, 0x46, 0xf3, 0x4d, 0x97, 0x5e, 0x46, 0x77} } - -using namespace mozilla; -using namespace mozilla::dom; - -namespace mozilla { - -// The singleton Wifi Cert service, to be used on the main thread. -StaticRefPtr<WifiCertService> gWifiCertService; - -class ImportCertTask final: public CryptoTask -{ -public: - ImportCertTask(int32_t aId, Blob* aCertBlob, - const nsAString& aCertPassword, - const nsAString& aCertNickname) - : mBlob(aCertBlob) - , mPassword(aCertPassword) - { - MOZ_ASSERT(NS_IsMainThread()); - - mResult.mId = aId; - mResult.mStatus = 0; - mResult.mUsageFlag = 0; - mResult.mNickname = aCertNickname; - } - -private: - virtual void ReleaseNSSResources() {} - - virtual nsresult CalculateResult() override - { - MOZ_ASSERT(!NS_IsMainThread()); - - // read data from blob. - nsCString blobBuf; - nsresult rv = ReadBlob(blobBuf); - if (NS_FAILED(rv)) { - return rv; - } - - char* buf; - uint32_t size = blobBuf.GetMutableData(&buf); - if (size == 0) { - return NS_ERROR_OUT_OF_MEMORY; - } - - // Try import as DER format first. - rv = ImportDERBlob(buf, size); - if (NS_SUCCEEDED(rv)) { - return rv; - } - - // Try import as PKCS#12 format. - return ImportPKCS12Blob(buf, size, mPassword); - } - - virtual void CallCallback(nsresult rv) - { - if (NS_FAILED(rv)) { - mResult.mStatus = -1; - } - gWifiCertService->DispatchResult(mResult); - } - - nsresult ImportDERBlob(char* buf, uint32_t size) - { - // Create certificate object. - ScopedCERTCertificate cert(CERT_DecodeCertFromPackage(buf, size)); - if (!cert) { - return MapSECStatus(SECFailure); - } - - // Import certificate. - return ImportCert(cert); - } - - static SECItem* - HandleNicknameCollision(SECItem* aOldNickname, PRBool* aCancel, void* aWincx) - { - const char* dummyName = "Imported User Cert"; - const size_t dummyNameLen = strlen(dummyName); - SECItem* newNick = ::SECITEM_AllocItem(nullptr, nullptr, dummyNameLen + 1); - if (!newNick) { - return nullptr; - } - - newNick->type = siAsciiString; - // Dummy name, will be renamed later. - memcpy(newNick->data, dummyName, dummyNameLen + 1); - newNick->len = dummyNameLen; - - return newNick; - } - - static SECStatus - HandleNicknameUpdate(const CERTCertificate *aCert, - const SECItem *default_nickname, - SECItem **new_nickname, - void *arg) - { - WifiCertServiceResultOptions *result = (WifiCertServiceResultOptions *)arg; - - nsCString userNickname; - CopyUTF16toUTF8(result->mNickname, userNickname); - - nsCString fullNickname; - if (aCert->isRoot && (aCert->nsCertType & NS_CERT_TYPE_SSL_CA)) { - // Accept self-signed SSL CA as server certificate. - fullNickname.AssignLiteral("WIFI_SERVERCERT_"); - fullNickname += userNickname; - result->mUsageFlag |= nsIWifiCertService::WIFI_CERT_USAGE_FLAG_SERVER; - } else if (aCert->nsCertType & NS_CERT_TYPE_SSL_CLIENT) { - // User Certificate - fullNickname.AssignLiteral("WIFI_USERCERT_"); - fullNickname += userNickname; - result->mUsageFlag |= nsIWifiCertService::WIFI_CERT_USAGE_FLAG_USER; - } - char* nickname; - uint32_t length = fullNickname.GetMutableData(&nickname); - - SECItem* newNick = ::SECITEM_AllocItem(nullptr, nullptr, length + 1); - if (!newNick) { - return SECFailure; - } - - newNick->type = siAsciiString; - memcpy(newNick->data, nickname, length + 1); - newNick->len = length; - - *new_nickname = newNick; - return SECSuccess; - } - - nsresult ImportPKCS12Blob(char* buf, uint32_t size, const nsAString& aPassword) - { - nsString password(aPassword); - - // password is null-terminated wide-char string. - // passwordItem is required to be big-endian form of password, stored in char - // array, including the null-termination. - uint32_t length = password.Length() + 1; - ScopedSECItem passwordItem( - ::SECITEM_AllocItem(nullptr, nullptr, length * sizeof(nsString::char_type))); - - if (!passwordItem) { - return NS_ERROR_FAILURE; - } - - mozilla::NativeEndian::copyAndSwapToBigEndian(passwordItem->data, - password.BeginReading(), - length); - // Create a decoder. - ScopedSEC_PKCS12DecoderContext p12dcx(SEC_PKCS12DecoderStart( - passwordItem, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr)); - - if (!p12dcx) { - return NS_ERROR_FAILURE; - } - - // Assign data to decorder. - SECStatus srv = SEC_PKCS12DecoderUpdate(p12dcx, - reinterpret_cast<unsigned char*>(buf), - size); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - // Verify certificates. - srv = SEC_PKCS12DecoderVerify(p12dcx); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - // Set certificate nickname and usage flag. - srv = SEC_PKCS12DecoderRenameCertNicknames(p12dcx, HandleNicknameUpdate, - &mResult); - - // Validate certificates. - srv = SEC_PKCS12DecoderValidateBags(p12dcx, HandleNicknameCollision); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - // Initialize slot. - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (!slot) { - return NS_ERROR_FAILURE; - } - if (PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) { - srv = PK11_InitPin(slot, "", ""); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - } - - // Import cert and key. - srv = SEC_PKCS12DecoderImportBags(p12dcx); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - // User certificate must be imported from PKCS#12. - return (mResult.mUsageFlag & nsIWifiCertService::WIFI_CERT_USAGE_FLAG_USER) - ? NS_OK : NS_ERROR_FAILURE; - } - - nsresult ReadBlob(/*out*/ nsCString& aBuf) - { - NS_ENSURE_ARG_POINTER(mBlob); - - static const uint64_t MAX_FILE_SIZE = 16384; - - ErrorResult rv; - uint64_t size = mBlob->GetSize(rv); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); - } - - if (size > MAX_FILE_SIZE) { - return NS_ERROR_FILE_TOO_BIG; - } - - nsCOMPtr<nsIInputStream> inputStream; - mBlob->GetInternalStream(getter_AddRefs(inputStream), rv); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); - } - - rv = NS_ReadInputStreamToString(inputStream, aBuf, (uint32_t)size); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); - } - - return NS_OK; - } - - nsresult ImportCert(CERTCertificate* aCert) - { - nsCString userNickname, fullNickname; - - CopyUTF16toUTF8(mResult.mNickname, userNickname); - // Determine certificate nickname by adding prefix according to its type. - if (aCert->isRoot && (aCert->nsCertType & NS_CERT_TYPE_SSL_CA)) { - // Accept self-signed SSL CA as server certificate. - fullNickname.AssignLiteral("WIFI_SERVERCERT_"); - fullNickname += userNickname; - mResult.mUsageFlag |= nsIWifiCertService::WIFI_CERT_USAGE_FLAG_SERVER; - } else if (aCert->nsCertType & NS_CERT_TYPE_SSL_CLIENT) { - // User Certificate - fullNickname.AssignLiteral("WIFI_USERCERT_"); - fullNickname += userNickname; - mResult.mUsageFlag |= nsIWifiCertService::WIFI_CERT_USAGE_FLAG_USER; - } else { - return NS_ERROR_ABORT; - } - - char* nickname; - uint32_t length; - length = fullNickname.GetMutableData(&nickname); - if (length == 0) { - return NS_ERROR_UNEXPECTED; - } - - // Import certificate, duplicated nickname will cause error. - SECStatus srv = CERT_AddTempCertToPerm(aCert, nickname, nullptr); - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - return NS_OK; - } - - RefPtr<Blob> mBlob; - nsString mPassword; - WifiCertServiceResultOptions mResult; -}; - -class DeleteCertTask final: public CryptoTask -{ -public: - DeleteCertTask(int32_t aId, const nsAString& aCertNickname) - { - MOZ_ASSERT(NS_IsMainThread()); - - mResult.mId = aId; - mResult.mStatus = 0; - mResult.mUsageFlag = 0; - mResult.mNickname = aCertNickname; - } - -private: - virtual void ReleaseNSSResources() {} - - virtual nsresult CalculateResult() override - { - MOZ_ASSERT(!NS_IsMainThread()); - - nsCString userNickname; - CopyUTF16toUTF8(mResult.mNickname, userNickname); - - // Delete server certificate. - nsCString serverCertName("WIFI_SERVERCERT_", 16); - serverCertName += userNickname; - nsresult rv = deleteCert(serverCertName); - if (NS_FAILED(rv)) { - return rv; - } - - // Delete user certificate and private key. - nsCString userCertName("WIFI_USERCERT_", 14); - userCertName += userNickname; - rv = deleteCert(userCertName); - if (NS_FAILED(rv)) { - return rv; - } - - return NS_OK; - } - - nsresult deleteCert(const nsCString &aCertNickname) - { - ScopedCERTCertificate cert( - CERT_FindCertByNickname(CERT_GetDefaultCertDB(), aCertNickname.get()) - ); - // Because we delete certificates in blind, so it's acceptable to delete - // a non-exist certificate. - if (!cert) { - return NS_OK; - } - - ScopedPK11SlotInfo slot( - PK11_KeyForCertExists(cert, nullptr, nullptr) - ); - - SECStatus srv; - if (slot) { - // Delete private key along with certificate. - srv = PK11_DeleteTokenCertAndKey(cert, nullptr); - } else { - srv = SEC_DeletePermCertificate(cert); - } - - if (srv != SECSuccess) { - return MapSECStatus(srv); - } - - return NS_OK; - } - - virtual void CallCallback(nsresult rv) - { - if (NS_FAILED(rv)) { - mResult.mStatus = -1; - } - gWifiCertService->DispatchResult(mResult); - } - - WifiCertServiceResultOptions mResult; -}; - -NS_IMPL_ISUPPORTS(WifiCertService, nsIWifiCertService) - -NS_IMETHODIMP -WifiCertService::Start(nsIWifiEventListener* aListener) -{ - MOZ_ASSERT(aListener); - - mListener = aListener; - - return NS_OK; -} - -NS_IMETHODIMP -WifiCertService::Shutdown() -{ - MOZ_ASSERT(NS_IsMainThread()); - - mListener = nullptr; - - return NS_OK; -} - -void -WifiCertService::DispatchResult(const WifiCertServiceResultOptions& aOptions) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mozilla::AutoSafeJSContext cx; - JS::RootedValue val(cx); - nsCString dummyInterface; - - if (!ToJSValue(cx, aOptions, &val)) { - return; - } - - // Certll the listener with a JS value. - mListener->OnCommand(val, dummyInterface); -} - -WifiCertService::WifiCertService() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!gWifiCertService); -} - -WifiCertService::~WifiCertService() -{ - MOZ_ASSERT(!gWifiCertService); - - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - return; - } - shutdown(ShutdownCalledFrom::Object); -} - -already_AddRefed<WifiCertService> -WifiCertService::FactoryCreate() -{ - if (!XRE_IsParentProcess()) { - return nullptr; - } - - MOZ_ASSERT(NS_IsMainThread()); - - if (!gWifiCertService) { - gWifiCertService = new WifiCertService(); - ClearOnShutdown(&gWifiCertService); - } - - RefPtr<WifiCertService> service = gWifiCertService.get(); - return service.forget(); -} - -NS_IMETHODIMP -WifiCertService::ImportCert(int32_t aId, nsIDOMBlob* aCertBlob, - const nsAString& aCertPassword, - const nsAString& aCertNickname) -{ - RefPtr<Blob> blob = static_cast<Blob*>(aCertBlob); - RefPtr<CryptoTask> task = new ImportCertTask(aId, blob, aCertPassword, - aCertNickname); - return task->Dispatch("WifiImportCert"); -} - -NS_IMETHODIMP -WifiCertService::DeleteCert(int32_t aId, const nsAString& aCertNickname) -{ - RefPtr<CryptoTask> task = new DeleteCertTask(aId, aCertNickname); - return task->Dispatch("WifiDeleteCert"); -} - -NS_IMETHODIMP -WifiCertService::HasPrivateKey(const nsAString& aCertNickname, bool *aHasKey) -{ - *aHasKey = false; - - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - return NS_ERROR_NOT_AVAILABLE; - } - - nsCString certNickname; - CopyUTF16toUTF8(aCertNickname, certNickname); - - ScopedCERTCertificate cert( - CERT_FindCertByNickname(CERT_GetDefaultCertDB(), certNickname.get()) - ); - if (!cert) { - return NS_OK; - } - - ScopedPK11SlotInfo slot( - PK11_KeyForCertExists(cert, nullptr, nullptr) - ); - if (slot) { - *aHasKey = true; - } - - return NS_OK; -} - -NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WifiCertService, - WifiCertService::FactoryCreate) - -NS_DEFINE_NAMED_CID(NS_WIFICERTSERVICE_CID); - -static const mozilla::Module::CIDEntry kWifiCertServiceCIDs[] = { - { &kNS_WIFICERTSERVICE_CID, false, nullptr, WifiCertServiceConstructor }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kWifiCertServiceContracts[] = { - { "@mozilla.org/wifi/certservice;1", &kNS_WIFICERTSERVICE_CID }, - { nullptr } -}; - -static const mozilla::Module kWifiCertServiceModule = { - mozilla::Module::kVersion, - kWifiCertServiceCIDs, - kWifiCertServiceContracts, - nullptr -}; - -} // namespace mozilla - -NSMODULE_DEFN(WifiCertServiceModule) = &kWifiCertServiceModule; diff --git a/dom/wifi/WifiCertService.h b/dom/wifi/WifiCertService.h deleted file mode 100644 index f542bb0c8..000000000 --- a/dom/wifi/WifiCertService.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef WifiCertService_h -#define WifiCertService_h - -#include "nsIWifiCertService.h" -#include "nsCOMPtr.h" -#include "nsNSSShutDown.h" -#include "nsThread.h" -#include "mozilla/dom/WifiOptionsBinding.h" - -namespace mozilla { -namespace dom { - -class WifiCertService final : public nsIWifiCertService, - public nsNSSShutDownObject -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIWIFICERTSERVICE - - static already_AddRefed<WifiCertService> - FactoryCreate(); - void DispatchResult(const mozilla::dom::WifiCertServiceResultOptions& aOptions); - -private: - WifiCertService(); - ~WifiCertService(); - virtual void virtualDestroyNSSReference() {}; - nsCOMPtr<nsIWifiEventListener> mListener; -}; - -} // namespce dom -} // namespace mozilla - -#endif // WifiCertService_h diff --git a/dom/wifi/WifiCommand.jsm b/dom/wifi/WifiCommand.jsm deleted file mode 100644 index 93b0f1a1e..000000000 --- a/dom/wifi/WifiCommand.jsm +++ /dev/null @@ -1,594 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["WifiCommand"]; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/systemlibs.js"); - -const SUPP_PROP = "init.svc.wpa_supplicant"; -const WPA_SUPPLICANT = "wpa_supplicant"; -const DEBUG = false; - -this.WifiCommand = function(aControlMessage, aInterface, aSdkVersion) { - function debug(msg) { - if (DEBUG) { - dump('-------------- WifiCommand: ' + msg); - } - } - - var command = {}; - - //------------------------------------------------- - // Utilities. - //------------------------------------------------- - command.getSdkVersion = function() { - return aSdkVersion; - }; - - //------------------------------------------------- - // General commands. - //------------------------------------------------- - - command.loadDriver = function (callback) { - voidControlMessage("load_driver", function(status) { - callback(status); - }); - }; - - command.unloadDriver = function (callback) { - voidControlMessage("unload_driver", function(status) { - callback(status); - }); - }; - - command.startSupplicant = function (callback) { - voidControlMessage("start_supplicant", callback); - }; - - command.killSupplicant = function (callback) { - // It is interesting to note that this function does exactly what - // wifi_stop_supplicant does. Unforunately, on the Galaxy S2, Samsung - // changed that function in a way that means that it doesn't recognize - // wpa_supplicant as already running. Therefore, we have to roll our own - // version here. - stopProcess(SUPP_PROP, WPA_SUPPLICANT, callback); - }; - - command.terminateSupplicant = function (callback) { - doBooleanCommand("TERMINATE", "OK", callback); - }; - - command.stopSupplicant = function (callback) { - voidControlMessage("stop_supplicant", callback); - }; - - command.listNetworks = function (callback) { - doStringCommand("LIST_NETWORKS", callback); - }; - - command.addNetwork = function (callback) { - doIntCommand("ADD_NETWORK", callback); - }; - - command.setNetworkVariable = function (netId, name, value, callback) { - doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + - value, "OK", callback); - }; - - command.getNetworkVariable = function (netId, name, callback) { - doStringCommand("GET_NETWORK " + netId + " " + name, callback); - }; - - command.removeNetwork = function (netId, callback) { - doBooleanCommand("REMOVE_NETWORK " + netId, "OK", callback); - }; - - command.enableNetwork = function (netId, disableOthers, callback) { - doBooleanCommand((disableOthers ? "SELECT_NETWORK " : "ENABLE_NETWORK ") + - netId, "OK", callback); - }; - - command.disableNetwork = function (netId, callback) { - doBooleanCommand("DISABLE_NETWORK " + netId, "OK", callback); - }; - - command.status = function (callback) { - doStringCommand("STATUS", callback); - }; - - command.ping = function (callback) { - doBooleanCommand("PING", "PONG", callback); - }; - - command.scanResults = function (callback) { - doStringCommand("SCAN_RESULTS", callback); - }; - - command.disconnect = function (callback) { - doBooleanCommand("DISCONNECT", "OK", callback); - }; - - command.reconnect = function (callback) { - doBooleanCommand("RECONNECT", "OK", callback); - }; - - command.reassociate = function (callback) { - doBooleanCommand("REASSOCIATE", "OK", callback); - }; - - command.setBackgroundScan = function (enable, callback) { - doBooleanCommand("SET pno " + (enable ? "1" : "0"), - "OK", - function(ok) { - callback(true, ok); - }); - }; - - command.doSetScanMode = function (setActive, callback) { - doBooleanCommand(setActive ? - "DRIVER SCAN-ACTIVE" : - "DRIVER SCAN-PASSIVE", "OK", callback); - }; - - command.scan = function (callback) { - doBooleanCommand("SCAN", "OK", callback); - }; - - command.setLogLevel = function (level, callback) { - doBooleanCommand("LOG_LEVEL " + level, "OK", callback); - }; - - command.getLogLevel = function (callback) { - doStringCommand("LOG_LEVEL", callback); - }; - - command.wpsPbc = function (callback, iface) { - let cmd = 'WPS_PBC'; - - // If the network interface is specified and we are based on JB, - // append the argument 'interface=[iface]' to the supplicant command. - // - // Note: The argument "interface" is only required for wifi p2p on JB. - // For other cases, the argument is useless and even leads error. - // Check the evil work here: - // http://androidxref.com/4.2.2_r1/xref/external/wpa_supplicant_8/wpa_supplicant/ctrl_iface_unix.c#172 - // - if (iface && isJellybean()) { - cmd += (' inferface=' + iface); - } - - doBooleanCommand(cmd, "OK", callback); - }; - - command.wpsPin = function (detail, callback) { - let cmd = 'WPS_PIN '; - - // See the comment above in wpsPbc(). - if (detail.iface && isJellybean()) { - cmd += ('inferface=' + iface + ' '); - } - - cmd += (detail.bssid === undefined ? "any" : detail.bssid); - cmd += (detail.pin === undefined ? "" : (" " + detail.pin)); - - doStringCommand(cmd, callback); - }; - - command.wpsCancel = function (callback) { - doBooleanCommand("WPS_CANCEL", "OK", callback); - }; - - command.startDriver = function (callback) { - doBooleanCommand("DRIVER START", "OK"); - }; - - command.stopDriver = function (callback) { - doBooleanCommand("DRIVER STOP", "OK"); - }; - - command.startPacketFiltering = function (callback) { - var commandChain = ["DRIVER RXFILTER-ADD 0", - "DRIVER RXFILTER-ADD 1", - "DRIVER RXFILTER-ADD 3", - "DRIVER RXFILTER-START"]; - - doBooleanCommandChain(commandChain, callback); - }; - - command.stopPacketFiltering = function (callback) { - var commandChain = ["DRIVER RXFILTER-STOP", - "DRIVER RXFILTER-REMOVE 3", - "DRIVER RXFILTER-REMOVE 1", - "DRIVER RXFILTER-REMOVE 0"]; - - doBooleanCommandChain(commandChain, callback); - }; - - command.doGetRssi = function (cmd, callback) { - doCommand(cmd, function(data) { - var rssi = -200; - - if (!data.status) { - // If we are associating, the reply is "OK". - var reply = data.reply; - if (reply !== "OK") { - // Format is: <SSID> rssi XX". SSID can contain spaces. - var offset = reply.lastIndexOf("rssi "); - if (offset !== -1) { - rssi = reply.substr(offset + 5) | 0; - } - } - } - callback(rssi); - }); - }; - - command.getRssi = function (callback) { - command.doGetRssi("DRIVER RSSI", callback); - }; - - command.getRssiApprox = function (callback) { - command.doGetRssi("DRIVER RSSI-APPROX", callback); - }; - - command.getLinkSpeed = function (callback) { - doStringCommand("DRIVER LINKSPEED", function(reply) { - if (reply) { - reply = reply.split(" ")[1] | 0; // Format: LinkSpeed XX - } - callback(reply); - }); - }; - - let infoKeys = [{regexp: /RSSI=/i, prop: 'rssi'}, - {regexp: /LINKSPEED=/i, prop: 'linkspeed'}]; - - command.getConnectionInfoICS = function (callback) { - doStringCommand("SIGNAL_POLL", function(reply) { - if (!reply) { - callback(null); - return; - } - - // Find any values matching |infoKeys|. This gets executed frequently - // enough that we want to avoid creating intermediate strings as much as - // possible. - let rval = {}; - for (let i = 0; i < infoKeys.length; i++) { - let re = infoKeys[i].regexp; - let iKeyStart = reply.search(re); - if (iKeyStart !== -1) { - let prop = infoKeys[i].prop; - let iValueStart = reply.indexOf('=', iKeyStart) + 1; - let iNewlineAfterValue = reply.indexOf('\n', iValueStart); - let iValueEnd = iNewlineAfterValue !== -1 - ? iNewlineAfterValue - : reply.length; - rval[prop] = reply.substring(iValueStart, iValueEnd) | 0; - } - } - - callback(rval); - }); - }; - - command.getMacAddress = function (callback) { - doStringCommand("DRIVER MACADDR", function(reply) { - if (reply) { - reply = reply.split(" ")[2]; // Format: Macaddr = XX.XX.XX.XX.XX.XX - } - callback(reply); - }); - }; - - command.connectToHostapd = function(callback) { - voidControlMessage("connect_to_hostapd", callback); - }; - - command.closeHostapdConnection = function(callback) { - voidControlMessage("close_hostapd_connection", callback); - }; - - command.hostapdCommand = function (callback, request) { - var msg = { cmd: "hostapd_command", - request: request, - iface: aInterface }; - - aControlMessage(msg, function(data) { - callback(data.status ? null : data.reply); - }); - }; - - command.hostapdGetStations = function (callback) { - var msg = { cmd: "hostapd_get_stations", - iface: aInterface }; - - aControlMessage(msg, function(data) { - callback(data.status); - }); - }; - - command.setPowerModeICS = function (mode, callback) { - doBooleanCommand("DRIVER POWERMODE " + (mode === "AUTO" ? 0 : 1), "OK", callback); - }; - - command.setPowerModeJB = function (mode, callback) { - doBooleanCommand("SET ps " + (mode === "AUTO" ? 1 : 0), "OK", callback); - }; - - command.getPowerMode = function (callback) { - doStringCommand("DRIVER GETPOWER", function(reply) { - if (reply) { - reply = (reply.split()[2]|0); // Format: powermode = XX - } - callback(reply); - }); - }; - - command.setNumAllowedChannels = function (numChannels, callback) { - doBooleanCommand("DRIVER SCAN-CHANNELS " + numChannels, "OK", callback); - }; - - command.getNumAllowedChannels = function (callback) { - doStringCommand("DRIVER SCAN-CHANNELS", function(reply) { - if (reply) { - reply = (reply.split()[2]|0); // Format: Scan-Channels = X - } - callback(reply); - }); - }; - - command.setBluetoothCoexistenceMode = function (mode, callback) { - doBooleanCommand("DRIVER BTCOEXMODE " + mode, "OK", callback); - }; - - command.setBluetoothCoexistenceScanMode = function (mode, callback) { - doBooleanCommand("DRIVER BTCOEXSCAN-" + (mode ? "START" : "STOP"), - "OK", callback); - }; - - command.saveConfig = function (callback) { - // Make sure we never write out a value for AP_SCAN other than 1. - doBooleanCommand("AP_SCAN 1", "OK", function(ok) { - doBooleanCommand("SAVE_CONFIG", "OK", callback); - }); - }; - - command.reloadConfig = function (callback) { - doBooleanCommand("RECONFIGURE", "OK", callback); - }; - - command.setScanResultHandling = function (mode, callback) { - doBooleanCommand("AP_SCAN " + mode, "OK", callback); - }; - - command.addToBlacklist = function (bssid, callback) { - doBooleanCommand("BLACKLIST " + bssid, "OK", callback); - }; - - command.clearBlacklist = function (callback) { - doBooleanCommand("BLACKLIST clear", "OK", callback); - }; - - command.setSuspendOptimizationsICS = function (enabled, callback) { - doBooleanCommand("DRIVER SETSUSPENDOPT " + (enabled ? 0 : 1), - "OK", callback); - }; - - command.setSuspendOptimizationsJB = function (enabled, callback) { - doBooleanCommand("DRIVER SETSUSPENDMODE " + (enabled ? 1 : 0), - "OK", callback); - }; - - command.connectToSupplicant = function(callback) { - voidControlMessage("connect_to_supplicant", callback); - }; - - command.closeSupplicantConnection = function(callback) { - voidControlMessage("close_supplicant_connection", callback); - }; - - command.getMacAddress = function(callback) { - doStringCommand("DRIVER MACADDR", function(reply) { - if (reply) { - reply = reply.split(" ")[2]; // Format: Macaddr = XX.XX.XX.XX.XX.XX - } - callback(reply); - }); - }; - - command.setDeviceName = function(deviceName, callback) { - doBooleanCommand("SET device_name " + deviceName, "OK", callback); - }; - - //------------------------------------------------- - // P2P commands. - //------------------------------------------------- - - command.p2pProvDiscovery = function(address, wpsMethod, callback) { - var command = "P2P_PROV_DISC " + address + " " + wpsMethod; - doBooleanCommand(command, "OK", callback); - }; - - command.p2pConnect = function(config, callback) { - var command = "P2P_CONNECT " + config.address + " " + config.wpsMethodWithPin + " "; - if (config.joinExistingGroup) { - command += "join"; - } else { - command += "go_intent=" + config.goIntent; - } - - debug('P2P connect command: ' + command); - doBooleanCommand(command, "OK", callback); - }; - - command.p2pGroupRemove = function(iface, callback) { - debug("groupRemove()"); - doBooleanCommand("P2P_GROUP_REMOVE " + iface, "OK", callback); - }; - - command.p2pEnable = function(detail, callback) { - var commandChain = ["SET device_name " + detail.deviceName, - "SET device_type " + detail.deviceType, - "SET config_methods " + detail.wpsMethods, - "P2P_SET conc_pref sta", - "P2P_FLUSH"]; - - doBooleanCommandChain(commandChain, callback); - }; - - command.p2pDisable = function(callback) { - doBooleanCommand("P2P_SET disabled 1", "OK", callback); - }; - - command.p2pEnableScan = function(timeout, callback) { - doBooleanCommand("P2P_FIND " + timeout, "OK", callback); - }; - - command.p2pDisableScan = function(callback) { - doBooleanCommand("P2P_STOP_FIND", "OK", callback); - }; - - command.p2pGetGroupCapab = function(address, callback) { - command.p2pPeer(address, function(reply) { - debug('p2p_peer reply: ' + reply); - if (!reply) { - callback(0); - return; - } - var capab = /group_capab=0x([0-9a-fA-F]+)/.exec(reply)[1]; - if (!capab) { - callback(0); - } else { - callback(parseInt(capab, 16)); - } - }); - }; - - command.p2pPeer = function(address, callback) { - doStringCommand("P2P_PEER " + address, callback); - }; - - command.p2pGroupAdd = function(netId, callback) { - doBooleanCommand("P2P_GROUP_ADD persistent=" + netId, callback); - }; - - command.p2pReinvoke = function(netId, address, callback) { - doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + address, "OK", callback); - }; - - //---------------------------------------------------------- - // Private stuff. - //---------------------------------------------------------- - - function voidControlMessage(cmd, callback) { - aControlMessage({ cmd: cmd, iface: aInterface }, function (data) { - callback(data.status); - }); - } - - function doCommand(request, callback) { - var msg = { cmd: "command", - request: request, - iface: aInterface }; - - aControlMessage(msg, callback); - } - - function doIntCommand(request, callback) { - doCommand(request, function(data) { - callback(data.status ? -1 : (data.reply|0)); - }); - } - - function doBooleanCommand(request, expected, callback) { - doCommand(request, function(data) { - callback(data.status ? false : (data.reply === expected)); - }); - } - - function doStringCommand(request, callback) { - doCommand(request, function(data) { - callback(data.status ? null : data.reply); - }); - } - - function doBooleanCommandChain(commandChain, callback, i) { - if (undefined === i) { - i = 0; - } - - doBooleanCommand(commandChain[i], "OK", function(ok) { - if (!ok) { - return callback(false); - } - i++; - if (i === commandChain.length || !commandChain[i]) { - // Reach the end or empty command. - return callback(true); - } - doBooleanCommandChain(commandChain, callback, i); - }); - } - - //-------------------------------------------------- - // Helper functions. - //-------------------------------------------------- - - function stopProcess(service, process, callback) { - var count = 0; - var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - function tick() { - let result = libcutils.property_get(service); - if (result === null) { - callback(); - return; - } - if (result === "stopped" || ++count >= 5) { - // Either we succeeded or ran out of time. - timer = null; - callback(); - return; - } - - // Else it's still running, continue waiting. - timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); - } - - setProperty("ctl.stop", process, tick); - } - - // Wrapper around libcutils.property_set that returns true if setting the - // value was successful. - // Note that the callback is not called asynchronously. - function setProperty(key, value, callback) { - let ok = true; - try { - libcutils.property_set(key, value); - } catch(e) { - ok = false; - } - callback(ok); - } - - function isJellybean() { - // According to http://developer.android.com/guide/topics/manifest/uses-sdk-element.html - // ---------------------------------------------------- - // | Platform Version | API Level | VERSION_CODE | - // ---------------------------------------------------- - // | Android 4.1, 4.1.1 | 16 | JELLY_BEAN_MR2 | - // | Android 4.2, 4.2.2 | 17 | JELLY_BEAN_MR1 | - // | Android 4.3 | 18 | JELLY_BEAN | - // ---------------------------------------------------- - return aSdkVersion === 16 || aSdkVersion === 17 || aSdkVersion === 18; - } - - return command; -}; diff --git a/dom/wifi/WifiHotspotUtils.cpp b/dom/wifi/WifiHotspotUtils.cpp deleted file mode 100644 index 5fdb9b76e..000000000 --- a/dom/wifi/WifiHotspotUtils.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "WifiHotspotUtils.h" -#include <dlfcn.h> -#include <errno.h> -#include <string.h> -#include <dirent.h> -#include <stdlib.h> -#include <cutils/properties.h> - -#include "prinit.h" -#include "mozilla/Assertions.h" -#include "mozilla/Sprintf.h" -#include "nsDebug.h" -#include "nsPrintfCString.h" - -static void* sWifiHotspotUtilsLib; -static PRCallOnceType sInitWifiHotspotUtilsLib; -// Socket pair used to exit from a blocking read. -static struct wpa_ctrl* ctrl_conn; -static const char *ctrl_iface_dir = "/data/misc/wifi/hostapd"; -static char *ctrl_ifname = nullptr; - -DEFINE_DLFUNC(wpa_ctrl_open, struct wpa_ctrl*, const char*) -DEFINE_DLFUNC(wpa_ctrl_close, void, struct wpa_ctrl*) -DEFINE_DLFUNC(wpa_ctrl_attach, int32_t, struct wpa_ctrl*) -DEFINE_DLFUNC(wpa_ctrl_detach, int32_t, struct wpa_ctrl*) -DEFINE_DLFUNC(wpa_ctrl_request, int32_t, struct wpa_ctrl*, - const char*, size_t cmd_len, char *reply, - size_t *reply_len, void (*msg_cb)(char *msg, size_t len)) - - -static PRStatus -InitWifiHotspotUtilsLib() -{ - sWifiHotspotUtilsLib = dlopen("/system/lib/libwpa_client.so", RTLD_LAZY); - // We might fail to open the hardware lib. That's OK. - return PR_SUCCESS; -} - -static void* -GetWifiHotspotLibHandle() -{ - PR_CallOnce(&sInitWifiHotspotUtilsLib, InitWifiHotspotUtilsLib); - return sWifiHotspotUtilsLib; -} - -struct wpa_ctrl * -WifiHotspotUtils::openConnection(const char *ifname) -{ - if (!ifname) { - return nullptr; - } - - USE_DLFUNC(wpa_ctrl_open) - ctrl_conn = wpa_ctrl_open(nsPrintfCString("%s/%s", ctrl_iface_dir, ifname).get()); - return ctrl_conn; -} - -int32_t -WifiHotspotUtils::sendCommand(struct wpa_ctrl *ctrl, const char *cmd, - char *reply, size_t *reply_len) -{ - int32_t ret; - - if (!ctrl_conn) { - NS_WARNING(nsPrintfCString("Not connected to hostapd - \"%s\" command dropped.\n", cmd).get()); - return -1; - } - - USE_DLFUNC(wpa_ctrl_request) - ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, nullptr); - if (ret == -2) { - NS_WARNING(nsPrintfCString("'%s' command timed out.\n", cmd).get()); - return -2; - } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) { - return -1; - } - - // Make the reply printable. - reply[*reply_len] = '\0'; - if (strncmp(cmd, "STA-FIRST", 9) == 0 || - strncmp(cmd, "STA-NEXT", 8) == 0) { - char *pos = reply; - - while (*pos && *pos != '\n') - pos++; - *pos = '\0'; - } - - return 0; -} - - -// static -void* -WifiHotspotUtils::GetSharedLibrary() -{ - void* wpaClientLib = GetWifiHotspotLibHandle(); - if (!wpaClientLib) { - NS_WARNING("No /system/lib/libwpa_client.so"); - } - return wpaClientLib; -} - -int32_t WifiHotspotUtils::do_wifi_connect_to_hostapd() -{ - struct dirent *dent; - - DIR *dir = opendir(ctrl_iface_dir); - if (dir) { - while ((dent = readdir(dir))) { - if (strcmp(dent->d_name, ".") == 0 || - strcmp(dent->d_name, "..") == 0) { - continue; - } - ctrl_ifname = strdup(dent->d_name); - break; - } - closedir(dir); - } - - ctrl_conn = openConnection(ctrl_ifname); - if (!ctrl_conn) { - NS_WARNING(nsPrintfCString("Unable to open connection to hostapd on \"%s\": %s", - ctrl_ifname, strerror(errno)).get()); - return -1; - } - - USE_DLFUNC(wpa_ctrl_attach) - if (wpa_ctrl_attach(ctrl_conn) != 0) { - USE_DLFUNC(wpa_ctrl_close) - wpa_ctrl_close(ctrl_conn); - ctrl_conn = nullptr; - return -1; - } - - return 0; -} - -int32_t WifiHotspotUtils::do_wifi_close_hostapd_connection() -{ - if (!ctrl_conn) { - NS_WARNING("Invalid ctrl_conn."); - return -1; - } - - USE_DLFUNC(wpa_ctrl_detach) - if (wpa_ctrl_detach(ctrl_conn) < 0) { - NS_WARNING("Failed to detach wpa_ctrl."); - } - - USE_DLFUNC(wpa_ctrl_close) - wpa_ctrl_close(ctrl_conn); - ctrl_conn = nullptr; - return 0; -} - -int32_t WifiHotspotUtils::do_wifi_hostapd_command(const char *command, - char *reply, - size_t *reply_len) -{ - return sendCommand(ctrl_conn, command, reply, reply_len); -} - -int32_t WifiHotspotUtils::do_wifi_hostapd_get_stations() -{ - char addr[32], cmd[64]; - int stations = 0; - size_t addrLen = sizeof(addr); - - if (sendCommand(ctrl_conn, "STA-FIRST", addr, &addrLen)) { - return 0; - } - stations++; - - SprintfLiteral(cmd, "STA-NEXT %s", addr); - while (sendCommand(ctrl_conn, cmd, addr, &addrLen) == 0) { - stations++; - SprintfLiteral(cmd, "STA-NEXT %s", addr); - } - - return stations; -} diff --git a/dom/wifi/WifiHotspotUtils.h b/dom/wifi/WifiHotspotUtils.h deleted file mode 100644 index 7afdec7da..000000000 --- a/dom/wifi/WifiHotspotUtils.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Abstraction on top of the network support from libnetutils that we - * use to set up network connections. - */ - -#ifndef WifiHotspotUtils_h -#define WifiHotspotUtils_h - -// Forward declaration. -struct wpa_ctrl; - -class WifiHotspotUtils -{ -public: - static void* GetSharedLibrary(); - - int32_t do_wifi_connect_to_hostapd(); - int32_t do_wifi_close_hostapd_connection(); - int32_t do_wifi_hostapd_command(const char *command, - char *reply, - size_t *reply_len); - int32_t do_wifi_hostapd_get_stations(); - -private: - struct wpa_ctrl * openConnection(const char *ifname); - int32_t sendCommand(struct wpa_ctrl *ctrl, const char *cmd, - char *reply, size_t *reply_len); -}; - -// Defines a function type with the right arguments and return type. -#define DEFINE_DLFUNC(name, ret, args...) typedef ret (*FUNC##name)(args); - -// Set up a dlsymed function ready to use. -#define USE_DLFUNC(name) \ - FUNC##name name = (FUNC##name) dlsym(GetSharedLibrary(), #name); \ - if (!name) { \ - MOZ_CRASH("Symbol not found in shared library : " #name); \ - } - -#endif // WifiHotspotUtils_h diff --git a/dom/wifi/WifiNetUtil.jsm b/dom/wifi/WifiNetUtil.jsm deleted file mode 100644 index 2a1866515..000000000 --- a/dom/wifi/WifiNetUtil.jsm +++ /dev/null @@ -1,154 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/systemlibs.js"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -this.EXPORTED_SYMBOLS = ["WifiNetUtil"]; - -const DHCP_PROP = "init.svc.dhcpcd"; -const DHCP = "dhcpcd"; -const DEBUG = false; - -this.WifiNetUtil = function(controlMessage) { - function debug(msg) { - if (DEBUG) { - dump('-------------- NetUtil: ' + msg); - } - } - - var util = {}; - - util.runDhcp = function (ifname, gen, callback) { - util.stopDhcp(ifname, function() { - gNetworkService.dhcpRequest(ifname, function(success, dhcpInfo) { - util.runIpConfig(ifname, dhcpInfo, function(data) { - callback(data, gen); - }); - }); - }); - }; - - util.stopDhcp = function (ifname, callback) { - // This function does exactly what dhcp_stop does. Unforunately, if we call - // this function twice before the previous callback is returned. We may block - // our self waiting for the callback. It slows down the wifi startup procedure. - // Therefore, we have to roll our own version here. - let dhcpService = DHCP_PROP + "_" + ifname; - let suffix = (ifname.substr(0, 3) === "p2p") ? "p2p" : ifname; - let processName = DHCP + "_" + suffix; - - // The implementation of |dhcp_do_request| would wait until the - // |result_prop_name| (e.g. dhcp.wlan0.result) to be non-null - // or 30 second timeout. So we manually change the result property - // to 'ko' to avoid timeout. - // - // http://androidxref.com/4.4.4_r1/xref/system/core/libnetutils/dhcp_utils.c#234 - setProperty('dhcp.' + suffix + '.result', 'ko', function() { - stopProcess(dhcpService, processName, callback); - }); - }; - - util.startDhcpServer = function (config, callback) { - gNetworkService.setDhcpServer(true, config, function (error) { - callback(!error); - }); - }; - - util.stopDhcpServer = function (callback) { - gNetworkService.setDhcpServer(false, null, function (error) { - callback(!error); - }); - }; - - util.runIpConfig = function (name, data, callback) { - if (!data) { - debug("IP config failed to run"); - callback({ info: data }); - return; - } - - setProperty("net." + name + ".dns1", ipToString(data.dns1), - function(ok) { - if (!ok) { - debug("Unable to set net.<ifname>.dns1"); - return; - } - setProperty("net." + name + ".dns2", ipToString(data.dns2), - function(ok) { - if (!ok) { - debug("Unable to set net.<ifname>.dns2"); - return; - } - setProperty("net." + name + ".gw", ipToString(data.gateway), - function(ok) { - if (!ok) { - debug("Unable to set net.<ifname>.gw"); - return; - } - callback({ info: data }); - }); - }); - }); - }; - - //-------------------------------------------------- - // Helper functions. - //-------------------------------------------------- - - function stopProcess(service, process, callback) { - var count = 0; - var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - function tick() { - let result = libcutils.property_get(service); - if (result === null) { - callback(); - return; - } - if (result === "stopped" || ++count >= 5) { - // Either we succeeded or ran out of time. - timer = null; - callback(); - return; - } - - // Else it's still running, continue waiting. - timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); - } - - setProperty("ctl.stop", process, tick); - } - - // Wrapper around libcutils.property_set that returns true if setting the - // value was successful. - // Note that the callback is not called asynchronously. - function setProperty(key, value, callback) { - let ok = true; - try { - libcutils.property_set(key, value); - } catch(e) { - ok = false; - } - callback(ok); - } - - function ipToString(n) { - return String((n >> 0) & 0xFF) + "." + - ((n >> 8) & 0xFF) + "." + - ((n >> 16) & 0xFF) + "." + - ((n >> 24) & 0xFF); - } - - return util; -}; diff --git a/dom/wifi/WifiP2pManager.jsm b/dom/wifi/WifiP2pManager.jsm deleted file mode 100644 index c1b687438..000000000 --- a/dom/wifi/WifiP2pManager.jsm +++ /dev/null @@ -1,1649 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/StateMachine.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/systemlibs.js"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSysMsgr", - "@mozilla.org/system-message-internal;1", - "nsISystemMessagesInternal"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager", - "@mozilla.org/network/manager;1", - "nsINetworkManager"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -this.EXPORTED_SYMBOLS = ["WifiP2pManager"]; - -const EVENT_IGNORED = -1; -const EVENT_UNKNOWN = -2; - -// Events from supplicant for p2p. -const EVENT_P2P_DEVICE_FOUND = 0; -const EVENT_P2P_DEVICE_LOST = 1; -const EVENT_P2P_GROUP_STARTED = 2; -const EVENT_P2P_GROUP_REMOVED = 3; -const EVENT_P2P_PROV_DISC_PBC_REQ = 4; -const EVENT_P2P_PROV_DISC_PBC_RESP = 5; -const EVENT_P2P_PROV_DISC_SHOW_PIN = 6; -const EVENT_P2P_PROV_DISC_ENTER_PIN = 7; -const EVENT_P2P_GO_NEG_REQUEST = 8; -const EVENT_P2P_GO_NEG_SUCCESS = 9; -const EVENT_P2P_GO_NEG_FAILURE = 10; -const EVENT_P2P_GROUP_FORMATION_SUCCESS = 11; -const EVENT_P2P_GROUP_FORMATION_FAILURE = 12; -const EVENT_P2P_FIND_STOPPED = 13; -const EVENT_P2P_INVITATION_RESULT = 14; -const EVENT_P2P_INVITATION_RECEIVED = 15; -const EVENT_P2P_PROV_DISC_FAILURE = 16; - -// Events from supplicant but not p2p specific. -const EVENT_AP_STA_DISCONNECTED = 100; -const EVENT_AP_STA_CONNECTED = 101; - -// Events from DOM. -const EVENT_P2P_SET_PAIRING_CONFIRMATION = 1000; -const EVENT_P2P_CMD_CONNECT = 1001; -const EVENT_P2P_CMD_DISCONNECT = 1002; -const EVENT_P2P_CMD_ENABLE = 1003; -const EVENT_P2P_CMD_DISABLE = 1004; -const EVENT_P2P_CMD_ENABLE_SCAN = 1005; -const EVENT_P2P_CMD_DISABLE_SCAN = 1006; -const EVENT_P2P_CMD_BLOCK_SCAN = 1007; -const EVENT_P2P_CMD_UNBLOCK_SCAN = 1008; - -// Internal events. -const EVENT_TIMEOUT_PAIRING_CONFIRMATION = 10000; -const EVENT_TIMEOUT_NEG_REQ = 10001; -const EVENT_TIMEOUT_CONNECTING = 10002; -const EVENT_P2P_ENABLE_SUCCESS = 10003; -const EVENT_P2P_ENABLE_FAILED = 10004; -const EVENT_P2P_DISABLE_SUCCESS = 10005; - -// WPS method string. -const WPS_METHOD_PBC = "pbc"; -const WPS_METHOD_DISPLAY = "display"; -const WPS_METHOD_KEYPAD = "keypad"; - -// Role string. -const P2P_ROLE_GO = "GO"; -const P2P_ROLE_CLIENT = "client"; - -// System message for pairing request. -const PAIRING_REQUEST_SYS_MSG = "wifip2p-pairing-request"; - -// Configuration. -const P2P_INTERFACE_NAME = "p2p0"; -const DEFAULT_GO_INTENT = 15; -const DEFAULT_P2P_DEVICE_NAME = "FirefoxPhone"; -const P2P_SCAN_TIMEOUT_SEC = 120; -const DEFAULT_P2P_WPS_METHODS = "virtual_push_button physical_display keypad"; // For wpa_supplicant. -const DEFAULT_P2P_DEVICE_TYPE = "10-0050F204-5"; // For wpa_supplicant. - -const GO_NETWORK_INTERFACE = { - ip: "192.168.2.1", - maskLength: 24, - gateway: "192.168.2.1", - dns1: "0.0.0.0", - dns2: "0.0.0.0", - dhcpServer: "192.168.2.1" -}; - -const GO_DHCP_SERVER_IP_RANGE = { - startIp: "192.168.2.10", - endIp: "192.168.2.30" -}; - -var gDebug = false; - -// Device Capability bitmap -const DEVICE_CAPAB_SERVICE_DISCOVERY = 1; -const DEVICE_CAPAB_CLIENT_DISCOVERABILITY = 1<<1; -const DEVICE_CAPAB_CONCURRENT_OPER = 1<<2; -const DEVICE_CAPAB_INFRA_MANAGED = 1<<3; -const DEVICE_CAPAB_DEVICE_LIMIT = 1<<4; -const DEVICE_CAPAB_INVITATION_PROCEDURE = 1<<5; - -// Group Capability bitmap -const GROUP_CAPAB_GROUP_OWNER = 1; -const GROUP_CAPAB_PERSISTENT_GROUP = 1<<1; -const GROUP_CAPAB_GROUP_LIMIT = 1<<2; -const GROUP_CAPAB_INTRA_BSS_DIST = 1<<3; -const GROUP_CAPAB_CROSS_CONN = 1<<4; -const GROUP_CAPAB_PERSISTENT_RECONN = 1<<5; -const GROUP_CAPAB_GROUP_FORMATION = 1<<6; - -// Constants defined in wpa_supplicants. -const DEV_PW_REGISTRAR_SPECIFIED = 5; -const DEV_PW_USER_SPECIFIED = 1; -const DEV_PW_PUSHBUTTON = 4; - -this.WifiP2pManager = function (aP2pCommand, aNetUtil) { - function debug(aMsg) { - if (gDebug) { - dump('-------------- WifiP2pManager: ' + aMsg); - } - } - - let manager = {}; - - let _stateMachine = P2pStateMachine(aP2pCommand, aNetUtil); - - // Set debug flag to true or false. - // - // @param aDebug Boolean to indicate enabling or disabling the debug flag. - manager.setDebug = function(aDebug) { - gDebug = aDebug; - }; - - // Set observer of observing internal state machine events. - // - // @param aObserver Used to notify WifiWorker what's happening - // in the internal p2p state machine. - manager.setObserver = function(aObserver) { - _stateMachine.setObserver(aObserver); - }; - - // Handle wpa_supplicant events. - // - // @param aEventString string from wpa_supplicant. - manager.handleEvent = function(aEventString) { - let event = parseEventString(aEventString); - if (EVENT_UNKNOWN === event.id || EVENT_IGNORED === event.id) { - debug('Unknow or ignored event: ' + aEventString); - return false; - } - return _stateMachine.sendEvent(event); - }; - - // Set the confirmation of pairing request. - // - // @param aResult Object of confirmation result which contains: - // .accepted: user granted. - // .pin: pin code which is displaying or input by user. - // .wpsMethod: string of "pbc" or "display" or "keypad". - manager.setPairingConfirmation = function(aResult) { - let event = { - id: EVENT_P2P_SET_PAIRING_CONFIRMATION, - info: { - accepted: aResult.accepted, - pin: aResult.pin - } - }; - _stateMachine.sendEvent(event); - }; - - // Connect to a known peer. - // - // @param aAddress MAC address of the peer to connect. - // @param aWpsMethod String of "pbc" or "display" or "keypad". - // @param aGoIntent Number from 0 to 15. - // @param aCallback Callback |true| on attempting to connect. - // |false| on failed to connect. - manager.connect = function(aAddress, aWpsMethod, aGoIntent, aCallback) { - let event = { - id: EVENT_P2P_CMD_CONNECT, - info: { - wpsMethod: aWpsMethod, - address: aAddress, - goIntent: aGoIntent, - onDoConnect: aCallback - } - }; - _stateMachine.sendEvent(event); - }; - - // Disconnect with a known peer. - // - // @param aAddress The address the user desires to disconect. - // @param aCallback Callback |true| on "attempting" to disconnect. - // |false| on failed to disconnect. - manager.disconnect = function(aAddress, aCallback) { - let event = { - id: EVENT_P2P_CMD_DISCONNECT, - info: { - address: aAddress, - onDoDisconnect: aCallback - } - }; - _stateMachine.sendEvent(event); - }; - - // Enable/disable wifi p2p. - // - // @param aEnabled |true| to enable, |false| to disable. - // @param aCallbacks object for callbacks: - // .onEnabled - // .onDisabled - // .onSupplicantConnected - manager.setEnabled = function(aEnabled, aCallbacks) { - let event = { - id: (aEnabled ? EVENT_P2P_CMD_ENABLE : EVENT_P2P_CMD_DISABLE), - info: { - onEnabled: aCallbacks.onEnabled, - onDisabled: aCallbacks.onDisabled, - onSupplicantConnected: aCallbacks.onSupplicantConnected - } - }; - _stateMachine.sendEvent(event); - }; - - // Enable/disable the wifi p2p scan. - // - // @param aEnabled |true| to enable scan, |false| to disable scan. - // @param aCallback Callback |true| on success to enable/disable scan. - // |false| on failed to enable/disable scan. - manager.setScanEnabled = function(aEnabled, aCallback) { - let event = { - id: (aEnabled ? EVENT_P2P_CMD_ENABLE_SCAN : EVENT_P2P_CMD_DISABLE_SCAN), - info: { callback: aCallback } - }; - _stateMachine.sendEvent(event); - }; - - // Block wifi p2p scan. - manager.blockScan = function() { - _stateMachine.sendEvent({ id: EVENT_P2P_CMD_BLOCK_SCAN }); - }; - - // Un-block and do the pending scan if any. - manager.unblockScan = function() { - _stateMachine.sendEvent({ id: EVENT_P2P_CMD_UNBLOCK_SCAN }); - }; - - // Set the p2p device name. - manager.setDeviceName = function(newDeivceName, callback) { - aP2pCommand.setDeviceName(newDeivceName, callback); - }; - - // Parse wps_supplicant event string. - // - // @param aEventString The raw event string from wpa_supplicant. - // - // @return Object: - // .id: a number to represent an event. - // .info: the additional information carried by this event string. - function parseEventString(aEventString) { - if (isIgnoredEvent(aEventString)) { - return { id: EVENT_IGNORED }; - } - - let match = RegExp("p2p_dev_addr=([0-9a-fA-F:]+) " + - "pri_dev_type=([0-9a-zA-Z-]+) " + - "name='(.*)' " + - "config_methods=0x([0-9a-fA-F]+) " + - "dev_capab=0x([0-9a-fA-F]+) " + - "group_capab=0x([0-9a-fA-F]+) ").exec(aEventString + ' '); - - let tokens = aEventString.split(" "); - - let id = EVENT_UNKNOWN; - - // general info. - let info = {}; - - if (match) { - info = { - address: match[1] ? match[1] : null, - type: match[2] ? match[2] : null, - name: match[3] ? match[3] : null, - wpsFlag: match[4] ? parseInt(match[4], 16) : null, - devFlag: match[5] ? parseInt(match[5], 16) : null, - groupFlag: match[6] ? parseInt(match[6], 16) : null - }; - } - - if (0 === aEventString.indexOf("P2P-DEVICE-FOUND")) { - id = EVENT_P2P_DEVICE_FOUND; - info.wpsCapabilities = wpsFlagToCapabilities(info.wpsFlag); - info.isGroupOwner = isPeerGroupOwner(info.groupFlag); - } else if (0 === aEventString.indexOf("P2P-DEVICE-LOST")) { - // e.g. "P2P-DEVICE-LOST p2p_dev_addr=5e:0a:5b:15:1f:80". - id = EVENT_P2P_DEVICE_LOST; - info.address = /p2p_dev_addr=([0-9a-f:]+)/.exec(aEventString)[1]; - } else if (0 === aEventString.indexOf("P2P-GROUP-STARTED")) { - // e.g. "P2P-GROUP-STARTED wlan0-p2p-0 GO ssid="DIRECT-3F Testing - // passphrase="12345678" go_dev_addr=02:40:61:c2:f3:b7 [PERSISTENT]". - - id = EVENT_P2P_GROUP_STARTED; - let groupMatch = RegExp('ssid="(.*)" ' + - 'freq=([0-9]*) ' + - '(passphrase|psk)=([^ ]+) ' + - 'go_dev_addr=([0-9a-f:]+)').exec(aEventString); - info.ssid = groupMatch[1]; - info.freq = groupMatch[2]; - if ('passphrase' === groupMatch[3]) { - let s = groupMatch[4]; // e.g. "G7jHkkz9". - info.passphrase = s.substring(1, s.length-1); // Trim the double quote. - } else { // psk - info.psk = groupMatch[4]; - } - info.goAddress = groupMatch[5]; - info.ifname = tokens[1]; - info.role = tokens[2]; - } else if (0 === aEventString.indexOf("P2P-GROUP-REMOVED")) { - id = EVENT_P2P_GROUP_REMOVED; - // e.g. "P2P-GROUP-REMOVED wlan0-p2p-0 GO". - info.ifname = tokens[1]; - info.role = tokens[2]; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-PBC-REQ")) { - id = EVENT_P2P_PROV_DISC_PBC_REQ; - info.wpsMethod = WPS_METHOD_PBC; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-PBC-RESP")) { - id = EVENT_P2P_PROV_DISC_PBC_RESP; - // The address is different from the general pattern. - info.address = aEventString.split(" ")[1]; - info.wpsMethod = WPS_METHOD_PBC; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-SHOW-PIN")) { - id = EVENT_P2P_PROV_DISC_SHOW_PIN; - // Obtain peer address and pin from tokens. - info.address = tokens[1]; - info.pin = tokens[2]; - info.wpsMethod = WPS_METHOD_DISPLAY; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-ENTER-PIN")) { - id = EVENT_P2P_PROV_DISC_ENTER_PIN; - // Obtain peer address from tokens. - info.address = tokens[1]; - info.wpsMethod = WPS_METHOD_KEYPAD; - } else if (0 === aEventString.indexOf("P2P-GO-NEG-REQUEST")) { - id = EVENT_P2P_GO_NEG_REQUEST; - info.address = tokens[1]; - switch (parseInt(tokens[2].split("=")[1], 10)) { - case DEV_PW_REGISTRAR_SPECIFIED: // (5) Peer is display. - info.wpsMethod = WPS_METHOD_KEYPAD; - break; - case DEV_PW_USER_SPECIFIED: // (1) Peer is keypad. - info.wpsMethod = WPS_METHOD_DISPLAY; - break; - case DEV_PW_PUSHBUTTON: // (4) Peer is pbc. - info.wpsMethod = WPS_METHOD_PBC; - break; - default: - debug('Unknown wps method from event P2P-GO-NEG-REQUEST'); - break; - } - } else if (0 === aEventString.indexOf("P2P-GO-NEG-SUCCESS")) { - id = EVENT_P2P_GO_NEG_SUCCESS; - } else if (0 === aEventString.indexOf("P2P-GO-NEG-FAILURE")) { - id = EVENT_P2P_GO_NEG_FAILURE; - } else if (0 === aEventString.indexOf("P2P-GROUP-FORMATION-FAILURE")) { - id = EVENT_P2P_GROUP_FORMATION_FAILURE; - } else if (0 === aEventString.indexOf("P2P-GROUP-FORMATION-SUCCESS")) { - id = EVENT_P2P_GROUP_FORMATION_SUCCESS; - } else if (0 === aEventString.indexOf("P2P-FIND-STOPPED")) { - id = EVENT_P2P_FIND_STOPPED; - } else if (0 === aEventString.indexOf("P2P-INVITATION-RESULT")) { - id = EVENT_P2P_INVITATION_RESULT; - info.status = /status=([0-9]+)/.exec(aEventString)[1]; - } else if (0 === aEventString.indexOf("P2P-INVITATION-RECEIVED")) { - // e.g. "P2P-INVITATION-RECEIVED sa=32:85:a9:da:e6:1f persistent=7". - id = EVENT_P2P_INVITATION_RECEIVED; - info.address = /sa=([0-9a-f:]+)/.exec(aEventString)[1]; - info.netId = /persistent=([0-9]+)/.exec(aEventString)[1]; - } else if (0 === aEventString.indexOf("P2P-PROV-DISC-FAILURE")) { - id = EVENT_P2P_PROV_DISC_FAILURE; - } else { - // Not P2P event but we do receive it. Try to recognize it. - if (0 === aEventString.indexOf("AP-STA-DISCONNECTED")) { - id = EVENT_AP_STA_DISCONNECTED; - info.address = tokens[1]; - } else if (0 === aEventString.indexOf("AP-STA-CONNECTED")) { - id = EVENT_AP_STA_CONNECTED; - info.address = tokens[1]; - } else { - // Neither P2P event nor recognized supplicant event. - debug('Unknwon event string: ' + aEventString); - } - } - - let event = {id: id, info: info}; - debug('Event parsing result: ' + aEventString + ": " + JSON.stringify(event)); - - return event; - } - - function isIgnoredEvent(aEventString) { - const IGNORED_EVENTS = [ - "CTRL-EVENT-BSS-ADDED", - "CTRL-EVENT-BSS-REMOVED", - "CTRL-EVENT-SCAN-RESULTS", - "CTRL-EVENT-STATE-CHANGE", - "WPS-AP-AVAILABLE", - "WPS-ENROLLEE-SEEN" - ]; - for(let i = 0; i < IGNORED_EVENTS.length; i++) { - if (0 === aEventString.indexOf(IGNORED_EVENTS[i])) { - return true; - } - } - return false; - } - - function isPeerGroupOwner(aGroupFlag) { - return (aGroupFlag & GROUP_CAPAB_GROUP_OWNER) !== 0; - } - - // Convert flag to a wps capability array. - // - // @param aWpsFlag Number that represents the wps capabilities. - // @return Array of WPS flag. - function wpsFlagToCapabilities(aWpsFlag) { - let wpsCapabilities = []; - if (aWpsFlag & 0x8) { - wpsCapabilities.push(WPS_METHOD_DISPLAY); - } - if (aWpsFlag & 0x80) { - wpsCapabilities.push(WPS_METHOD_PBC); - } - if (aWpsFlag & 0x100) { - wpsCapabilities.push(WPS_METHOD_KEYPAD); - } - return wpsCapabilities; - } - - _stateMachine.start(); - return manager; -}; - -function P2pStateMachine(aP2pCommand, aNetUtil) { - function debug(aMsg) { - if (gDebug) { - dump('-------------- WifiP2pStateMachine: ' + aMsg); - } - } - - let p2pSm = {}; // The state machine to return. - - let _sm = StateMachine('WIFIP2P'); // The general purpose state machine. - - // Information we need to keep track across states. - let _observer; - - let _onEnabled; - let _onDisabled; - let _onSupplicantConnected; - let _savedConfig = {}; // Configuration used to do P2P_CONNECT. - let _groupInfo = {}; // The information of the group we have formed. - let _removedGroupInfo = {}; // Used to store the group info we are going to remove. - - let _scanBlocked = false; - let _scanPostponded = false; - - let _localDevice = { - address: "", - deviceName: DEFAULT_P2P_DEVICE_NAME + "_" + libcutils.property_get("ro.build.product"), - wpsCapabilities: [WPS_METHOD_PBC, WPS_METHOD_KEYPAD, WPS_METHOD_DISPLAY] - }; - - let _p2pNetworkInterface = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]), - - info: { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo]), - - state: Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED, - type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI_P2P, - name: P2P_INTERFACE_NAME, - ips: [], - prefixLengths: [], - dnses: [], - gateways: [], - - getAddresses: function (ips, prefixLengths) { - ips.value = this.ips.slice(); - prefixLengths.value = this.prefixLengths.slice(); - - return this.ips.length; - }, - - getGateways: function (count) { - if (count) { - count.value = this.gateways.length; - } - return this.gateways.slice(); - }, - - getDnses: function (count) { - if (count) { - count.value = this.dnses.length; - } - return this.dnses.slice(); - } - }, - - httpProxyHost: null, - httpProxyPort: null, - - // help - registered: false - }; - - //--------------------------------------------------------- - // State machine APIs. - //--------------------------------------------------------- - - // Register the observer which is implemented in WifiP2pWorkerObserver.jsm. - // - // @param aObserver: - // .onEnabled - // .onDisbaled - // .onPeerFound - // .onPeerLost - // .onConnecting - // .onConnected - // .onDisconnected - // .onLocalDeviceChanged - p2pSm.setObserver = function(aObserver) { - _observer = aObserver; - }; - - p2pSm.start = function() { - _sm.start(stateDisabled); - }; - - p2pSm.sendEvent = function(aEvent) { - let willBeHandled = isInP2pManagedState(_sm.getCurrentState()); - _sm.sendEvent(aEvent); - return willBeHandled; - }; - - // Initialize internal state machine _sm. - _sm.setDefaultEventHandler(handleEventCommon); - - //---------------------------------------------------------- - // State definition. - //---------------------------------------------------------- - - // The initial state. - var stateDisabled = _sm.makeState("DISABLED", { - enter: function() { - _onEnabled = null; - _onSupplicantConnected = null; - _savedConfig = null; - _groupInfo = null; - _removedGroupInfo = null; - _scanBlocked = false; - _scanPostponded = false; - - unregisterP2pNetworkInteface(); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_CMD_ENABLE: - _onEnabled = aEvent.info.onEnabled; - _onSupplicantConnected = aEvent.info.onSupplicantConnected; - _sm.gotoState(stateEnabling); - break; - - default: - return false; - } // End of switch. - return true; - } - }); - - // The state where we are trying to enable wifi p2p. - var stateEnabling = _sm.makeState("ENABLING", { - enter: function() { - - function onFailure() - { - _onEnabled(false); - _observer.onDisabled(); - _sm.gotoState(stateDisabled); - } - - function onSuccess() - { - _onEnabled(true); - _observer.onEnabled(); - _sm.gotoState(stateInactive); - } - - _sm.pause(); - - // This function will only call back on success. - function connectToSupplicantIfNeeded(callback) { - if (aP2pCommand.getSdkVersion() >= 19) { - // No need to connect to supplicant on KK. Call back directly. - callback(); - return; - } - aP2pCommand.connectToSupplicant(function (status) { - if (0 !== status) { - debug('Failed to connect to p2p0'); - onFailure(); - return; - } - debug('wpa_supplicant p2p0 connected!'); - _onSupplicantConnected(); - callback(); - }); - } - - // Step 1: Connect to p2p0 if needed. - connectToSupplicantIfNeeded(function callback () { - let detail; - - // Step 2: Get MAC address. - if (!_localDevice.address) { - aP2pCommand.getMacAddress(function (address) { - if (!address) { - debug('Failed to get MAC address....'); - onFailure(); - return; - } - debug('Got mac address: ' + address); - _localDevice.address = address; - _observer.onLocalDeviceChanged(_localDevice); - }); - } - - // Step 3: Enable p2p with the device name and wps methods. - detail = { deviceName: _localDevice.deviceName, - deviceType: libcutils.property_get("ro.moz.wifi.p2p_device_type") || DEFAULT_P2P_DEVICE_TYPE, - wpsMethods: libcutils.property_get("ro.moz.wifi.p2p_wps_methods") || DEFAULT_P2P_WPS_METHODS }; - - aP2pCommand.p2pEnable(detail, function (success) { - if (!success) { - debug('Failed to enable p2p'); - onFailure(); - return; - } - - debug('P2P is enabled! Enabling net interface...'); - - // Step 4: Enable p2p0 net interface. wpa_supplicant may have - // already done it for us. - gNetworkService.enableInterface(P2P_INTERFACE_NAME, function (success) { - onSuccess(); - }); - }); - }); - }, - - handleEvent: function(aEvent) { - // We won't receive any event since all of them will be blocked. - return true; - } - }); - - // The state just after enabling wifi direct. - var stateInactive = _sm.makeState("INACTIVE", { - enter: function() { - registerP2pNetworkInteface(); - - if (_sm.getPreviousState() !== stateEnabling) { - _observer.onDisconnected(_savedConfig); - } - - _savedConfig = null; // Used to connect p2p peer. - _groupInfo = null; // The information of the formed group. - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - // Receiving the following 3 states implies someone is trying to - // connect to me. - case EVENT_P2P_PROV_DISC_PBC_REQ: - case EVENT_P2P_PROV_DISC_SHOW_PIN: - case EVENT_P2P_PROV_DISC_ENTER_PIN: - debug('Someone is trying to connect to me: ' + JSON.stringify(aEvent.info)); - - _savedConfig = { - name: aEvent.info.name, - address: aEvent.info.address, - wpsMethod: aEvent.info.wpsMethod, - goIntent: DEFAULT_GO_INTENT, - pin: aEvent.info.pin // EVENT_P2P_PROV_DISC_SHOW_PIN only. - }; - - _sm.gotoState(stateWaitingForConfirmation); - break; - - // Connect to a peer. - case EVENT_P2P_CMD_CONNECT: - debug('Trying to connect to peer: ' + JSON.stringify(aEvent.info)); - - _savedConfig = { - address: aEvent.info.address, - wpsMethod: aEvent.info.wpsMethod, - goIntent: aEvent.info.goIntent - }; - - _sm.gotoState(stateProvisionDiscovery); - aEvent.info.onDoConnect(true); - break; - - case EVENT_P2P_INVITATION_RECEIVED: - _savedConfig = { - address: aEvent.info.address, - wpsMethod: WPS_METHOD_PBC, - goIntent: DEFAULT_GO_INTENT, - netId: aEvent.info.netId - }; - _sm.gotoState(stateWaitingForInvitationConfirmation); - break; - - case EVENT_P2P_GROUP_STARTED: - // Most likely the peer just reinvoked a peristen group and succeeeded. - - _savedConfig = { address: aEvent.info.goAddress }; - - _sm.pause(); - handleGroupStarted(aEvent.info, function (success) { - _sm.resume(); - }); - break; - - case EVENT_AP_STA_DISCONNECTED: - // We will hit this case when we used to be a group owner and - // requested to remove the group we owned. - break; - - default: - return false; - } // End of switch. - return true; - }, - }); - - // Waiting for user's confirmation. - var stateWaitingForConfirmation = _sm.makeState("WAITING_FOR_CONFIRMATION", { - timeoutTimer: null, - - enter: function() { - gSysMsgr.broadcastMessage(PAIRING_REQUEST_SYS_MSG, _savedConfig); - this.timeoutTimer = initTimeoutTimer(30000, EVENT_TIMEOUT_PAIRING_CONFIRMATION); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_SET_PAIRING_CONFIRMATION: - if (!aEvent.info.accepted) { - debug('User rejected this request'); - _sm.gotoState(stateInactive); // Reset to inactive state. - break; - } - - debug('User accepted this request'); - - // The only information we may have to grab from user. - _savedConfig.pin = aEvent.info.pin; - - // The case that user requested to form a group ealier on. - // Just go to connecting state and do p2p_connect. - if (_sm.getPreviousState() === stateProvisionDiscovery) { - _sm.gotoState(stateConnecting); - break; - } - - // Otherwise, wait for EVENT_P2P_GO_NEG_REQUEST. - _sm.gotoState(stateWaitingForNegReq); - break; - - case EVENT_TIMEOUT_PAIRING_CONFIRMATION: - debug('Confirmation timeout!'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GO_NEG_REQUEST: - _sm.deferEvent(aEvent); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - var stateWaitingForNegReq = _sm.makeState("WAITING_FOR_NEG_REQ", { - timeoutTimer: null, - - enter: function() { - debug('Wait for EVENT_P2P_GO_NEG_REQUEST'); - this.timeoutTimer = initTimeoutTimer(30000, EVENT_TIMEOUT_NEG_REQ); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_GO_NEG_REQUEST: - if (aEvent.info.wpsMethod !== _savedConfig.wpsMethod) { - debug('Unmatched wps method: ' + aEvent.info.wpsMethod + ", " + _savedConfig.wpsMetho); - } - _sm.gotoState(stateConnecting); - break; - - case EVENT_TIMEOUT_NEG_REQ: - debug("Waiting for NEG-REQ timeout"); - _sm.gotoState(stateInactive); - break; - - default: - return false; - } // End of switch. - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - // Waiting for user's confirmation for invitation. - var stateWaitingForInvitationConfirmation = _sm.makeState("WAITING_FOR_INV_CONFIRMATION", { - timeoutTimer: null, - - enter: function() { - gSysMsgr.broadcastMessage(PAIRING_REQUEST_SYS_MSG, _savedConfig); - this.timeoutTimer = initTimeoutTimer(30000, EVENT_TIMEOUT_PAIRING_CONFIRMATION); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_SET_PAIRING_CONFIRMATION: - if (!aEvent.info.accepted) { - debug('User rejected this request'); - _sm.gotoState(stateInactive); // Reset to inactive state. - break; - } - - debug('User accepted this request'); - _sm.pause(); - aP2pCommand.p2pGetGroupCapab(_savedConfig.address, function (gc) { - let isPeeGroupOwner = gc & GROUP_CAPAB_GROUP_OWNER; - _sm.gotoState(isPeeGroupOwner ? stateGroupAdding : stateReinvoking); - }); - - break; - - case EVENT_TIMEOUT_PAIRING_CONFIRMATION: - debug('Confirmation timeout!'); - _sm.gotoState(stateInactive); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - var stateGroupAdding = _sm.makeState("GROUP_ADDING", { - timeoutTimer: null, - - enter: function() { - let self = this; - - _observer.onConnecting(_savedConfig); - - _sm.pause(); - aP2pCommand.p2pGroupAdd(_savedConfig.netId, function (success) { - if (!success) { - _sm.gotoState(stateInactive); - return; - } - // Waiting for EVENT_P2P_GROUP_STARTED. - self.timeoutTimer = initTimeoutTimer(60000, EVENT_TIMEOUT_CONNECTING); - _sm.resume(); - }); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_GROUP_STARTED: - _sm.pause(); - handleGroupStarted(aEvent.info, function (success) { - _sm.resume(); - }); - break; - - case EVENT_P2P_GO_NEG_FAILURE: - debug('Negotiation failure. Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_TIMEOUT_CONNECTING: - debug('Connecting timeout! Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_FORMATION_SUCCESS: - case EVENT_P2P_GO_NEG_SUCCESS: - break; - - case EVENT_P2P_GROUP_FORMATION_FAILURE: - debug('Group formation failure'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_REMOVED: - debug('Received P2P-GROUP-REMOVED due to previous failed handleGroupdStarted()'); - _removedGroupInfo = { - role: aEvent.info.role, - ifname: aEvent.info.ifname - }; - _sm.gotoState(stateDisconnecting); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - var stateReinvoking = _sm.makeState("REINVOKING", { - timeoutTimer: null, - - enter: function() { - let self = this; - - _observer.onConnecting(_savedConfig); - _sm.pause(); - aP2pCommand.p2pReinvoke(_savedConfig.netId, _savedConfig.address, function(success) { - if (!success) { - _sm.gotoState(stateInactive); - return; - } - // Waiting for EVENT_P2P_GROUP_STARTED. - self.timeoutTimer = initTimeoutTimer(60000, EVENT_TIMEOUT_CONNECTING); - _sm.resume(); - }); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_GROUP_STARTED: - _sm.pause(); - handleGroupStarted(aEvent.info, function(success) { - _sm.resume(); - }); - break; - - case EVENT_P2P_GO_NEG_FAILURE: - debug('Negotiation failure. Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_TIMEOUT_CONNECTING: - debug('Connecting timeout! Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_FORMATION_SUCCESS: - case EVENT_P2P_GO_NEG_SUCCESS: - break; - - case EVENT_P2P_GROUP_FORMATION_FAILURE: - debug('Group formation failure'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_REMOVED: - debug('Received P2P-GROUP-REMOVED due to previous failed handleGroupdStarted()'); - _removedGroupInfo = { - role: aEvent.info.role, - ifname: aEvent.info.ifname - }; - _sm.gotoState(stateDisconnecting); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - } - }); - - var stateProvisionDiscovery = _sm.makeState("PROVISION_DISCOVERY", { - enter: function() { - function onDiscoveryCommandSent(success) { - if (!success) { - _sm.gotoState(stateInactive); - debug('Failed to send p2p_prov_disc. Go back to inactive state.'); - return; - } - - debug('p2p_prov_disc has been sent.'); - - _sm.resume(); - // Waiting for EVENT_P2P_PROV_DISC_PBC_RESP or - // EVENT_P2P_PROV_DISC_SHOW_PIN or - // EVENT_P2P_PROV_DISC_ENTER_PIN. - } - - _sm.pause(); - aP2pCommand.p2pProvDiscovery(_savedConfig.address, - toPeerWpsMethod(_savedConfig.wpsMethod), - onDiscoveryCommandSent); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_PROV_DISC_PBC_RESP: - _sm.gotoState(stateConnecting); // No need for local user grant. - break; - case EVENT_P2P_PROV_DISC_SHOW_PIN: - case EVENT_P2P_PROV_DISC_ENTER_PIN: - if (aEvent.info.wpsMethod !== _savedConfig.wpsMethod) { - debug('Unmatched wps method: ' + aEvent.info.wpsMethod + ":" + _savedConfig.wpsMethod); - } - if (EVENT_P2P_PROV_DISC_SHOW_PIN === aEvent.id) { - _savedConfig.pin = aEvent.info.pin; - } - _sm.gotoState(stateWaitingForConfirmation); - break; - - case EVENT_P2P_PROV_DISC_FAILURE: - _sm.gotoState(stateInactive); - break; - - default: - return false; - } // End of switch. - return true; - } - }); - - // We are going to connect to the peer. - // |_savedConfig| is supposed to have been filled properly. - var stateConnecting = _sm.makeState("CONNECTING", { - timeoutTimer: null, - - enter: function() { - let self = this; - - if (null === _savedConfig.goIntent) { - _savedConfig.goIntent = DEFAULT_GO_INTENT; - } - - _observer.onConnecting(_savedConfig); - - let wpsMethodWithPin; - if (WPS_METHOD_KEYPAD === _savedConfig.wpsMethod || - WPS_METHOD_DISPLAY === _savedConfig.wpsMethod) { - // e.g. '12345678 display or '12345678 keypad'. - wpsMethodWithPin = (_savedConfig.pin + ' ' + _savedConfig.wpsMethod); - } else { - // e.g. 'pbc'. - wpsMethodWithPin = _savedConfig.wpsMethod; - } - - _sm.pause(); - - aP2pCommand.p2pGetGroupCapab(_savedConfig.address, function(gc) { - debug('group capabilities of ' + _savedConfig.address + ': ' + gc); - - let isPeerGroupOwner = gc & GROUP_CAPAB_GROUP_OWNER; - let config = { address: _savedConfig.address, - wpsMethodWithPin: wpsMethodWithPin, - goIntent: _savedConfig.goIntent, - joinExistingGroup: isPeerGroupOwner }; - - aP2pCommand.p2pConnect(config, function (success) { - if (!success) { - debug('Failed to send p2p_connect'); - _sm.gotoState(stateInactive); - return; - } - debug('Waiting for EVENT_P2P_GROUP_STARTED.'); - self.timeoutTimer = initTimeoutTimer(60000, EVENT_TIMEOUT_CONNECTING); - _sm.resume(); - }); - }); - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_GROUP_STARTED: - _sm.pause(); - handleGroupStarted(aEvent.info, function (success) { - _sm.resume(); - }); - break; - - case EVENT_P2P_GO_NEG_FAILURE: - debug('Negotiation failure. Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_TIMEOUT_CONNECTING: - debug('Connecting timeout! Go back to inactive state'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_FORMATION_SUCCESS: - case EVENT_P2P_GO_NEG_SUCCESS: - break; - - case EVENT_P2P_GROUP_FORMATION_FAILURE: - debug('Group formation failure'); - _sm.gotoState(stateInactive); - break; - - case EVENT_P2P_GROUP_REMOVED: - debug('Received P2P-GROUP-REMOVED due to previous failed ' + - 'handleGroupdStarted()'); - _removedGroupInfo = { - role: aEvent.info.role, - ifname: aEvent.info.ifname - }; - _sm.gotoState(stateDisconnecting); - break; - - default: - return false; - } // End of switch. - - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - } - }); - - var stateConnected = _sm.makeState("CONNECTED", { - groupOwner: null, - - enter: function() { - this.groupOwner = { - macAddress: _groupInfo.goAddress, - ipAddress: _groupInfo.networkInterface.info.gateways[0], - passphrase: _groupInfo.passphrase, - ssid: _groupInfo.ssid, - freq: _groupInfo.freq, - isLocal: _groupInfo.isGroupOwner - }; - - if (!_groupInfo.isGroupOwner) { - _observer.onConnected(this.groupOwner, _savedConfig); - } else { - // If I am a group owner, notify onConnected until EVENT_AP_STA_CONNECTED - // is received. - } - - _removedGroupInfo = null; - }, - - handleEvent: function(aEvent) { - switch (aEvent.id) { - case EVENT_AP_STA_CONNECTED: - if (_groupInfo.isGroupOwner) { - _observer.onConnected(this.groupOwner, _savedConfig); - } - break; - - case EVENT_P2P_GROUP_REMOVED: - _removedGroupInfo = { - role: aEvent.info.role, - ifname: aEvent.info.ifname - }; - _sm.gotoState(stateDisconnecting); - break; - - case EVENT_AP_STA_DISCONNECTED: - debug('Client disconnected: ' + aEvent.info.address); - - // Now we suppose it's the only client. Remove my group. - _sm.pause(); - aP2pCommand.p2pGroupRemove(_groupInfo.ifname, function (success) { - debug('Requested to remove p2p group. Wait for EVENT_P2P_GROUP_REMOVED.'); - _sm.resume(); - }); - break; - - case EVENT_P2P_CMD_DISCONNECT: - // Since we only support single connection, we can ignore - // the given peer address. - _sm.pause(); - aP2pCommand.p2pGroupRemove(_groupInfo.ifname, function(success) { - aEvent.info.onDoDisconnect(true); - _sm.resume(); - }); - - debug('Sent disconnect command. Wait for EVENT_P2P_GROUP_REMOVED.'); - break; - - case EVENT_P2P_PROV_DISC_PBC_REQ: - case EVENT_P2P_PROV_DISC_SHOW_PIN: - case EVENT_P2P_PROV_DISC_ENTER_PIN: - debug('Someone is trying to connect to me: ' + JSON.stringify(aEvent.info)); - - _savedConfig = { - name: aEvent.info.name, - address: aEvent.info.address, - wpsMethod: aEvent.info.wpsMethod, - pin: aEvent.info.pin - }; - - _sm.gotoState(stateWaitingForJoiningConfirmation); - break; - - default: - return false; - } // end of switch - return true; - } - }); - - var stateWaitingForJoiningConfirmation = _sm.makeState("WAITING_FOR_JOINING_CONFIRMATION", { - timeoutTimer: null, - - enter: function() { - gSysMsgr.broadcastMessage(PAIRING_REQUEST_SYS_MSG, _savedConfig); - this.timeoutTimer = initTimeoutTimer(30000, EVENT_TIMEOUT_PAIRING_CONFIRMATION); - }, - - handleEvent: function (aEvent) { - switch (aEvent.id) { - case EVENT_P2P_SET_PAIRING_CONFIRMATION: - if (!aEvent.info.accepted) { - debug('User rejected invitation!'); - _sm.gotoState(stateConnected); - break; - } - - let onWpsCommandSent = function(success) { - _observer.onConnecting(_savedConfig); - _sm.gotoState(stateConnected); - }; - - _sm.pause(); - if (WPS_METHOD_PBC === _savedConfig.wpsMethod) { - aP2pCommand.wpsPbc(onWpsCommandSent, _groupInfo.ifname); - } else { - let detail = { pin: _savedConfig.pin, iface: _groupInfo.ifname }; - aP2pCommand.wpsPin(detail, onWpsCommandSent); - } - break; - - case EVENT_TIMEOUT_PAIRING_CONFIRMATION: - debug('WAITING_FOR_JOINING_CONFIRMATION timeout!'); - _sm.gotoState(stateConnected); - break; - - default: - return false; - } // End of switch. - return true; - }, - - exit: function() { - this.timeoutTimer.cancel(); - this.timeoutTimer = null; - } - }); - - var stateDisconnecting = _sm.makeState("DISCONNECTING", { - enter: function() { - _sm.pause(); - handleGroupRemoved(_removedGroupInfo, function (success) { - if (!success) { - debug('Failed to handle group removed event. What can I do?'); - } - _sm.gotoState(stateInactive); - }); - }, - - handleEvent: function(aEvent) { - return false; // We will not receive any event in this state. - } - }); - - var stateDisabling = _sm.makeState("DISABLING", { - enter: function() { - _sm.pause(); - aNetUtil.stopDhcpServer(function (success) { // Stopping DHCP server is harmless. - debug('Stop DHCP server result: ' + success); - aP2pCommand.p2pDisable(function(success) { - debug('P2P function disabled'); - closeSupplicantConnectionIfNeeded(function() { - debug('Supplicant connection closed'); - gNetworkService.disableInterface(P2P_INTERFACE_NAME, function (success){ - debug('Disabled interface: ' + P2P_INTERFACE_NAME); - _onDisabled(true); - _observer.onDisabled(); - _sm.gotoState(stateDisabled); - }); - }); - }); - }); - - function closeSupplicantConnectionIfNeeded(callback) { - // No need to connect to supplicant on KK. Call back directly. - if (aP2pCommand.getSdkVersion() >= 19) { - callback(); - return; - } - aP2pCommand.closeSupplicantConnection(callback); - } - }, - - handleEvent: function(aEvent) { - return false; // We will not receive any event in this state. - } - }); - - //---------------------------------------------------------- - // Helper functions. - //---------------------------------------------------------- - - // Handle 'P2P_GROUP_STARTED' event. Note that this function - // will also do the state transitioning and error handling. - // - // @param aInfo Information carried by "P2P_GROUP_STARTED" event: - // .role: P2P_ROLE_GO or P2P_ROLE_CLIENT - // .ssid: - // .freq: - // .passphrase: Used to connect to GO for legacy device. - // .goAddress: - // .ifname: e.g. p2p-p2p0 - // - // @param aCallback Callback function. - function handleGroupStarted(aInfo, aCallback) { - debug('handleGroupStarted: ' + JSON.stringify(aInfo)); - - function onSuccess() - { - _sm.gotoState(stateConnected); - aCallback(true); - } - - function onFailure() - { - debug('Failed to handleGroupdStarted(). Remove the group...'); - aP2pCommand.p2pGroupRemove(aInfo.ifname, function (success) { - aCallback(false); - - if (success) { - return; // Stay in current state and wait for EVENT_P2P_GROUP_REMOVED. - } - - debug('p2pGroupRemove command error!'); - _sm.gotoState(stateInactive); - }); - } - - // Save this group information. - _groupInfo = aInfo; - _groupInfo.isGroupOwner = (P2P_ROLE_GO === aInfo.role); - - if (_groupInfo.isGroupOwner) { - debug('Group owner. Start DHCP server'); - let dhcpServerConfig = { ifname: aInfo.ifname, - startIp: GO_DHCP_SERVER_IP_RANGE.startIp, - endIp: GO_DHCP_SERVER_IP_RANGE.endIp, - serverIp: GO_NETWORK_INTERFACE.ip, - maskLength: GO_NETWORK_INTERFACE.maskLength }; - - aNetUtil.startDhcpServer(dhcpServerConfig, function (success) { - if (!success) { - debug('Failed to start DHCP server'); - onFailure(); - return; - } - - // Update p2p network interface. - _p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED; - _p2pNetworkInterface.info.ips = [GO_NETWORK_INTERFACE.ip]; - _p2pNetworkInterface.info.prefixLengths = [GO_NETWORK_INTERFACE.maskLength]; - _p2pNetworkInterface.info.gateways = [GO_NETWORK_INTERFACE.ip]; - handleP2pNetworkInterfaceStateChanged(); - - _groupInfo.networkInterface = _p2pNetworkInterface; - - debug('Everything is done. Happy p2p GO~'); - onSuccess(); - }); - - return; - } - - // We are the client. - - debug("Client. Request IP from DHCP server on interface: " + _groupInfo.ifname); - - aNetUtil.runDhcp(aInfo.ifname, 0, function(dhcpData) { - if(!dhcpData || !dhcpData.info) { - debug('Failed to run DHCP client'); - onFailure(); - return; - } - - // Save network interface. - debug("DHCP request success: " + JSON.stringify(dhcpData.info)); - - // Update p2p network interface. - let maskLength = - netHelpers.getMaskLength(netHelpers.stringToIP(dhcpData.info.mask_str)); - if (!maskLength) { - maskLength = 32; // max prefix for IPv4. - } - _p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED; - _p2pNetworkInterface.info.ips = [dhcpData.info.ipaddr_str]; - _p2pNetworkInterface.info.prefixLengths = [maskLength]; - if (typeof dhcpData.info.dns1_str == "string" && - dhcpData.info.dns1_str.length) { - _p2pNetworkInterface.info.dnses.push(dhcpData.info.dns1_str); - } - if (typeof dhcpData.info.dns2_str == "string" && - dhcpData.info.dns2_str.length) { - _p2pNetworkInterface.info.dnses.push(dhcpData.info.dns2_str); - } - _p2pNetworkInterface.info.gateways = [dhcpData.info.gateway_str]; - handleP2pNetworkInterfaceStateChanged(); - - _groupInfo.networkInterface = _p2pNetworkInterface; - - debug('Happy p2p client~'); - onSuccess(); - }); - } - - function resetP2pNetworkInterface() { - _p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; - _p2pNetworkInterface.info.ips = []; - _p2pNetworkInterface.info.prefixLengths = []; - _p2pNetworkInterface.info.dnses = []; - _p2pNetworkInterface.info.gateways = []; - } - - function registerP2pNetworkInteface() { - if (!_p2pNetworkInterface.registered) { - resetP2pNetworkInterface(); - gNetworkManager.registerNetworkInterface(_p2pNetworkInterface); - _p2pNetworkInterface.registered = true; - } - } - - function unregisterP2pNetworkInteface() { - if (_p2pNetworkInterface.registered) { - resetP2pNetworkInterface(); - gNetworkManager.unregisterNetworkInterface(_p2pNetworkInterface); - _p2pNetworkInterface.registered = false; - } - } - - function handleP2pNetworkInterfaceStateChanged() { - gNetworkManager.updateNetworkInterface(_p2pNetworkInterface); - } - - // Handle 'P2P_GROUP_STARTED' event. - // - // @param aInfo information carried by "P2P_GROUP_REMOVED" event: - // .ifname - // .role: "GO" or "client". - // - // @param aCallback Callback function. - function handleGroupRemoved(aInfo, aCallback) { - if (!_groupInfo) { - debug('No group info. Why?'); - aCallback(true); - return; - } - if (_groupInfo.ifname !== aInfo.ifname || - _groupInfo.role !== aInfo.role) { - debug('Unmatched group info: ' + JSON.stringify(_groupInfo) + - ' v.s. ' + JSON.stringify(aInfo)); - } - - // Update p2p network interface. - _p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; - handleP2pNetworkInterfaceStateChanged(); - - if (P2P_ROLE_GO === aInfo.role) { - aNetUtil.stopDhcpServer(function(success) { - debug('Stop DHCP server result: ' + success); - aCallback(true); - }); - } else { - aNetUtil.stopDhcp(aInfo.ifname, function() { - aCallback(true); - }); - } - } - - // Non state-specific event handler. - function handleEventCommon(aEvent) { - switch (aEvent.id) { - case EVENT_P2P_DEVICE_FOUND: - _observer.onPeerFound(aEvent.info); - break; - - case EVENT_P2P_DEVICE_LOST: - _observer.onPeerLost(aEvent.info); - break; - - case EVENT_P2P_CMD_DISABLE: - _onDisabled = aEvent.info.onDisabled; - _sm.gotoState(stateDisabling); - break; - - case EVENT_P2P_CMD_ENABLE_SCAN: - if (_scanBlocked) { - _scanPostponded = true; - aEvent.info.callback(true); - break; - } - aP2pCommand.p2pEnableScan(P2P_SCAN_TIMEOUT_SEC, aEvent.info.callback); - break; - - case EVENT_P2P_CMD_DISABLE_SCAN: - aP2pCommand.p2pDisableScan(aEvent.info.callback); - break; - - case EVENT_P2P_FIND_STOPPED: - break; - - case EVENT_P2P_CMD_BLOCK_SCAN: - _scanBlocked = true; - aP2pCommand.p2pDisableScan(function(success) {}); - break; - - case EVENT_P2P_CMD_UNBLOCK_SCAN: - _scanBlocked = false; - if (_scanPostponded) { - aP2pCommand.p2pEnableScan(P2P_SCAN_TIMEOUT_SEC, function(success) {}); - } - break; - - case EVENT_P2P_CMD_CONNECT: - case EVENT_P2P_CMD_DISCONNECT: - debug("The current state couldn't handle connect/disconnect request. Ignore it."); - break; - - default: - return false; - } // End of switch. - return true; - } - - function isInP2pManagedState(aState) { - let p2pManagedStates = [stateWaitingForConfirmation, - stateWaitingForNegReq, - stateProvisionDiscovery, - stateWaitingForInvitationConfirmation, - stateGroupAdding, - stateReinvoking, - stateConnecting, - stateConnected, - stateDisconnecting]; - - for (let i = 0; i < p2pManagedStates.length; i++) { - if (aState === p2pManagedStates[i]) { - return true; - } - } - - return false; - } - - function initTimeoutTimer(aTimeoutMs, aTimeoutEvent) { - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - function onTimerFired() { - _sm.sendEvent({ id: aTimeoutEvent }); - timer = null; - } - timer.initWithCallback(onTimerFired.bind(this), aTimeoutMs, - Ci.nsITimer.TYPE_ONE_SHOT); - return timer; - } - - // Converts local WPS method to peer WPS method. - function toPeerWpsMethod(aLocalWpsMethod) { - switch (aLocalWpsMethod) { - case WPS_METHOD_DISPLAY: - return WPS_METHOD_KEYPAD; - case WPS_METHOD_KEYPAD: - return WPS_METHOD_DISPLAY; - case WPS_METHOD_PBC: - return WPS_METHOD_PBC; - default: - return WPS_METHOD_PBC; // Use "push button" as the default method. - } - } - - return p2pSm; -} - -this.WifiP2pManager.INTERFACE_NAME = P2P_INTERFACE_NAME; diff --git a/dom/wifi/WifiP2pWorkerObserver.jsm b/dom/wifi/WifiP2pWorkerObserver.jsm deleted file mode 100644 index d04e8db5e..000000000 --- a/dom/wifi/WifiP2pWorkerObserver.jsm +++ /dev/null @@ -1,319 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -const CONNECTION_STATUS_DISCONNECTED = "disconnected"; -const CONNECTION_STATUS_CONNECTING = "connecting"; -const CONNECTION_STATUS_CONNECTED = "connected"; -const CONNECTION_STATUS_DISCONNECTING = "disconnecting"; - -const DEBUG = false; - -this.EXPORTED_SYMBOLS = ["WifiP2pWorkerObserver"]; - -// WifiP2pWorkerObserver resides in WifiWorker to handle DOM message -// by either 1) returning internally maintained information or -// 2) delegating to aDomMsgResponder. It is also responsible -// for observing events from WifiP2pManager and dispatch to DOM. -// -// @param aDomMsgResponder handles DOM messages, including -// - setScanEnabled -// - connect -// - disconnect -// - setPairingConfirmation -// The instance is actually WifiP2pManager. -this.WifiP2pWorkerObserver = function(aDomMsgResponder) { - function debug(aMsg) { - if (DEBUG) { - dump('-------------- WifiP2pWorkerObserver: ' + aMsg); - } - } - - // Private member variables. - let _localDevice; - let _peerList = {}; // List of P2pDevice. - let _domManagers = []; - let _enabled = false; - let _groupOwner = null; - let _currentPeer = null; - - // Constructor of P2pDevice. It will be exposed to DOM. - // - // @param aPeer object representing a P2P device: - // .name: string for the device name. - // .address: Mac address. - // .isGroupOwner: boolean to indicate if this device is the group owner. - // .wpsCapabilities: array of string of {"pbc", "display", "keypad"}. - function P2pDevice(aPeer) { - this.address = aPeer.address; - this.name = (aPeer.name ? aPeer.name : aPeer.address); - this.isGroupOwner = aPeer.isGroupOwner; - this.wpsCapabilities = aPeer.wpsCapabilities; - this.connectionStatus = CONNECTION_STATUS_DISCONNECTED; - - // Since this object will be exposed to web, defined the exposed - // properties here. - this.__exposedProps__ = { - address: "r", - name: "r", - isGroupOwner: "r", - wpsCapabilities: "r", - connectionStatus: "r" - }; - } - - // Constructor of P2pGroupOwner. - // - // @param aGroupOwner: - // .macAddress - // .ipAddress - // .passphrase - // .ssid - // .freq - // .isLocal - function P2pGroupOwner(aGroupOwner) { - this.macAddress = aGroupOwner.macAddress; // The identifier to get further information. - this.ipAddress = aGroupOwner.ipAddress; - this.passphrase = aGroupOwner.passphrase; - this.ssid = aGroupOwner.ssid; // e.g. DIRECT-xy. - this.freq = aGroupOwner.freq; - this.isLocal = aGroupOwner.isLocal; - - let detail = _peerList[aGroupOwner.macAddress]; - if (detail) { - this.name = detail.name; - this.wpsCapabilities = detail.wpsCapabilities; - } else if (_localDevice.address === this.macAddress) { - this.name = _localDevice.name; - this.wpsCapabilities = _localDevice.wpsCapabilities; - } else { - debug("We don't know this group owner: " + aGroupOwner.macAddress); - this.name = aGroupOwner.macAddress; - this.wpsCapabilities = []; - } - } - - function fireEvent(aMessage, aData) { - debug('domManager: ' + JSON.stringify(_domManagers)); - _domManagers.forEach(function(manager) { - // Note: We should never have a dead message manager here because we - // observe our child message managers shutting down below. - manager.sendAsyncMessage("WifiP2pManager:" + aMessage, aData); - }); - } - - function addDomManager(aMsg) { - if (-1 === _domManagers.indexOf(aMsg.manager)) { - _domManagers.push(aMsg.manager); - } - } - - function returnMessage(aMessage, aSuccess, aData, aMsg) { - let rMsg = aMessage + ":Return:" + (aSuccess ? "OK" : "NO"); - aMsg.manager.sendAsyncMessage(rMsg, - { data: aData, rid: aMsg.rid, mid: aMsg.mid }); - } - - function handlePeerListUpdated() { - fireEvent("onpeerinfoupdate", {}); - } - - // Return a literal object as the constructed object. - return { - onLocalDeviceChanged: function(aDevice) { - _localDevice = aDevice; - debug('Local device updated to: ' + JSON.stringify(_localDevice)); - }, - - onEnabled: function() { - _peerList = []; - _enabled = true; - fireEvent("p2pUp", {}); - }, - - onDisbaled: function() { - _enabled = false; - fireEvent("p2pDown", {}); - }, - - onPeerFound: function(aPeer) { - let newFoundPeer = new P2pDevice(aPeer); - let origianlPeer = _peerList[aPeer.address]; - _peerList[aPeer.address] = newFoundPeer; - if (origianlPeer) { - newFoundPeer.connectionStatus = origianlPeer.connectionStatus; - } - handlePeerListUpdated(); - }, - - onPeerLost: function(aPeer) { - let lostPeer = _peerList[aPeer.address]; - if (!lostPeer) { - debug('Unknown peer lost: ' + aPeer.address); - return; - } - delete _peerList[aPeer.address]; - handlePeerListUpdated(); - }, - - onConnecting: function(aPeer) { - let peer = _peerList[aPeer.address]; - if (!peer) { - debug('Unknown peer connecting: ' + aPeer.address); - peer = new P2pDevice(aPeer); - _peerList[aPeer.address] = peer; - handlePeerListUpdated(); - } - peer.connectionStatus = CONNECTION_STATUS_CONNECTING; - - fireEvent('onconnecting', { peer: peer }); - }, - - onConnected: function(aGroupOwner, aPeer) { - let go = new P2pGroupOwner(aGroupOwner); - let peer = _peerList[aPeer.address]; - if (!peer) { - debug('Unknown peer connected: ' + aPeer.address); - peer = new P2pDevice(aPeer); - _peerList[aPeer.address] = peer; - handlePeerListUpdated(); - } - peer.connectionStatus = CONNECTION_STATUS_CONNECTED; - peer.isGroupOwner = (aPeer.address === aGroupOwner.address); - - _groupOwner = go; - _currentPeer = peer; - - fireEvent('onconnected', { groupOwner: go, peer: peer }); - }, - - onDisconnected: function(aPeer) { - let peer = _peerList[aPeer.address]; - if (!peer) { - debug('Unknown peer disconnected: ' + aPeer.address); - return; - } - - peer.connectionStatus = CONNECTION_STATUS_DISCONNECTED; - - _groupOwner = null; - _currentPeer = null; - - fireEvent('ondisconnected', { peer: peer }); - }, - - getObservedDOMMessages: function() { - return [ - "WifiP2pManager:getState", - "WifiP2pManager:getPeerList", - "WifiP2pManager:setScanEnabled", - "WifiP2pManager:connect", - "WifiP2pManager:disconnect", - "WifiP2pManager:setPairingConfirmation", - "WifiP2pManager:setDeviceName" - ]; - }, - - onDOMMessage: function(aMessage) { - let msg = aMessage.data || {}; - msg.manager = aMessage.target; - - if ("child-process-shutdown" === aMessage.name) { - let i; - if (-1 !== (i = _domManagers.indexOf(msg.manager))) { - _domManagers.splice(i, 1); - } - return; - } - - if (!aMessage.target.assertPermission("wifi-manage")) { - return; - } - - switch (aMessage.name) { - case "WifiP2pManager:getState": // A new DOM manager is created. - addDomManager(msg); - return { // Synchronous call. Simply return it. - enabled: _enabled, - groupOwner: _groupOwner, - currentPeer: _currentPeer - }; - - case "WifiP2pManager:setScanEnabled": - { - let enabled = msg.data; - - aDomMsgResponder.setScanEnabled(enabled, function(success) { - returnMessage(aMessage.name, success, (success ? true : "ERROR"), msg); - }); - } - break; - - case "WifiP2pManager:getPeerList": - { - // Convert the object to an array. - let peerArray = []; - for (let key in _peerList) { - if (_peerList.hasOwnProperty(key)) { - peerArray.push(_peerList[key]); - } - } - - returnMessage(aMessage.name, true, peerArray, msg); - } - break; - - case "WifiP2pManager:connect": - { - let peer = msg.data; - - let onDoConnect = function(success) { - returnMessage(aMessage.name, success, (success ? true : "ERROR"), msg); - }; - - aDomMsgResponder.connect(peer.address, peer.wpsMethod, - peer.goIntent, onDoConnect); - } - break; - - case "WifiP2pManager:disconnect": - { - let address = msg.data; - - aDomMsgResponder.disconnect(address, function(success) { - returnMessage(aMessage.name, success, (success ? true : "ERROR"), msg); - }); - } - break; - - case "WifiP2pManager:setPairingConfirmation": - { - let result = msg.data; - aDomMsgResponder.setPairingConfirmation(result); - returnMessage(aMessage.name, true, true, msg); - } - break; - - case "WifiP2pManager:setDeviceName": - { - let newDeviceName = msg.data; - aDomMsgResponder.setDeviceName(newDeviceName, function(success) { - returnMessage(aMessage.name, success, (success ? true : "ERROR"), msg); - }); - } - break; - - default: - if (0 === aMessage.name.indexOf("WifiP2pManager:")) { - debug("DOM WifiP2pManager message not handled: " + aMessage.name); - } - } // End of switch. - } - }; -}; diff --git a/dom/wifi/WifiProxyService.cpp b/dom/wifi/WifiProxyService.cpp deleted file mode 100644 index 0ff5097af..000000000 --- a/dom/wifi/WifiProxyService.cpp +++ /dev/null @@ -1,357 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "WifiProxyService.h" -#include "nsServiceManagerUtils.h" -#include "mozilla/ModuleUtils.h" -#include "mozilla/ClearOnShutdown.h" -#include "mozilla/dom/ToJSValue.h" -#include "nsXULAppAPI.h" -#include "WifiUtils.h" - -#ifdef MOZ_TASK_TRACER -#include "GeckoTaskTracer.h" -using namespace mozilla::tasktracer; -#endif - -#define NS_WIFIPROXYSERVICE_CID \ - { 0xc6c9be7e, 0x744f, 0x4222, {0xb2, 0x03, 0xcd, 0x55, 0xdf, 0xc8, 0xbc, 0x12} } - -using namespace mozilla; -using namespace mozilla::dom; - -namespace mozilla { - -// The singleton Wifi service, to be used on the main thread. -static StaticRefPtr<WifiProxyService> gWifiProxyService; - -// The singleton supplicant class, that can be used on any thread. -static UniquePtr<WpaSupplicant> gWpaSupplicant; - -// Runnable used dispatch the WaitForEvent result on the main thread. -class WifiEventDispatcher : public Runnable -{ -public: - WifiEventDispatcher(const nsAString& aEvent, const nsACString& aInterface) - : mEvent(aEvent) - , mInterface(aInterface) - { - MOZ_ASSERT(!NS_IsMainThread()); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - gWifiProxyService->DispatchWifiEvent(mEvent, mInterface); - return NS_OK; - } - -private: - nsString mEvent; - nsCString mInterface; -}; - -// Runnable used to call WaitForEvent on the event thread. -class EventRunnable : public Runnable -{ -public: - EventRunnable(const nsACString& aInterface) - : mInterface(aInterface) - { - MOZ_ASSERT(NS_IsMainThread()); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(!NS_IsMainThread()); - nsAutoString event; - gWpaSupplicant->WaitForEvent(event, mInterface); - if (!event.IsEmpty()) { -#ifdef MOZ_TASK_TRACER - // Make wifi initialization events to be the source events of TaskTracer, - // and originate the rest correlation tasks from here. - AutoSourceEvent taskTracerEvent(SourceEventType::Wifi); - AddLabel("%s %s", mInterface.get(), NS_ConvertUTF16toUTF8(event).get()); -#endif - nsCOMPtr<nsIRunnable> runnable = new WifiEventDispatcher(event, mInterface); - NS_DispatchToMainThread(runnable); - } - return NS_OK; - } - -private: - nsCString mInterface; -}; - -// Runnable used dispatch the Command result on the main thread. -class WifiResultDispatcher : public Runnable -{ -public: - WifiResultDispatcher(WifiResultOptions& aResult, const nsACString& aInterface) - : mResult(aResult) - , mInterface(aInterface) - { - MOZ_ASSERT(!NS_IsMainThread()); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - gWifiProxyService->DispatchWifiResult(mResult, mInterface); - return NS_OK; - } - -private: - WifiResultOptions mResult; - nsCString mInterface; -}; - -// Runnable used to call SendCommand on the control thread. -class ControlRunnable : public Runnable -{ -public: - ControlRunnable(CommandOptions aOptions, const nsACString& aInterface) - : mOptions(aOptions) - , mInterface(aInterface) - { - MOZ_ASSERT(NS_IsMainThread()); - } - - NS_IMETHOD Run() override - { - WifiResultOptions result; - if (gWpaSupplicant->ExecuteCommand(mOptions, result, mInterface)) { - nsCOMPtr<nsIRunnable> runnable = new WifiResultDispatcher(result, mInterface); - NS_DispatchToMainThread(runnable); - } - return NS_OK; - } -private: - CommandOptions mOptions; - nsCString mInterface; -}; - -NS_IMPL_ISUPPORTS(WifiProxyService, nsIWifiProxyService) - -WifiProxyService::WifiProxyService() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!gWifiProxyService); -} - -WifiProxyService::~WifiProxyService() -{ - MOZ_ASSERT(!gWifiProxyService); -} - -already_AddRefed<WifiProxyService> -WifiProxyService::FactoryCreate() -{ - if (!XRE_IsParentProcess()) { - return nullptr; - } - - MOZ_ASSERT(NS_IsMainThread()); - - if (!gWifiProxyService) { - gWifiProxyService = new WifiProxyService(); - ClearOnShutdown(&gWifiProxyService); - - gWpaSupplicant = MakeUnique<WpaSupplicant>(); - ClearOnShutdown(&gWpaSupplicant); - } - - RefPtr<WifiProxyService> service = gWifiProxyService.get(); - return service.forget(); -} - -NS_IMETHODIMP -WifiProxyService::Start(nsIWifiEventListener* aListener, - const char ** aInterfaces, - uint32_t aNumOfInterfaces) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aListener); - -#if ANDROID_VERSION >= 19 - // KK changes the way mux'ing/demux'ing different supplicant interfaces - // (e.g. wlan0/p2p0) from multi-sockets to single socket embedded with - // prefixed interface name (e.g. IFNAME=wlan0 xxxxxx). Therefore, we use - // the first given interface as the global interface for KK. - aNumOfInterfaces = 1; -#endif - - nsresult rv; - - // Since EventRunnable runs in the manner of blocking, we have to - // spin a thread for each interface. - // (See the WpaSupplicant::WaitForEvent) - mEventThreadList.SetLength(aNumOfInterfaces); - for (uint32_t i = 0; i < aNumOfInterfaces; i++) { - mEventThreadList[i].mInterface = aInterfaces[i]; - rv = NS_NewThread(getter_AddRefs(mEventThreadList[i].mThread)); - if (NS_FAILED(rv)) { - NS_WARNING("Can't create wifi event thread"); - Shutdown(); - return NS_ERROR_FAILURE; - } - } - - rv = NS_NewThread(getter_AddRefs(mControlThread)); - if (NS_FAILED(rv)) { - NS_WARNING("Can't create wifi control thread"); - Shutdown(); - return NS_ERROR_FAILURE; - } - - mListener = aListener; - - return NS_OK; -} - -NS_IMETHODIMP -WifiProxyService::Shutdown() -{ - MOZ_ASSERT(NS_IsMainThread()); - for (size_t i = 0; i < mEventThreadList.Length(); i++) { - if (mEventThreadList[i].mThread) { - mEventThreadList[i].mThread->Shutdown(); - mEventThreadList[i].mThread = nullptr; - } - } - - mEventThreadList.Clear(); - - if (mControlThread) { - mControlThread->Shutdown(); - mControlThread = nullptr; - } - - mListener = nullptr; - - return NS_OK; -} - -NS_IMETHODIMP -WifiProxyService::SendCommand(JS::Handle<JS::Value> aOptions, - const nsACString& aInterface, - JSContext* aCx) -{ - MOZ_ASSERT(NS_IsMainThread()); - WifiCommandOptions options; - - if (!options.Init(aCx, aOptions)) { - NS_WARNING("Bad dictionary passed to WifiProxyService::SendCommand"); - return NS_ERROR_FAILURE; - } - - if (!mControlThread) { - return NS_ERROR_FAILURE; - } - - // Dispatch the command to the control thread. - CommandOptions commandOptions(options); - nsCOMPtr<nsIRunnable> runnable = new ControlRunnable(commandOptions, aInterface); - mControlThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL); - return NS_OK; -} - -NS_IMETHODIMP -WifiProxyService::WaitForEvent(const nsACString& aInterface) -{ - MOZ_ASSERT(NS_IsMainThread()); - -#if ANDROID_VERSION >= 19 - // We will only have one global interface for KK. - if (!mEventThreadList.IsEmpty()) { - nsCOMPtr<nsIRunnable> runnable = new EventRunnable(aInterface); - mEventThreadList[0].mThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL); - return NS_OK; - } -#else - // Dispatch to the event thread which has the given interface name - for (size_t i = 0; i < mEventThreadList.Length(); i++) { - if (mEventThreadList[i].mInterface.Equals(aInterface)) { - nsCOMPtr<nsIRunnable> runnable = new EventRunnable(aInterface); - mEventThreadList[i].mThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL); - return NS_OK; - } - } -#endif - - return NS_ERROR_FAILURE; -} - -void -WifiProxyService::DispatchWifiResult(const WifiResultOptions& aOptions, const nsACString& aInterface) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mozilla::AutoSafeJSContext cx; - JS::Rooted<JS::Value> val(cx); - - if (!ToJSValue(cx, aOptions, &val)) { - return; - } - - if (mListener) { - // Call the listener with a JS value. - mListener->OnCommand(val, aInterface); - } -} - -void -WifiProxyService::DispatchWifiEvent(const nsAString& aEvent, const nsACString& aInterface) -{ - MOZ_ASSERT(NS_IsMainThread()); - -#if ANDROID_VERSION < 19 - mListener->OnWaitEvent(aEvent, aInterface); -#else - // The interface might be embedded in the event string such as - // "IFNAME=wlan0 CTRL-EVENT-BSS-ADDED 65 3c:94:d5:7c:11:8b". - // Parse the interface name from the event string and use p2p0 - // as the default interface if "IFNAME" is not found. - nsAutoString event; - nsAutoString embeddedInterface(NS_LITERAL_STRING("p2p0")); - if (StringBeginsWith(aEvent, NS_LITERAL_STRING("IFNAME"))) { - int32_t ifnameFrom = aEvent.FindChar('=') + 1; - int32_t ifnameTo = aEvent.FindChar(' ') - 1; - embeddedInterface = Substring(aEvent, ifnameFrom, ifnameTo - ifnameFrom + 1); - event = Substring(aEvent, aEvent.FindChar(' ') + 1); - } - else { - event = aEvent; - } - mListener->OnWaitEvent(event, NS_ConvertUTF16toUTF8(embeddedInterface)); -#endif -} - -NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WifiProxyService, - WifiProxyService::FactoryCreate) - -NS_DEFINE_NAMED_CID(NS_WIFIPROXYSERVICE_CID); - -static const mozilla::Module::CIDEntry kWifiProxyServiceCIDs[] = { - { &kNS_WIFIPROXYSERVICE_CID, false, nullptr, WifiProxyServiceConstructor }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kWifiProxyServiceContracts[] = { - { "@mozilla.org/wifi/service;1", &kNS_WIFIPROXYSERVICE_CID }, - { nullptr } -}; - -static const mozilla::Module kWifiProxyServiceModule = { - mozilla::Module::kVersion, - kWifiProxyServiceCIDs, - kWifiProxyServiceContracts, - nullptr -}; - -} // namespace mozilla - -NSMODULE_DEFN(WifiProxyServiceModule) = &kWifiProxyServiceModule; diff --git a/dom/wifi/WifiProxyService.h b/dom/wifi/WifiProxyService.h deleted file mode 100644 index 406be47de..000000000 --- a/dom/wifi/WifiProxyService.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef WifiProxyService_h -#define WifiProxyService_h - -#include "nsIWifiService.h" -#include "nsCOMPtr.h" -#include "nsThread.h" -#include "mozilla/dom/WifiOptionsBinding.h" -#include "nsTArray.h" - -namespace mozilla { - -class WifiProxyService final : public nsIWifiProxyService -{ -private: - struct EventThreadListEntry - { - nsCOMPtr<nsIThread> mThread; - nsCString mInterface; - }; - -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIWIFIPROXYSERVICE - - static already_AddRefed<WifiProxyService> - FactoryCreate(); - - void DispatchWifiEvent(const nsAString& aEvent, const nsACString& aInterface); - void DispatchWifiResult(const mozilla::dom::WifiResultOptions& aOptions, - const nsACString& aInterface); - -private: - WifiProxyService(); - ~WifiProxyService(); - - nsTArray<EventThreadListEntry> mEventThreadList; - nsCOMPtr<nsIThread> mControlThread; - nsCOMPtr<nsIWifiEventListener> mListener; -}; - -} // namespace mozilla - -#endif // WifiProxyService_h diff --git a/dom/wifi/WifiUtils.cpp b/dom/wifi/WifiUtils.cpp deleted file mode 100644 index 2526c9ea4..000000000 --- a/dom/wifi/WifiUtils.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "WifiUtils.h" -#include <dlfcn.h> -#include <errno.h> -#include <cutils/properties.h> -#include "prinit.h" -#include "mozilla/Sprintf.h" -#include "js/CharacterEncoding.h" - -using namespace mozilla::dom; - -#define BUFFER_SIZE 4096 -#define COMMAND_SIZE 256 - -// Intentionally not trying to dlclose() this handle. That's playing -// Russian roulette with security bugs. -static void* sWifiLib; -static PRCallOnceType sInitWifiLib; - -static PRStatus -InitWifiLib() -{ - sWifiLib = dlopen("/system/lib/libhardware_legacy.so", RTLD_LAZY); - // We might fail to open the hardware lib. That's OK. - return PR_SUCCESS; -} - -static void* -GetSharedLibrary() -{ - PR_CallOnce(&sInitWifiLib, InitWifiLib); - return sWifiLib; -} - -static bool -GetWifiP2pSupported() -{ - char propP2pSupported[PROPERTY_VALUE_MAX]; - property_get("ro.moz.wifi.p2p_supported", propP2pSupported, "0"); - return (0 == strcmp(propP2pSupported, "1")); -} - -static int -hex2num(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - return -1; -} - -static int -hex2byte(const char* hex) -{ - int a, b; - a = hex2num(*hex++); - if (a < 0) - return -1; - b = hex2num(*hex++); - if (b < 0) - return -1; - return (a << 4) | b; -} - -// This function is equivalent to printf_decode() at src/utils/common.c in -// the supplicant. - -static uint32_t -convertToBytes(char* buf, uint32_t maxlen, const char* str) -{ - const char *pos = str; - uint32_t len = 0; - int val; - - while (*pos) { - if (len == maxlen) - break; - switch (*pos) { - case '\\': - pos++; - switch (*pos) { - case '\\': - buf[len++] = '\\'; - pos++; - break; - case '"': - buf[len++] = '"'; - pos++; - break; - case 'n': - buf[len++] = '\n'; - pos++; - break; - case 'r': - buf[len++] = '\r'; - pos++; - break; - case 't': - buf[len++] = '\t'; - pos++; - break; - case 'e': - buf[len++] = '\e'; - pos++; - break; - case 'x': - pos++; - val = hex2byte(pos); - if (val < 0) { - val = hex2num(*pos); - if (val < 0) - break; - buf[len++] = val; - pos++; - } else { - buf[len++] = val; - pos += 2; - } - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - val = *pos++ - '0'; - if (*pos >= '0' && *pos <= '7') - val = val * 8 + (*pos++ - '0'); - if (*pos >= '0' && *pos <= '7') - val = val * 8 + (*pos++ - '0'); - buf[len++] = val; - break; - default: - break; - } - break; - default: - buf[len++] = *pos++; - break; - } - } - return len; -} - -// This is the same algorithm as in InflateUTF8StringToBuffer with Copy and -// while ignoring invalids. -// https://mxr.mozilla.org/mozilla-central/source/js/src/vm/CharacterEncoding.cpp#231 - -static const uint32_t REPLACE_UTF8 = 0xFFFD; - -static void -LossyConvertUTF8toUTF16(const char* aInput, uint32_t aLength, nsAString& aOut) -{ - JS::UTF8Chars src(aInput, aLength); - - char16_t dst[aLength]; // Allocating for worst case. - - // Count how many char16_t characters are needed in the inflated string. - // |i| is the index into |src|, and |j| is the the index into |dst|. - size_t srclen = src.length(); - uint32_t j = 0; - for (uint32_t i = 0; i < srclen; i++, j++) { - uint32_t v = uint32_t(src[i]); - if (v == uint32_t('\0') && i < srclen - 1) { - // If the leading byte is '\0' and it's not the last byte, - // just ignore it to prevent from being truncated. This could - // be caused by |convertToBytes| (e.g. \x00 would be converted to '\0') - j--; - continue; - } - if (!(v & 0x80)) { - // ASCII code unit. Simple copy. - dst[j] = char16_t(v); - } else { - // Non-ASCII code unit. Determine its length in bytes (n). - uint32_t n = 1; - while (v & (0x80 >> n)) - n++; - - #define INVALID(report, arg, n2) \ - do { \ - n = n2; \ - goto invalidMultiByteCodeUnit; \ - } while (0) - - // Check the leading byte. - if (n < 2 || n > 4) - INVALID(ReportInvalidCharacter, i, 1); - - // Check that |src| is large enough to hold an n-byte code unit. - if (i + n > srclen) - INVALID(ReportBufferTooSmall, /* dummy = */ 0, 1); - - // Check the second byte. From Unicode Standard v6.2, Table 3-7 - // Well-Formed UTF-8 Byte Sequences. - if ((v == 0xE0 && ((uint8_t)src[i + 1] & 0xE0) != 0xA0) || // E0 A0~BF - (v == 0xED && ((uint8_t)src[i + 1] & 0xE0) != 0x80) || // ED 80~9F - (v == 0xF0 && ((uint8_t)src[i + 1] & 0xF0) == 0x80) || // F0 90~BF - (v == 0xF4 && ((uint8_t)src[i + 1] & 0xF0) != 0x80)) // F4 80~8F - { - INVALID(ReportInvalidCharacter, i, 1); - } - - // Check the continuation bytes. - for (uint32_t m = 1; m < n; m++) - if ((src[i + m] & 0xC0) != 0x80) - INVALID(ReportInvalidCharacter, i, m); - - // Determine the code unit's length in char16_t units and act accordingly. - v = JS::Utf8ToOneUcs4Char((uint8_t *)&src[i], n); - if (v < 0x10000) { - // The n-byte UTF8 code unit will fit in a single char16_t. - dst[j] = char16_t(v); - } else { - v -= 0x10000; - if (v <= 0xFFFFF) { - // The n-byte UTF8 code unit will fit in two char16_t units. - dst[j] = char16_t((v >> 10) + 0xD800); - j++; - dst[j] = char16_t((v & 0x3FF) + 0xDC00); - } else { - // The n-byte UTF8 code unit won't fit in two char16_t units. - INVALID(ReportTooBigCharacter, v, 1); - } - } - - invalidMultiByteCodeUnit: - // Move i to the last byte of the multi-byte code unit; the loop - // header will do the final i++ to move to the start of the next - // code unit. - i += n - 1; - } - } - - dst[j] = 0; - aOut = dst; -} - -// Helper to check we have loaded the hardware shared library. -#define CHECK_HWLIB(ret) \ - void* hwLib = GetSharedLibrary(); \ - if (!hwLib) { \ - NS_WARNING("No /system/lib/libhardware_legacy.so"); \ - return ret; \ - } - -#define DEFAULT_IMPL(name, ret, args...) \ - DEFINE_DLFUNC(name, ret, args...) \ - ret do_##name(args) { \ - USE_DLFUNC(name) \ - return name(args); \ - } - -// ICS implementation. -class ICSWpaSupplicantImpl : public WpaSupplicantImpl -{ -public: - DEFAULT_IMPL(wifi_load_driver, int32_t, ) - DEFAULT_IMPL(wifi_unload_driver, int32_t, ) - - DEFINE_DLFUNC(wifi_wait_for_event, int32_t, char*, size_t) - int32_t do_wifi_wait_for_event(const char *iface, char *buf, size_t len) { - USE_DLFUNC(wifi_wait_for_event) - return wifi_wait_for_event(buf, len); - } - - DEFINE_DLFUNC(wifi_command, int32_t, const char*, char*, size_t*) - int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) { - USE_DLFUNC(wifi_command) - return wifi_command(cmd, buf, len); - } - - DEFINE_DLFUNC(wifi_start_supplicant, int32_t, ) - int32_t do_wifi_start_supplicant(int32_t) { - USE_DLFUNC(wifi_start_supplicant) - return wifi_start_supplicant(); - } - - DEFINE_DLFUNC(wifi_stop_supplicant, int32_t) - int32_t do_wifi_stop_supplicant(int32_t) { - USE_DLFUNC(wifi_stop_supplicant) - return wifi_stop_supplicant(); - } - - DEFINE_DLFUNC(wifi_connect_to_supplicant, int32_t, ) - int32_t do_wifi_connect_to_supplicant(const char* iface) { - USE_DLFUNC(wifi_connect_to_supplicant) - return wifi_connect_to_supplicant(); - } - - DEFINE_DLFUNC(wifi_close_supplicant_connection, void, ) - void do_wifi_close_supplicant_connection(const char* iface) { - USE_DLFUNC(wifi_close_supplicant_connection) - return wifi_close_supplicant_connection(); - } -}; - -// JB implementation. -// We only redefine the methods that have a different signature than on ICS. -class JBWpaSupplicantImpl : public ICSWpaSupplicantImpl -{ -public: - DEFINE_DLFUNC(wifi_wait_for_event, int32_t, const char*, char*, size_t) - int32_t do_wifi_wait_for_event(const char* iface, char* buf, size_t len) { - USE_DLFUNC(wifi_wait_for_event) - return wifi_wait_for_event(iface, buf, len); - } - - DEFINE_DLFUNC(wifi_command, int32_t, const char*, const char*, char*, size_t*) - int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) { - USE_DLFUNC(wifi_command) - return wifi_command(iface, cmd, buf, len); - } - - DEFINE_DLFUNC(wifi_start_supplicant, int32_t, int32_t) - int32_t do_wifi_start_supplicant(int32_t arg) { - USE_DLFUNC(wifi_start_supplicant) - return wifi_start_supplicant(arg); - } - - DEFINE_DLFUNC(wifi_stop_supplicant, int32_t, int32_t) - int32_t do_wifi_stop_supplicant(int32_t arg) { - USE_DLFUNC(wifi_stop_supplicant) - return wifi_stop_supplicant(arg); - } - - DEFINE_DLFUNC(wifi_connect_to_supplicant, int32_t, const char*) - int32_t do_wifi_connect_to_supplicant(const char* iface) { - USE_DLFUNC(wifi_connect_to_supplicant) - return wifi_connect_to_supplicant(iface); - } - - DEFINE_DLFUNC(wifi_close_supplicant_connection, void, const char*) - void do_wifi_close_supplicant_connection(const char* iface) { - USE_DLFUNC(wifi_close_supplicant_connection) - wifi_close_supplicant_connection(iface); - } -}; - -// KK implementation. -// We only redefine the methods that have a different signature than on ICS. -class KKWpaSupplicantImpl : public ICSWpaSupplicantImpl -{ -public: - DEFINE_DLFUNC(wifi_start_supplicant, int32_t, int32_t) - int32_t do_wifi_start_supplicant(int32_t arg) { - USE_DLFUNC(wifi_start_supplicant) - return wifi_start_supplicant(arg); - } - - DEFINE_DLFUNC(wifi_stop_supplicant, int32_t, int32_t) - int32_t do_wifi_stop_supplicant(int32_t arg) { - USE_DLFUNC(wifi_stop_supplicant) - return wifi_stop_supplicant(arg); - } - - DEFINE_DLFUNC(wifi_command, int32_t, const char*, char*, size_t*) - int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) { - char command[COMMAND_SIZE]; - if (!strcmp(iface, "p2p0")) { - // Commands for p2p0 interface don't need prefix - SprintfLiteral(command, "%s", cmd); - } - else { - SprintfLiteral(command, "IFNAME=%s %s", iface, cmd); - } - USE_DLFUNC(wifi_command) - return wifi_command(command, buf, len); - } -}; - -// Concrete class to use to access the wpa supplicant. -WpaSupplicant::WpaSupplicant() -{ - char propVersion[PROPERTY_VALUE_MAX]; - property_get("ro.build.version.sdk", propVersion, "0"); - mSdkVersion = strtol(propVersion, nullptr, 10); - - if (mSdkVersion < 16) { - mImpl = MakeUnique<ICSWpaSupplicantImpl>(); - } else if (mSdkVersion < 19) { - mImpl = MakeUnique<JBWpaSupplicantImpl>(); - } else { - mImpl = MakeUnique<KKWpaSupplicantImpl>(); - } - mWifiHotspotUtils = MakeUnique<WifiHotspotUtils>(); -}; - -void WpaSupplicant::WaitForEvent(nsAString& aEvent, const nsCString& aInterface) -{ - CHECK_HWLIB() - - char buffer[BUFFER_SIZE]; - int32_t ret = mImpl->do_wifi_wait_for_event(aInterface.get(), buffer, BUFFER_SIZE); - CheckBuffer(buffer, ret, aEvent); -} - -#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aOptions.prop).get() - -/** - * Make a subnet mask. - */ -uint32_t WpaSupplicant::MakeMask(uint32_t len) { - uint32_t mask = 0; - for (uint32_t i = 0; i < len; ++i) { - mask |= (0x80000000 >> i); - } - return ntohl(mask); -} - -bool WpaSupplicant::ExecuteCommand(CommandOptions aOptions, - WifiResultOptions& aResult, - const nsCString& aInterface) -{ - CHECK_HWLIB(false) - - if (!mWifiHotspotUtils->GetSharedLibrary()) { - return false; - } - - // Always correlate the opaque ids. - aResult.mId = aOptions.mId; - - if (aOptions.mCmd.EqualsLiteral("command")) { - size_t len = BUFFER_SIZE - 1; - char buffer[BUFFER_SIZE]; - NS_ConvertUTF16toUTF8 request(aOptions.mRequest); - aResult.mStatus = mImpl->do_wifi_command(aInterface.get(), request.get(), buffer, &len); - nsString value; - if (aResult.mStatus == 0) { - if (buffer[len - 1] == '\n') { // remove trailing new lines. - len--; - } - buffer[len] = '\0'; - CheckBuffer(buffer, len, value); - } - aResult.mReply = value; - } else if (aOptions.mCmd.EqualsLiteral("close_supplicant_connection")) { - mImpl->do_wifi_close_supplicant_connection(aInterface.get()); - } else if (aOptions.mCmd.EqualsLiteral("load_driver")) { - aResult.mStatus = mImpl->do_wifi_load_driver(); - } else if (aOptions.mCmd.EqualsLiteral("unload_driver")) { - aResult.mStatus = mImpl->do_wifi_unload_driver(); - } else if (aOptions.mCmd.EqualsLiteral("start_supplicant")) { - aResult.mStatus = mImpl->do_wifi_start_supplicant(GetWifiP2pSupported() ? 1 : 0); - } else if (aOptions.mCmd.EqualsLiteral("stop_supplicant")) { - aResult.mStatus = mImpl->do_wifi_stop_supplicant(0); - } else if (aOptions.mCmd.EqualsLiteral("connect_to_supplicant")) { - aResult.mStatus = mImpl->do_wifi_connect_to_supplicant(aInterface.get()); - } else if (aOptions.mCmd.EqualsLiteral("hostapd_command")) { - size_t len = BUFFER_SIZE - 1; - char buffer[BUFFER_SIZE]; - NS_ConvertUTF16toUTF8 request(aOptions.mRequest); - aResult.mStatus = mWifiHotspotUtils->do_wifi_hostapd_command(request.get(), - buffer, - &len); - nsString value; - if (aResult.mStatus == 0) { - if (buffer[len - 1] == '\n') { // remove trailing new lines. - len--; - } - buffer[len] = '\0'; - CheckBuffer(buffer, len, value); - } - aResult.mReply = value; - } else if (aOptions.mCmd.EqualsLiteral("hostapd_get_stations")) { - aResult.mStatus = mWifiHotspotUtils->do_wifi_hostapd_get_stations(); - } else if (aOptions.mCmd.EqualsLiteral("connect_to_hostapd")) { - aResult.mStatus = mWifiHotspotUtils->do_wifi_connect_to_hostapd(); - } else if (aOptions.mCmd.EqualsLiteral("close_hostapd_connection")) { - aResult.mStatus = mWifiHotspotUtils->do_wifi_close_hostapd_connection(); - - } else { - NS_WARNING("WpaSupplicant::ExecuteCommand : Unknown command"); - printf_stderr("WpaSupplicant::ExecuteCommand : Unknown command: %s", - NS_ConvertUTF16toUTF8(aOptions.mCmd).get()); - return false; - } - - return true; -} - -// Checks the buffer and do the utf processing. -void -WpaSupplicant::CheckBuffer(char* buffer, int32_t length, - nsAString& aEvent) -{ - if (length <= 0 || length >= (BUFFER_SIZE - 1)) { - NS_WARNING("WpaSupplicant::CheckBuffer: Invalid buffer length"); - return; - } - - if (mSdkVersion < 18) { - buffer[length] = 0; - LossyConvertUTF8toUTF16(buffer, length, aEvent); - return; - } - - // After Android JB4.3, the SSIDs have been converted into printable form. - // In most of cases, SSIDs do not use unprintable characters, but IEEE 802.11 - // standard does not limit the used character set, so anything could be used - // in an SSID. Convert it to raw data form here. - char bytesBuffer[BUFFER_SIZE]; - uint32_t bytes = convertToBytes(bytesBuffer, length, buffer); - if (bytes <= 0 || bytes >= BUFFER_SIZE) { - NS_WARNING("WpaSupplicant::CheckBuffer: Invalid bytesbuffer length"); - return; - } - bytesBuffer[bytes] = 0; - LossyConvertUTF8toUTF16(bytesBuffer, bytes, aEvent); -} diff --git a/dom/wifi/WifiUtils.h b/dom/wifi/WifiUtils.h deleted file mode 100644 index a83ba9c15..000000000 --- a/dom/wifi/WifiUtils.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Abstraction on top of the wifi support from libhardware_legacy that we - * use to talk to the wpa_supplicant. - */ - -#ifndef WifiUtils_h -#define WifiUtils_h - -#include "nsString.h" -#include "mozilla/dom/WifiOptionsBinding.h" -#include "mozilla/UniquePtr.h" -#include "WifiHotspotUtils.h" - -// Needed to add a copy constructor to WifiCommandOptions. -struct CommandOptions -{ -public: - CommandOptions(const mozilla::dom::WifiCommandOptions& aOther) { - -#define COPY_OPT_FIELD(prop, defaultValue) \ - if (aOther.prop.WasPassed()) { \ - prop = aOther.prop.Value(); \ - } else { \ - prop = defaultValue; \ - } - -#define COPY_FIELD(prop) prop = aOther.prop; - COPY_FIELD(mId) - COPY_FIELD(mCmd) - COPY_OPT_FIELD(mRequest, EmptyString()) - -#undef COPY_OPT_FIELD -#undef COPY_FIELD - } - - // All the fields, not Optional<> anymore to get copy constructors. - nsString mCmd; - int32_t mId; - nsString mRequest; -}; - -// Abstract class that exposes libhardware_legacy functions we need for -// wifi management. -// We use the ICS signatures here since they are likely more future-proof. -class WpaSupplicantImpl -{ -public: - // Suppress warning from |UniquePtr| - virtual ~WpaSupplicantImpl() {} - - virtual int32_t - do_wifi_wait_for_event(const char *iface, char *buf, size_t len) = 0; // KK == ICS != JB - - virtual int32_t - do_wifi_command(const char* iface, const char* cmd, char* buff, size_t* len) = 0; // KK == ICS != JB - - virtual int32_t - do_wifi_load_driver() = 0; - - virtual int32_t - do_wifi_unload_driver() = 0; - - virtual int32_t - do_wifi_start_supplicant(int32_t) = 0; // ICS != JB == KK - - virtual int32_t - do_wifi_stop_supplicant(int32_t) = 0; //ICS != JB == KK - - virtual int32_t - do_wifi_connect_to_supplicant(const char* iface) = 0; // KK == ICS != JB - - virtual void - do_wifi_close_supplicant_connection(const char* iface) = 0; // KK == ICS != JB -}; - -// Concrete class to use to access the wpa supplicant. -class WpaSupplicant final -{ -public: - WpaSupplicant(); - - // Use nsCString as the type of aInterface to guarantee it's - // null-terminated so that we can pass it to c API without - // conversion - void WaitForEvent(nsAString& aEvent, const nsCString& aInterface); - bool ExecuteCommand(CommandOptions aOptions, - mozilla::dom::WifiResultOptions& result, - const nsCString& aInterface); - -private: - UniquePtr<WpaSupplicantImpl> mImpl; - UniquePtr<WifiHotspotUtils> mWifiHotspotUtils; - - uint32_t mSdkVersion; - -protected: - void CheckBuffer(char* buffer, int32_t length, nsAString& aEvent); - uint32_t MakeMask(uint32_t len); -}; - -#endif // WifiUtils_h diff --git a/dom/wifi/WifiWorker.h b/dom/wifi/WifiWorker.h deleted file mode 100644 index 2cd89c3e7..000000000 --- a/dom/wifi/WifiWorker.h +++ /dev/null @@ -1,9 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#define NS_WIFIWORKER_CID \ -{ 0xA14E8977, 0xD259, 0x433A, \ - { 0xA8, 0x8D, 0x58, 0xDD, 0x44, 0x65, 0x7E, 0x5B } } diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js deleted file mode 100644 index 243ba8b97..000000000 --- a/dom/wifi/WifiWorker.js +++ /dev/null @@ -1,3928 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/systemlibs.js"); -Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource://gre/modules/WifiCommand.jsm"); -Cu.import("resource://gre/modules/WifiNetUtil.jsm"); -Cu.import("resource://gre/modules/WifiP2pManager.jsm"); -Cu.import("resource://gre/modules/WifiP2pWorkerObserver.jsm"); - -var DEBUG = false; // set to true to show debug messages. - -const WIFIWORKER_CONTRACTID = "@mozilla.org/wifi/worker;1"; -const WIFIWORKER_CID = Components.ID("{a14e8977-d259-433a-a88d-58dd44657e5b}"); - -const WIFIWORKER_WORKER = "resource://gre/modules/wifi_worker.js"; - -const kMozSettingsChangedObserverTopic = "mozsettings-changed"; - -const MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2; -const MAX_SUPPLICANT_LOOP_ITERATIONS = 4; -const MAX_RETRIES_ON_DHCP_FAILURE = 2; - -// Settings DB path for wifi -const SETTINGS_WIFI_ENABLED = "wifi.enabled"; -const SETTINGS_WIFI_DEBUG_ENABLED = "wifi.debugging.enabled"; -// Settings DB path for Wifi tethering. -const SETTINGS_WIFI_TETHERING_ENABLED = "tethering.wifi.enabled"; -const SETTINGS_WIFI_SSID = "tethering.wifi.ssid"; -const SETTINGS_WIFI_SECURITY_TYPE = "tethering.wifi.security.type"; -const SETTINGS_WIFI_SECURITY_PASSWORD = "tethering.wifi.security.password"; -const SETTINGS_WIFI_IP = "tethering.wifi.ip"; -const SETTINGS_WIFI_PREFIX = "tethering.wifi.prefix"; -const SETTINGS_WIFI_DHCPSERVER_STARTIP = "tethering.wifi.dhcpserver.startip"; -const SETTINGS_WIFI_DHCPSERVER_ENDIP = "tethering.wifi.dhcpserver.endip"; -const SETTINGS_WIFI_DNS1 = "tethering.wifi.dns1"; -const SETTINGS_WIFI_DNS2 = "tethering.wifi.dns2"; - -// Settings DB path for USB tethering. -const SETTINGS_USB_DHCPSERVER_STARTIP = "tethering.usb.dhcpserver.startip"; -const SETTINGS_USB_DHCPSERVER_ENDIP = "tethering.usb.dhcpserver.endip"; - -// Default value for WIFI tethering. -const DEFAULT_WIFI_IP = "192.168.1.1"; -const DEFAULT_WIFI_PREFIX = "24"; -const DEFAULT_WIFI_DHCPSERVER_STARTIP = "192.168.1.10"; -const DEFAULT_WIFI_DHCPSERVER_ENDIP = "192.168.1.30"; -const DEFAULT_WIFI_SSID = "FirefoxHotspot"; -const DEFAULT_WIFI_SECURITY_TYPE = "open"; -const DEFAULT_WIFI_SECURITY_PASSWORD = "1234567890"; -const DEFAULT_DNS1 = "8.8.8.8"; -const DEFAULT_DNS2 = "8.8.4.4"; - -// Default value for USB tethering. -const DEFAULT_USB_DHCPSERVER_STARTIP = "192.168.0.10"; -const DEFAULT_USB_DHCPSERVER_ENDIP = "192.168.0.30"; - -const WIFI_FIRMWARE_AP = "AP"; -const WIFI_FIRMWARE_STATION = "STA"; -const WIFI_SECURITY_TYPE_NONE = "open"; -const WIFI_SECURITY_TYPE_WPA_PSK = "wpa-psk"; -const WIFI_SECURITY_TYPE_WPA2_PSK = "wpa2-psk"; - -const NETWORK_INTERFACE_UP = "up"; -const NETWORK_INTERFACE_DOWN = "down"; - -const DEFAULT_WLAN_INTERFACE = "wlan0"; - -const DRIVER_READY_WAIT = 2000; - -const SUPP_PROP = "init.svc.wpa_supplicant"; -const WPA_SUPPLICANT = "wpa_supplicant"; -const DHCP_PROP = "init.svc.dhcpcd"; -const DHCP = "dhcpcd"; - -const MODE_ESS = 0; -const MODE_IBSS = 1; - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager", - "@mozilla.org/network/manager;1", - "nsINetworkManager"); - -XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", - "@mozilla.org/network/service;1", - "nsINetworkService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", - "@mozilla.org/settingsService;1", - "nsISettingsService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gTetheringService", - "@mozilla.org/tethering/service;1", - "nsITetheringService"); - -// A note about errors and error handling in this file: -// The libraries that we use in this file are intended for C code. For -// C code, it is natural to return -1 for errors and 0 for success. -// Therefore, the code that interacts directly with the worker uses this -// convention (note: command functions do get boolean results since the -// command always succeeds and we do a string/boolean check for the -// expected results). -var WifiManager = (function() { - var manager = {}; - - function getStartupPrefs() { - return { - sdkVersion: parseInt(libcutils.property_get("ro.build.version.sdk"), 10), - unloadDriverEnabled: libcutils.property_get("ro.moz.wifi.unloaddriver") === "1", - schedScanRecovery: libcutils.property_get("ro.moz.wifi.sched_scan_recover") === "false" ? false : true, - driverDelay: libcutils.property_get("ro.moz.wifi.driverDelay"), - p2pSupported: libcutils.property_get("ro.moz.wifi.p2p_supported") === "1", - eapSimSupported: libcutils.property_get("ro.moz.wifi.eapsim_supported") === "1", - ibssSupported: libcutils.property_get("ro.moz.wifi.ibss_supported", "true") === "true", - ifname: libcutils.property_get("wifi.interface") - }; - } - - let {sdkVersion, unloadDriverEnabled, schedScanRecovery, - driverDelay, p2pSupported, eapSimSupported, ibssSupported, ifname} = getStartupPrefs(); - - let capabilities = { - security: ["OPEN", "WEP", "WPA-PSK", "WPA-EAP"], - eapMethod: ["PEAP", "TTLS", "TLS"], - eapPhase2: ["MSCHAPV2"], - certificate: ["SERVER"], - mode: [MODE_ESS] - }; - if (eapSimSupported) { - capabilities.eapMethod.unshift("SIM"); - } - if (ibssSupported) { - capabilities.mode.push(MODE_IBSS); - } - - let wifiListener = { - onWaitEvent: function(event, iface) { - if (manager.ifname === iface && handleEvent(event)) { - waitForEvent(iface); - } else if (p2pSupported) { - // Please refer to - // http://androidxref.com/4.4.2_r1/xref/frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java#519 - // for interface event mux/demux rules. In short words, both - // 'p2p0' and 'p2p-' should go to Wifi P2P state machine. - if (WifiP2pManager.INTERFACE_NAME === iface || -1 !== iface.indexOf('p2p-')) { - // If the connection is closed, wifi.c::wifi_wait_for_event() - // will still return 'CTRL-EVENT-TERMINATING - connection closed' - // rather than blocking. So when we see this special event string, - // just return immediately. - const TERMINATED_EVENT = 'CTRL-EVENT-TERMINATING - connection closed'; - if (-1 !== event.indexOf(TERMINATED_EVENT)) { - return; - } - p2pManager.handleEvent(event); - waitForEvent(iface); - } - } - }, - - onCommand: function(event, iface) { - onmessageresult(event, iface); - } - } - - manager.ifname = ifname; - manager.connectToSupplicant = false; - // Emulator build runs to here. - // The debug() should only be used after WifiManager. - if (!ifname) { - manager.ifname = DEFAULT_WLAN_INTERFACE; - } - manager.schedScanRecovery = schedScanRecovery; - manager.driverDelay = driverDelay ? parseInt(driverDelay, 10) : DRIVER_READY_WAIT; - - // Regular Wifi stuff. - var netUtil = WifiNetUtil(controlMessage); - var wifiCommand = WifiCommand(controlMessage, manager.ifname, sdkVersion); - - // Wifi P2P stuff - var p2pManager; - if (p2pSupported) { - let p2pCommand = WifiCommand(controlMessage, WifiP2pManager.INTERFACE_NAME, sdkVersion); - p2pManager = WifiP2pManager(p2pCommand, netUtil); - } - - let wifiService = Cc["@mozilla.org/wifi/service;1"]; - if (wifiService) { - wifiService = wifiService.getService(Ci.nsIWifiProxyService); - let interfaces = [manager.ifname]; - if (p2pSupported) { - interfaces.push(WifiP2pManager.INTERFACE_NAME); - } - wifiService.start(wifiListener, interfaces, interfaces.length); - } else { - debug("No wifi service component available!"); - } - - // Callbacks to invoke when a reply arrives from the wifi service. - var controlCallbacks = Object.create(null); - var idgen = 0; - - function controlMessage(obj, callback) { - var id = idgen++; - obj.id = id; - if (callback) { - controlCallbacks[id] = callback; - } - wifiService.sendCommand(obj, obj.iface); - } - - let onmessageresult = function(data, iface) { - var id = data.id; - var callback = controlCallbacks[id]; - if (callback) { - callback(data); - delete controlCallbacks[id]; - } - } - - // Polling the status worker - var recvErrors = 0; - - function waitForEvent(iface) { - wifiService.waitForEvent(iface); - } - - // Commands to the control worker. - - var driverLoaded = false; - - function loadDriver(callback) { - if (driverLoaded) { - callback(0); - return; - } - - wifiCommand.loadDriver(function (status) { - driverLoaded = (status >= 0); - callback(status) - }); - } - - function unloadDriver(type, callback) { - if (!unloadDriverEnabled) { - // Unloading drivers is generally unnecessary and - // can trigger bugs in some drivers. - // On properly written drivers, bringing the interface - // down powers down the interface. - if (type === WIFI_FIRMWARE_STATION) { - notify("supplicantlost", { success: true }); - } - callback(0); - return; - } - - wifiCommand.unloadDriver(function(status) { - driverLoaded = (status < 0); - if (type === WIFI_FIRMWARE_STATION) { - notify("supplicantlost", { success: true }); - } - callback(status); - }); - } - - // A note about background scanning: - // Normally, background scanning shouldn't be necessary as wpa_supplicant - // has the capability to automatically schedule its own scans at appropriate - // intervals. However, with some drivers, this appears to get stuck after - // three scans, so we enable the driver's background scanning to work around - // that when we're not connected to any network. This ensures that we'll - // automatically reconnect to networks if one falls out of range. - var reEnableBackgroundScan = false; - - // NB: This is part of the internal API. - manager.backgroundScanEnabled = false; - function setBackgroundScan(enable, callback) { - var doEnable = (enable === "ON"); - if (doEnable === manager.backgroundScanEnabled) { - callback(false, true); - return; - } - - manager.backgroundScanEnabled = doEnable; - wifiCommand.setBackgroundScan(manager.backgroundScanEnabled, callback); - } - - var scanModeActive = false; - - function scan(forceActive, callback) { - if (forceActive && !scanModeActive) { - // Note: we ignore errors from doSetScanMode. - wifiCommand.doSetScanMode(true, function(ignore) { - setBackgroundScan("OFF", function(turned, ignore) { - reEnableBackgroundScan = turned; - manager.handlePreWifiScan(); - wifiCommand.scan(function(ok) { - wifiCommand.doSetScanMode(false, function(ignore) { - // The result of scanCommand is the result of the actual SCAN - // request. - callback(ok); - }); - }); - }); - }); - return; - } - manager.handlePreWifiScan(); - wifiCommand.scan(callback); - } - - var debugEnabled = false; - - function syncDebug() { - if (debugEnabled !== DEBUG) { - let wanted = DEBUG; - wifiCommand.setLogLevel(wanted ? "DEBUG" : "INFO", function(ok) { - if (ok) - debugEnabled = wanted; - }); - if (p2pSupported && p2pManager) { - p2pManager.setDebug(DEBUG); - } - } - } - - function getDebugEnabled(callback) { - wifiCommand.getLogLevel(function(level) { - if (level === null) { - debug("Unable to get wpa_supplicant's log level"); - callback(false); - return; - } - - var lines = level.split("\n"); - for (let i = 0; i < lines.length; ++i) { - let match = /Current level: (.*)/.exec(lines[i]); - if (match) { - debugEnabled = match[1].toLowerCase() === "debug"; - callback(true); - return; - } - } - - // If we're here, we didn't get the current level. - callback(false); - }); - } - - function setScanMode(setActive, callback) { - scanModeActive = setActive; - wifiCommand.doSetScanMode(setActive, callback); - } - - var httpProxyConfig = Object.create(null); - - /** - * Given a network, configure http proxy when using wifi. - * @param network A network object to update http proxy - * @param info Info should have following field: - * - httpProxyHost ip address of http proxy. - * - httpProxyPort port of http proxy, set 0 to use default port 8080. - * @param callback callback function. - */ - function configureHttpProxy(network, info, callback) { - if (!network) - return; - - let networkKey = getNetworkKey(network); - - if (!info || info.httpProxyHost === "") { - delete httpProxyConfig[networkKey]; - } else { - httpProxyConfig[networkKey] = network; - httpProxyConfig[networkKey].httpProxyHost = info.httpProxyHost; - httpProxyConfig[networkKey].httpProxyPort = info.httpProxyPort; - } - - callback(true); - } - - function getHttpProxyNetwork(network) { - if (!network) - return null; - - let networkKey = getNetworkKey(network); - return httpProxyConfig[networkKey]; - } - - function setHttpProxy(network) { - if (!network) - return; - - // If we got here, arg network must be the currentNetwork, so we just update - // WifiNetworkInterface correspondingly and notify NetworkManager. - WifiNetworkInterface.httpProxyHost = network.httpProxyHost; - WifiNetworkInterface.httpProxyPort = network.httpProxyPort; - - if (WifiNetworkInterface.info.state == - Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - gNetworkManager.updateNetworkInterface(WifiNetworkInterface); - } - } - - var staticIpConfig = Object.create(null); - function setStaticIpMode(network, info, callback) { - let setNetworkKey = getNetworkKey(network); - let curNetworkKey = null; - let currentNetwork = Object.create(null); - currentNetwork.netId = manager.connectionInfo.id; - - manager.getNetworkConfiguration(currentNetwork, function () { - curNetworkKey = getNetworkKey(currentNetwork); - - // Add additional information to static ip configuration - // It is used to compatiable with information dhcp callback. - info.ipaddr = netHelpers.stringToIP(info.ipaddr_str); - info.gateway = netHelpers.stringToIP(info.gateway_str); - info.mask_str = netHelpers.ipToString(netHelpers.makeMask(info.maskLength)); - - // Optional - info.dns1 = netHelpers.stringToIP(info.dns1_str); - info.dns2 = netHelpers.stringToIP(info.dns2_str); - info.proxy = netHelpers.stringToIP(info.proxy_str); - - staticIpConfig[setNetworkKey] = info; - - // If the ssid of current connection is the same as configured ssid - // It means we need update current connection to use static IP address. - if (setNetworkKey == curNetworkKey) { - // Use configureInterface directly doesn't work, the network interface - // and routing table is changed but still cannot connect to network - // so the workaround here is disable interface the enable again to - // trigger network reconnect with static ip. - gNetworkService.disableInterface(manager.ifname, function (ok) { - gNetworkService.enableInterface(manager.ifname, function (ok) { - callback(ok); - }); - }); - return; - } - - callback(true); - }); - } - - var dhcpInfo = null; - - function runStaticIp(ifname, key) { - debug("Run static ip"); - - // Read static ip information from settings. - let staticIpInfo; - - if (!(key in staticIpConfig)) - return; - - staticIpInfo = staticIpConfig[key]; - - // Stop dhcpd when use static IP - if (dhcpInfo != null) { - netUtil.stopDhcp(manager.ifname, function() {}); - } - - // Set ip, mask length, gateway, dns to network interface - gNetworkService.configureInterface( { ifname: ifname, - ipaddr: staticIpInfo.ipaddr, - mask: staticIpInfo.maskLength, - gateway: staticIpInfo.gateway, - dns1: staticIpInfo.dns1, - dns2: staticIpInfo.dns2 }, function (data) { - netUtil.runIpConfig(ifname, staticIpInfo, function(data) { - dhcpInfo = data.info; - notify("networkconnected", data); - }); - }); - } - - var suppressEvents = false; - function notify(eventName, eventObject) { - if (suppressEvents) - return; - var handler = manager["on" + eventName]; - if (handler) { - if (!eventObject) - eventObject = ({}); - handler.call(eventObject); - } - } - - function notifyStateChange(fields) { - // If we're already in the COMPLETED state, we might receive events from - // the supplicant that tell us that we're re-authenticating or reminding - // us that we're associated to a network. In those cases, we don't need to - // do anything, so just ignore them. - if (manager.state === "COMPLETED" && - fields.state !== "DISCONNECTED" && - fields.state !== "INTERFACE_DISABLED" && - fields.state !== "INACTIVE" && - fields.state !== "SCANNING") { - return false; - } - - // Stop background scanning if we're trying to connect to a network. - if (manager.backgroundScanEnabled && - (fields.state === "ASSOCIATING" || - fields.state === "ASSOCIATED" || - fields.state === "FOUR_WAY_HANDSHAKE" || - fields.state === "GROUP_HANDSHAKE" || - fields.state === "COMPLETED")) { - setBackgroundScan("OFF", function() {}); - } - - fields.prevState = manager.state; - // Detect wpa_supplicant's loop iterations. - manager.supplicantLoopDetection(fields.prevState, fields.state); - notify("statechange", fields); - - // Don't update state when and after disabling. - if (manager.state === "DISABLING" || - manager.state === "UNINITIALIZED") { - return false; - } - - manager.state = fields.state; - return true; - } - - function parseStatus(status) { - if (status === null) { - debug("Unable to get wpa supplicant's status"); - return; - } - - var ssid; - var bssid; - var state; - var ip_address; - var id; - - var lines = status.split("\n"); - for (let i = 0; i < lines.length; ++i) { - let [key, value] = lines[i].split("="); - switch (key) { - case "wpa_state": - state = value; - break; - case "ssid": - ssid = value; - break; - case "bssid": - bssid = value; - break; - case "ip_address": - ip_address = value; - break; - case "id": - id = value; - break; - } - } - - if (bssid && ssid) { - manager.connectionInfo.bssid = bssid; - manager.connectionInfo.ssid = ssid; - manager.connectionInfo.id = id; - } - - if (ip_address) - dhcpInfo = { ip_address: ip_address }; - - notifyStateChange({ state: state, fromStatus: true }); - - // If we parse the status and the supplicant has already entered the - // COMPLETED state, then we need to set up DHCP right away. - if (state === "COMPLETED") - onconnected(); - } - - // try to connect to the supplicant - var connectTries = 0; - var retryTimer = null; - function connectCallback(ok) { - if (ok === 0) { - // Tell the event worker to start waiting for events. - retryTimer = null; - connectTries = 0; - recvErrors = 0; - manager.connectToSupplicant = true; - didConnectSupplicant(function(){}); - return; - } - if (connectTries++ < 5) { - // Try again in 1 seconds. - if (!retryTimer) - retryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - - retryTimer.initWithCallback(function(timer) { - wifiCommand.connectToSupplicant(connectCallback); - }, 1000, Ci.nsITimer.TYPE_ONE_SHOT); - return; - } - - retryTimer = null; - connectTries = 0; - notify("supplicantlost", { success: false }); - } - - manager.connectionDropped = function(callback) { - // Reset network interface when connection drop - gNetworkService.configureInterface( { ifname: manager.ifname, - ipaddr: 0, - mask: 0, - gateway: 0, - dns1: 0, - dns2: 0 }, function (data) { - }); - - // If we got disconnected, kill the DHCP client in preparation for - // reconnection. - gNetworkService.resetConnections(manager.ifname, function() { - netUtil.stopDhcp(manager.ifname, function() { - callback(); - }); - }); - } - - manager.start = function() { - debug("detected SDK version " + sdkVersion); - wifiCommand.connectToSupplicant(connectCallback); - } - - let dhcpRequestGen = 0; - - function onconnected() { - // For now we do our own DHCP. In the future, this should be handed - // off to the Network Manager. - let currentNetwork = Object.create(null); - currentNetwork.netId = manager.connectionInfo.id; - - manager.getNetworkConfiguration(currentNetwork, function (){ - let key = getNetworkKey(currentNetwork); - if (staticIpConfig && - (key in staticIpConfig) && - staticIpConfig[key].enabled) { - debug("Run static ip"); - runStaticIp(manager.ifname, key); - return; - } - netUtil.runDhcp(manager.ifname, dhcpRequestGen++, function(data, gen) { - dhcpInfo = data.info; - debug('dhcpRequestGen: ' + dhcpRequestGen + ', gen: ' + gen); - if (!dhcpInfo) { - if (gen + 1 < dhcpRequestGen) { - debug('Do not bother younger DHCP request.'); - return; - } - if (++manager.dhcpFailuresCount >= MAX_RETRIES_ON_DHCP_FAILURE) { - manager.dhcpFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - return; - } - // NB: We have to call disconnect first. Otherwise, we only reauth with - // the existing AP and don't retrigger DHCP. - manager.disconnect(function() { - manager.reassociate(function(){}); - }); - return; - } - - manager.dhcpFailuresCount = 0; - notify("networkconnected", data); - }); - }); - } - - var supplicantStatesMap = (sdkVersion >= 15) ? - ["DISCONNECTED", "INTERFACE_DISABLED", "INACTIVE", "SCANNING", - "AUTHENTICATING", "ASSOCIATING", "ASSOCIATED", "FOUR_WAY_HANDSHAKE", - "GROUP_HANDSHAKE", "COMPLETED"] - : - ["DISCONNECTED", "INACTIVE", "SCANNING", "ASSOCIATING", - "ASSOCIATED", "FOUR_WAY_HANDSHAKE", "GROUP_HANDSHAKE", - "COMPLETED", "DORMANT", "UNINITIALIZED"]; - - var driverEventMap = { STOPPED: "driverstopped", STARTED: "driverstarted", HANGED: "driverhung" }; - - manager.getNetworkId = function (ssid, callback) { - manager.getConfiguredNetworks(function(networks) { - if (!networks) { - debug("Unable to get configured networks"); - return callback(null); - } - for (let net in networks) { - let network = networks[net]; - // Trying to get netId from - // 1. network matching SSID if SSID is provided. - // 2. current network if no SSID is provided, it's not guaranteed that - // current network matches requested SSID. - if ((!ssid && network.status === "CURRENT") || - (ssid && network.ssid && ssid === dequote(network.ssid))) { - return callback(net); - } - } - callback(null); - }); - } - - function handleWpaEapEvents(event) { - if (event.indexOf("CTRL-EVENT-EAP-FAILURE") !== -1) { - if (event.indexOf("EAP authentication failed") !== -1) { - notify("passwordmaybeincorrect"); - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - } - return true; - } - if (event.indexOf("CTRL-EVENT-EAP-TLS-CERT-ERROR") !== -1) { - // Cert Error - notify("passwordmaybeincorrect"); - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - return true; - } - if (event.indexOf("CTRL-EVENT-EAP-STARTED") !== -1) { - notifyStateChange({ state: "AUTHENTICATING" }); - return true; - } - return true; - } - - // Handle events sent to us by the event worker. - function handleEvent(event) { - debug("Event coming in: " + event); - if (event.indexOf("CTRL-EVENT-") !== 0 && event.indexOf("WPS") !== 0) { - // Handle connection fail exception on WEP-128, while password length - // is not 5 nor 13 bytes. - if (event.indexOf("Association request to the driver failed") !== -1) { - notify("passwordmaybeincorrect"); - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - return true; - } - - if (event.indexOf("WPA:") == 0 && - event.indexOf("pre-shared key may be incorrect") != -1) { - notify("passwordmaybeincorrect"); - } - - // This is ugly, but we need to grab the SSID here. BSSID is not guaranteed - // to be provided, so don't grab BSSID here. - var match = /Trying to associate with.*SSID[ =]'(.*)'/.exec(event); - if (match) { - debug("Matched: " + match[1] + "\n"); - manager.connectionInfo.ssid = match[1]; - } - return true; - } - - var space = event.indexOf(" "); - var eventData = event.substr(0, space + 1); - if (eventData.indexOf("CTRL-EVENT-STATE-CHANGE") === 0) { - // Parse the event data. - var fields = {}; - var tokens = event.substr(space + 1).split(" "); - for (var n = 0; n < tokens.length; ++n) { - var kv = tokens[n].split("="); - if (kv.length === 2) - fields[kv[0]] = kv[1]; - } - if (!("state" in fields)) - return true; - fields.state = supplicantStatesMap[fields.state]; - - // The BSSID field is only valid in the ASSOCIATING and ASSOCIATED - // states, except when we "reauth", except this seems to depend on the - // driver, so simply check to make sure that we don't have a null BSSID. - if (fields.BSSID !== "00:00:00:00:00:00") - manager.connectionInfo.bssid = fields.BSSID; - - if (notifyStateChange(fields) && fields.state === "COMPLETED") { - onconnected(); - } - return true; - } - if (eventData.indexOf("CTRL-EVENT-DRIVER-STATE") === 0) { - var handlerName = driverEventMap[eventData]; - if (handlerName) - notify(handlerName); - return true; - } - if (eventData.indexOf("CTRL-EVENT-TERMINATING") === 0) { - // As long the monitor socket is not closed and we haven't seen too many - // recv errors yet, we will keep going for a bit longer. - if (event.indexOf("connection closed") === -1 && - event.indexOf("recv error") !== -1 && ++recvErrors < 10) - return true; - - notifyStateChange({ state: "DISCONNECTED", BSSID: null, id: -1 }); - - // If the supplicant is terminated as commanded, the supplicant lost - // notification will be sent after driver unloaded. In such case, the - // manager state will be "DISABLING" or "UNINITIALIZED". - // So if supplicant terminated with incorrect manager state, implying - // unexpected condition, we should notify supplicant lost here. - if (manager.state !== "DISABLING" && manager.state !== "UNINITIALIZED") { - notify("supplicantlost", { success: true }); - } - - if (manager.stopSupplicantCallback) { - cancelWaitForTerminateEventTimer(); - // It's possible that the terminating event triggered by timer comes - // earlier than the event from wpa_supplicant. Since - // stopSupplicantCallback contains async. callbacks, swap it to local - // to prevent calling the callback twice. - let stopSupplicantCallback = manager.stopSupplicantCallback.bind(manager); - manager.stopSupplicantCallback = null; - stopSupplicantCallback(); - stopSupplicantCallback = null; - } - return false; - } - if (eventData.indexOf("CTRL-EVENT-DISCONNECTED") === 0) { - var token = event.split(" ")[1]; - var bssid = token.split("=")[1]; - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - manager.connectionInfo.bssid = null; - manager.connectionInfo.ssid = null; - manager.connectionInfo.id = -1; - return true; - } - if (eventData.indexOf("CTRL-EVENT-CONNECTED") === 0) { - // Format: CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=] - var bssid = event.split(" ")[4]; - - var keyword = "id="; - var id = event.substr(event.indexOf(keyword) + keyword.length).split(" ")[0]; - // Read current BSSID here, it will always being provided. - manager.connectionInfo.id = id; - manager.connectionInfo.bssid = bssid; - return true; - } - if (eventData.indexOf("CTRL-EVENT-SCAN-RESULTS") === 0) { - debug("Notifying of scan results available"); - if (reEnableBackgroundScan) { - reEnableBackgroundScan = false; - setBackgroundScan("ON", function() {}); - } - manager.handlePostWifiScan(); - notify("scanresultsavailable"); - return true; - } - if (eventData.indexOf("CTRL-EVENT-EAP") === 0) { - return handleWpaEapEvents(event); - } - if (eventData.indexOf("CTRL-EVENT-ASSOC-REJECT") === 0) { - debug("CTRL-EVENT-ASSOC-REJECT: network error"); - notify("passwordmaybeincorrect"); - if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) { - manager.authenticationFailuresCount = 0; - debug("CTRL-EVENT-ASSOC-REJECT: disconnect network"); - notify("disconnected", {connectionInfo: manager.connectionInfo}); - } - return true; - } - if (eventData.indexOf("WPS-TIMEOUT") === 0) { - notifyStateChange({ state: "WPS_TIMEOUT", BSSID: null, id: -1 }); - return true; - } - if (eventData.indexOf("WPS-FAIL") === 0) { - notifyStateChange({ state: "WPS_FAIL", BSSID: null, id: -1 }); - return true; - } - if (eventData.indexOf("WPS-OVERLAP-DETECTED") === 0) { - notifyStateChange({ state: "WPS_OVERLAP_DETECTED", BSSID: null, id: -1 }); - return true; - } - // Unknown event. - return true; - } - - function setPowerSavingMode(enabled) { - let mode = enabled ? "AUTO" : "ACTIVE"; - // Some wifi drivers may not implement this command. Set power mode - // even if suspend optimization command failed. - manager.setSuspendOptimizations(enabled, function(ok) { - manager.setPowerMode(mode, function() {}); - }); - } - - function didConnectSupplicant(callback) { - waitForEvent(manager.ifname); - - // Load up the supplicant state. - getDebugEnabled(function(ok) { - syncDebug(); - }); - wifiCommand.status(function(status) { - parseStatus(status); - notify("supplicantconnection"); - callback(); - }); - // WPA supplicant already connected. - manager.setPowerSavingMode(true); - if (p2pSupported) { - manager.enableP2p(function(success) {}); - } - } - - function prepareForStartup(callback) { - let status = libcutils.property_get(DHCP_PROP + "_" + manager.ifname); - if (status !== "running") { - tryStopSupplicant(); - return; - } - manager.connectionDropped(function() { - tryStopSupplicant(); - }); - - // Ignore any errors and kill any currently-running supplicants. On some - // phones, stopSupplicant won't work for a supplicant that we didn't - // start, so we hand-roll it here. - function tryStopSupplicant () { - let status = libcutils.property_get(SUPP_PROP); - if (status !== "running") { - callback(); - return; - } - suppressEvents = true; - wifiCommand.killSupplicant(function() { - gNetworkService.disableInterface(manager.ifname, function (ok) { - suppressEvents = false; - callback(); - }); - }); - } - } - - // Initial state. - manager.state = "UNINITIALIZED"; - manager.tetheringState = "UNINITIALIZED"; - manager.supplicantStarted = false; - manager.connectionInfo = { ssid: null, bssid: null, id: -1 }; - manager.authenticationFailuresCount = 0; - manager.loopDetectionCount = 0; - manager.dhcpFailuresCount = 0; - manager.stopSupplicantCallback = null; - - manager.__defineGetter__("enabled", function() { - switch (manager.state) { - case "UNINITIALIZED": - case "INITIALIZING": - case "DISABLING": - return false; - default: - return true; - } - }); - - var waitForTerminateEventTimer = null; - function cancelWaitForTerminateEventTimer() { - if (waitForTerminateEventTimer) { - waitForTerminateEventTimer.cancel(); - waitForTerminateEventTimer = null; - } - }; - function createWaitForTerminateEventTimer(onTimeout) { - if (waitForTerminateEventTimer) { - return; - } - waitForTerminateEventTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - waitForTerminateEventTimer.initWithCallback(onTimeout, - 4000, - Ci.nsITimer.TYPE_ONE_SHOT); - }; - - var waitForDriverReadyTimer = null; - function cancelWaitForDriverReadyTimer() { - if (waitForDriverReadyTimer) { - waitForDriverReadyTimer.cancel(); - waitForDriverReadyTimer = null; - } - }; - function createWaitForDriverReadyTimer(onTimeout) { - waitForDriverReadyTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - waitForDriverReadyTimer.initWithCallback(onTimeout, - manager.driverDelay, - Ci.nsITimer.TYPE_ONE_SHOT); - }; - - // Public interface of the wifi service. - manager.setWifiEnabled = function(enabled, callback) { - if (enabled === manager.isWifiEnabled(manager.state)) { - callback("no change"); - return; - } - - if (enabled) { - manager.state = "INITIALIZING"; - // Register as network interface. - WifiNetworkInterface.info.name = manager.ifname; - if (!WifiNetworkInterface.registered) { - gNetworkManager.registerNetworkInterface(WifiNetworkInterface); - WifiNetworkInterface.registered = true; - } - WifiNetworkInterface.info.state = - Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; - WifiNetworkInterface.info.ips = []; - WifiNetworkInterface.info.prefixLengths = []; - WifiNetworkInterface.info.gateways = []; - WifiNetworkInterface.info.dnses = []; - gNetworkManager.updateNetworkInterface(WifiNetworkInterface); - - prepareForStartup(function() { - loadDriver(function (status) { - if (status < 0) { - callback(status); - manager.state = "UNINITIALIZED"; - return; - } - // This command is mandatory for Nexus 4. But some devices like - // Galaxy S2 don't support it. Continue to start wpa_supplicant - // even if we fail to set wifi operation mode to station. - gNetworkService.setWifiOperationMode(manager.ifname, - WIFI_FIRMWARE_STATION, - function (status) { - - function startSupplicantInternal() { - wifiCommand.startSupplicant(function (status) { - if (status < 0) { - unloadDriver(WIFI_FIRMWARE_STATION, function() { - callback(status); - }); - manager.state = "UNINITIALIZED"; - return; - } - - manager.supplicantStarted = true; - gNetworkService.enableInterface(manager.ifname, function (ok) { - callback(ok ? 0 : -1); - }); - }); - } - - function doStartSupplicant() { - cancelWaitForDriverReadyTimer(); - - if (!manager.connectToSupplicant) { - startSupplicantInternal(); - return; - } - wifiCommand.closeSupplicantConnection(function () { - manager.connectToSupplicant = false; - // closeSupplicantConnection() will trigger onsupplicantlost - // and set manager.state to "UNINITIALIZED", we have to - // restore it here. - manager.state = "INITIALIZING"; - startSupplicantInternal(); - }); - } - // Driver startup on certain platforms takes longer than it takes for us - // to return from loadDriver, so wait 2 seconds before starting - // the supplicant to give it a chance to start. - if (manager.driverDelay > 0) { - createWaitForDriverReadyTimer(doStartSupplicant); - } else { - doStartSupplicant(); - } - }); - }); - }); - } else { - manager.state = "DISABLING"; - // Note these following calls ignore errors. If we fail to kill the - // supplicant gracefully, then we need to continue telling it to die - // until it does. - let doDisableWifi = function() { - manager.stopSupplicantCallback = (function () { - wifiCommand.stopSupplicant(function (status) { - wifiCommand.closeSupplicantConnection(function() { - manager.connectToSupplicant = false; - manager.state = "UNINITIALIZED"; - gNetworkService.disableInterface(manager.ifname, function (ok) { - unloadDriver(WIFI_FIRMWARE_STATION, callback); - }); - }); - }); - }).bind(this); - - let terminateEventCallback = (function() { - handleEvent("CTRL-EVENT-TERMINATING"); - }).bind(this); - createWaitForTerminateEventTimer(terminateEventCallback); - - // We are going to terminate the connection between wpa_supplicant. - // Stop the polling timer immediately to prevent connection info update - // command blocking in control thread until socket timeout. - notify("stopconnectioninfotimer"); - - wifiCommand.terminateSupplicant(function (ok) { - manager.connectionDropped(function () { - }); - }); - } - - if (p2pSupported) { - p2pManager.setEnabled(false, { onDisabled: doDisableWifi }); - } else { - doDisableWifi(); - } - } - } - - var wifiHotspotStatusTimer = null; - function cancelWifiHotspotStatusTimer() { - if (wifiHotspotStatusTimer) { - wifiHotspotStatusTimer.cancel(); - wifiHotspotStatusTimer = null; - } - } - - function createWifiHotspotStatusTimer(onTimeout) { - wifiHotspotStatusTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - wifiHotspotStatusTimer.init(onTimeout, 5000, Ci.nsITimer.TYPE_REPEATING_SLACK); - } - - // Get wifi interface and load wifi driver when enable Ap mode. - manager.setWifiApEnabled = function(enabled, configuration, callback) { - if (enabled === manager.isWifiTetheringEnabled(manager.tetheringState)) { - callback("no change"); - return; - } - - if (enabled) { - manager.tetheringState = "INITIALIZING"; - loadDriver(function (status) { - if (status < 0) { - callback(); - manager.tetheringState = "UNINITIALIZED"; - if (wifiHotspotStatusTimer) { - cancelWifiHotspotStatusTimer(); - wifiCommand.closeHostapdConnection(function(result) { - }); - } - return; - } - - function getWifiHotspotStatus() { - wifiCommand.hostapdGetStations(function(result) { - notify("stationinfoupdate", {station: result}); - }); - } - - function doStartWifiTethering() { - cancelWaitForDriverReadyTimer(); - WifiNetworkInterface.info.name = - libcutils.property_get("wifi.tethering.interface", manager.ifname); - gTetheringService.setWifiTethering(enabled, - WifiNetworkInterface.info.name, - configuration, function(result) { - if (result) { - manager.tetheringState = "UNINITIALIZED"; - } else { - manager.tetheringState = "COMPLETED"; - wifiCommand.connectToHostapd(function(result) { - if (result) { - return; - } - // Create a timer to track the connection status. - createWifiHotspotStatusTimer(getWifiHotspotStatus); - }); - } - // Pop out current request. - callback(); - // Should we fire a dom event if we fail to set wifi tethering ? - debug("Enable Wifi tethering result: " + (result ? result : "successfully")); - }); - } - - // Driver startup on certain platforms takes longer than it takes - // for us to return from loadDriver, so wait 2 seconds before - // turning on Wifi tethering. - createWaitForDriverReadyTimer(doStartWifiTethering); - }); - } else { - cancelWifiHotspotStatusTimer(); - gTetheringService.setWifiTethering(enabled, WifiNetworkInterface, - configuration, function(result) { - // Should we fire a dom event if we fail to set wifi tethering ? - debug("Disable Wifi tethering result: " + (result ? result : "successfully")); - // Unload wifi driver even if we fail to control wifi tethering. - unloadDriver(WIFI_FIRMWARE_AP, function(status) { - if (status < 0) { - debug("Fail to unload wifi driver"); - } - manager.tetheringState = "UNINITIALIZED"; - callback(); - }); - }); - } - } - - manager.disconnect = wifiCommand.disconnect; - manager.reconnect = wifiCommand.reconnect; - manager.reassociate = wifiCommand.reassociate; - - var networkConfigurationFields = [ - {name: "ssid", type: "string"}, - {name: "bssid", type: "string"}, - {name: "psk", type: "string"}, - {name: "wep_key0", type: "string"}, - {name: "wep_key1", type: "string"}, - {name: "wep_key2", type: "string"}, - {name: "wep_key3", type: "string"}, - {name: "wep_tx_keyidx", type: "integer"}, - {name: "priority", type: "integer"}, - {name: "key_mgmt", type: "string"}, - {name: "scan_ssid", type: "string"}, - {name: "disabled", type: "integer"}, - {name: "identity", type: "string"}, - {name: "password", type: "string"}, - {name: "auth_alg", type: "string"}, - {name: "phase1", type: "string"}, - {name: "phase2", type: "string"}, - {name: "eap", type: "string"}, - {name: "pin", type: "string"}, - {name: "pcsc", type: "string"}, - {name: "ca_cert", type: "string"}, - {name: "subject_match", type: "string"}, - {name: "client_cert", type: "string"}, - {name: "private_key", type: "stirng"}, - {name: "engine", type: "integer"}, - {name: "engine_id", type: "string"}, - {name: "key_id", type: "string"}, - {name: "frequency", type: "integer"}, - {name: "mode", type: "integer"} - ]; - // These fields are only handled in IBSS (aka ad-hoc) mode - var ibssNetworkConfigurationFields = [ - "frequency", "mode" - ]; - - manager.getNetworkConfiguration = function(config, callback) { - var netId = config.netId; - var done = 0; - for (var n = 0; n < networkConfigurationFields.length; ++n) { - let fieldName = networkConfigurationFields[n].name; - let fieldType = networkConfigurationFields[n].type; - wifiCommand.getNetworkVariable(netId, fieldName, function(value) { - if (value !== null) { - if (fieldType === "integer") { - config[fieldName] = parseInt(value, 10); - } else if ( fieldName == "ssid" && value[0] != '"' ) { - // SET_NETWORK will set a quoted ssid to wpa_supplicant. - // But if ssid contains non-ascii char, it will be converted into utf-8. - // For example: "Testçš„wifi" --> 54657374e79a8477696669 - // When GET_NETWORK receive a un-quoted utf-8 ssid, it must be decoded and quoted. - config[fieldName] = quote(decodeURIComponent(value.replace(/[0-9a-f]{2}/g, '%$&'))); - } else { - // value is string type by default. - config[fieldName] = value; - } - } - if (++done == networkConfigurationFields.length) - callback(config); - }); - } - } - manager.setNetworkConfiguration = function(config, callback) { - var netId = config.netId; - var done = 0; - var errors = 0; - - function hasValidProperty(name) { - return ((name in config) && - config[name] != null && - (["password", "wep_key0", "psk"].indexOf(name) === -1 || - config[name] !== '*')); - } - - function getModeFromConfig() { - /* we use the mode from the config, or ESS as default */ - return hasValidProperty("mode") ? config["mode"] : MODE_ESS; - } - - var mode = getModeFromConfig(); - - function validForMode(name, mode) { - /* all fields are valid for IBSS */ - return (mode == MODE_IBSS) || - /* IBSS fields are not valid for ESS */ - ((mode == MODE_ESS) && !(name in ibssNetworkConfigurationFields)); - } - - for (var n = 0; n < networkConfigurationFields.length; ++n) { - let fieldName = networkConfigurationFields[n].name; - if (!hasValidProperty(fieldName) || !validForMode(fieldName, mode)) { - ++done; - } else { - wifiCommand.setNetworkVariable(netId, fieldName, config[fieldName], function(ok) { - if (!ok) - ++errors; - if (++done == networkConfigurationFields.length) - callback(errors == 0); - }); - } - } - // If config didn't contain any of the fields we want, don't lose the error callback. - if (done == networkConfigurationFields.length) - callback(false); - } - manager.getConfiguredNetworks = function(callback) { - wifiCommand.listNetworks(function (reply) { - var networks = Object.create(null); - var lines = reply ? reply.split("\n") : 0; - if (lines.length <= 1) { - // We need to make sure we call the callback even if there are no - // configured networks. - callback(networks); - return; - } - - var done = 0; - var errors = 0; - for (var n = 1; n < lines.length; ++n) { - var result = lines[n].split("\t"); - var netId = parseInt(result[0], 10); - var config = networks[netId] = { netId: netId }; - switch (result[3]) { - case "[CURRENT]": - config.status = "CURRENT"; - break; - case "[DISABLED]": - config.status = "DISABLED"; - break; - default: - config.status = "ENABLED"; - break; - } - manager.getNetworkConfiguration(config, function (ok) { - if (!ok) - ++errors; - if (++done == lines.length - 1) { - if (errors) { - // If an error occured, delete the new netId. - wifiCommand.removeNetwork(netId, function() { - callback(null); - }); - } else { - callback(networks); - } - } - }); - } - }); - } - manager.addNetwork = function(config, callback) { - wifiCommand.addNetwork(function (netId) { - config.netId = netId; - manager.setNetworkConfiguration(config, function (ok) { - if (!ok) { - wifiCommand.removeNetwork(netId, function() { callback(false); }); - return; - } - - callback(ok); - }); - }); - } - manager.updateNetwork = function(config, callback) { - manager.setNetworkConfiguration(config, callback); - } - manager.removeNetwork = function(netId, callback) { - wifiCommand.removeNetwork(netId, callback); - } - - manager.saveConfig = function(callback) { - wifiCommand.saveConfig(callback); - } - manager.enableNetwork = function(netId, disableOthers, callback) { - if (p2pSupported) { - // We have to stop wifi direct scan before associating to an AP. - // Otherwise we will get a "REJECT" wpa supplicant event. - p2pManager.setScanEnabled(false, function(success) {}); - } - wifiCommand.enableNetwork(netId, disableOthers, callback); - } - manager.disableNetwork = function(netId, callback) { - wifiCommand.disableNetwork(netId, callback); - } - manager.getMacAddress = wifiCommand.getMacAddress; - manager.getScanResults = wifiCommand.scanResults; - manager.setScanMode = function(mode, callback) { - setScanMode(mode === "active", callback); // Use our own version. - } - manager.setBackgroundScan = setBackgroundScan; // Use our own version. - manager.scan = scan; // Use our own version. - manager.wpsPbc = wifiCommand.wpsPbc; - manager.wpsPin = wifiCommand.wpsPin; - manager.wpsCancel = wifiCommand.wpsCancel; - manager.setPowerMode = (sdkVersion >= 16) - ? wifiCommand.setPowerModeJB - : wifiCommand.setPowerModeICS; - manager.setPowerSavingMode = setPowerSavingMode; - manager.getHttpProxyNetwork = getHttpProxyNetwork; - manager.setHttpProxy = setHttpProxy; - manager.configureHttpProxy = configureHttpProxy; - manager.setSuspendOptimizations = (sdkVersion >= 16) - ? wifiCommand.setSuspendOptimizationsJB - : wifiCommand.setSuspendOptimizationsICS; - manager.setStaticIpMode = setStaticIpMode; - manager.getRssiApprox = wifiCommand.getRssiApprox; - manager.getLinkSpeed = wifiCommand.getLinkSpeed; - manager.getDhcpInfo = function() { return dhcpInfo; } - manager.getConnectionInfo = (sdkVersion >= 15) - ? wifiCommand.getConnectionInfoICS - : wifiCommand.getConnectionInfoGB; - - manager.ensureSupplicantDetached = aCallback => { - if (!manager.enabled) { - aCallback(); - return; - } - wifiCommand.closeSupplicantConnection(aCallback); - }; - - manager.isHandShakeState = function(state) { - switch (state) { - case "AUTHENTICATING": - case "ASSOCIATING": - case "ASSOCIATED": - case "FOUR_WAY_HANDSHAKE": - case "GROUP_HANDSHAKE": - return true; - case "DORMANT": - case "COMPLETED": - case "DISCONNECTED": - case "INTERFACE_DISABLED": - case "INACTIVE": - case "SCANNING": - case "UNINITIALIZED": - case "INVALID": - case "CONNECTED": - default: - return false; - } - } - - manager.isWifiEnabled = function(state) { - switch (state) { - case "UNINITIALIZED": - case "DISABLING": - return false; - default: - return true; - } - } - - manager.isWifiTetheringEnabled = function(state) { - switch (state) { - case "UNINITIALIZED": - return false; - default: - return true; - } - } - - manager.syncDebug = syncDebug; - manager.stateOrdinal = function(state) { - return supplicantStatesMap.indexOf(state); - } - manager.supplicantLoopDetection = function(prevState, state) { - var isPrevStateInHandShake = manager.isHandShakeState(prevState); - var isStateInHandShake = manager.isHandShakeState(state); - - if (isPrevStateInHandShake) { - if (isStateInHandShake) { - // Increase the count only if we are in the loop. - if (manager.stateOrdinal(state) > manager.stateOrdinal(prevState)) { - manager.loopDetectionCount++; - } - if (manager.loopDetectionCount > MAX_SUPPLICANT_LOOP_ITERATIONS) { - notify("disconnected", {connectionInfo: manager.connectionInfo}); - manager.loopDetectionCount = 0; - } - } - } else { - // From others state to HandShake state. Reset the count. - if (isStateInHandShake) { - manager.loopDetectionCount = 0; - } - } - } - - manager.handlePreWifiScan = function() { - if (p2pSupported) { - // Before doing regular wifi scan, we have to disable wifi direct - // scan first. Otherwise we will never get the scan result. - p2pManager.blockScan(); - } - }; - - manager.handlePostWifiScan = function() { - if (p2pSupported) { - // After regular wifi scanning, we should restore the restricted - // wifi direct scan. - p2pManager.unblockScan(); - } - }; - - // - // Public APIs for P2P. - // - - manager.p2pSupported = function() { - return p2pSupported; - }; - - manager.getP2pManager = function() { - return p2pManager; - }; - - manager.enableP2p = function(callback) { - p2pManager.setEnabled(true, { - onSupplicantConnected: function() { - waitForEvent(WifiP2pManager.INTERFACE_NAME); - }, - - onEnabled: function(success) { - callback(success); - } - }); - }; - - manager.getCapabilities = function() { - return capabilities; - } - - // Cert Services - let wifiCertService = Cc["@mozilla.org/wifi/certservice;1"]; - if (wifiCertService) { - wifiCertService = wifiCertService.getService(Ci.nsIWifiCertService); - wifiCertService.start(wifiListener); - } else { - debug("No wifi CA service component available"); - } - - manager.importCert = function(caInfo, callback) { - var id = idgen++; - if (callback) { - controlCallbacks[id] = callback; - } - - wifiCertService.importCert(id, caInfo.certBlob, caInfo.certPassword, - caInfo.certNickname); - } - - manager.deleteCert = function(caInfo, callback) { - var id = idgen++; - if (callback) { - controlCallbacks[id] = callback; - } - - wifiCertService.deleteCert(id, caInfo.certNickname); - } - - manager.sdkVersion = function() { - return sdkVersion; - } - - return manager; -})(); - -// Get unique key for a network, now the key is created by escape(SSID)+Security. -// So networks of same SSID but different security mode can be identified. -function getNetworkKey(network) -{ - var ssid = "", - encryption = "OPEN"; - - if ("security" in network) { - // manager network object, represents an AP - // object structure - // { - // .ssid : SSID of AP - // .security[] : "WPA-PSK" for WPA-PSK - // "WPA-EAP" for WPA-EAP - // "WEP" for WEP - // "" for OPEN - // other keys - // } - - var security = network.security; - ssid = network.ssid; - - for (let j = 0; j < security.length; j++) { - if (security[j] === "WPA-PSK") { - encryption = "WPA-PSK"; - break; - } else if (security[j] === "WPA-EAP") { - encryption = "WPA-EAP"; - break; - } else if (security[j] === "WEP") { - encryption = "WEP"; - break; - } - } - } else if ("key_mgmt" in network) { - // configure network object, represents a network - // object structure - // { - // .ssid : SSID of network, quoted - // .key_mgmt : Encryption type - // "WPA-PSK" for WPA-PSK - // "WPA-EAP" for WPA-EAP - // "NONE" for WEP/OPEN - // .auth_alg : Encryption algorithm(WEP mode only) - // "OPEN_SHARED" for WEP - // other keys - // } - var key_mgmt = network.key_mgmt, - auth_alg = network.auth_alg; - ssid = dequote(network.ssid); - - if (key_mgmt == "WPA-PSK") { - encryption = "WPA-PSK"; - } else if (key_mgmt.indexOf("WPA-EAP") != -1) { - encryption = "WPA-EAP"; - } else if (key_mgmt == "NONE" && auth_alg === "OPEN SHARED") { - encryption = "WEP"; - } - } - - // ssid here must be dequoted, and it's safer to esacpe it. - // encryption won't be empty and always be assigned one of the followings : - // "OPEN"/"WEP"/"WPA-PSK"/"WPA-EAP". - // So for a invalid network object, the returned key will be "OPEN". - return escape(ssid) + encryption; -} - -function getMode(flags) { - if (/\[IBSS/.test(flags)) - return MODE_IBSS; - - return MODE_ESS; -} - -function getKeyManagement(flags) { - var types = []; - if (!flags) - return types; - - if (/\[WPA2?-PSK/.test(flags)) - types.push("WPA-PSK"); - if (/\[WPA2?-EAP/.test(flags)) - types.push("WPA-EAP"); - if (/\[WEP/.test(flags)) - types.push("WEP"); - return types; -} - -function getCapabilities(flags) { - var types = []; - if (!flags) - return types; - - if (/\[WPS/.test(flags)) - types.push("WPS"); - return types; -} - -// These constants shamelessly ripped from WifiManager.java -// strength is the value returned by scan_results. It is nominally in dB. We -// transform it into a percentage for clients looking to simply show a -// relative indication of the strength of a network. -const MIN_RSSI = -100; -const MAX_RSSI = -55; - -function calculateSignal(strength) { - // Some wifi drivers represent their signal strengths as 8-bit integers, so - // in order to avoid negative numbers, they add 256 to the actual values. - // While we don't *know* that this is the case here, we make an educated - // guess. - if (strength > 0) - strength -= 256; - - if (strength <= MIN_RSSI) - return 0; - if (strength >= MAX_RSSI) - return 100; - return Math.floor(((strength - MIN_RSSI) / (MAX_RSSI - MIN_RSSI)) * 100); -} - -function Network(ssid, mode, frequency, security, password, capabilities) { - this.ssid = ssid; - this.mode = mode; - this.frequency = frequency; - this.security = security; - - if (typeof password !== "undefined") - this.password = password; - if (capabilities !== undefined) - this.capabilities = capabilities; - // TODO connected here as well? - - this.__exposedProps__ = Network.api; -} - -Network.api = { - ssid: "r", - mode: "r", - frequency: "r", - security: "r", - capabilities: "r", - known: "r", - - password: "rw", - keyManagement: "rw", - psk: "rw", - identity: "rw", - wep: "rw", - hidden: "rw", - eap: "rw", - pin: "rw", - phase1: "rw", - phase2: "rw", - serverCertificate: "rw", - userCertificate: "rw" -}; - -// Note: We never use ScanResult.prototype, so the fact that it's unrelated to -// Network.prototype is OK. -function ScanResult(ssid, bssid, frequency, flags, signal) { - Network.call(this, ssid, getMode(flags), frequency, - getKeyManagement(flags), undefined, getCapabilities(flags)); - this.bssid = bssid; - this.signalStrength = signal; - this.relSignalStrength = calculateSignal(Number(signal)); - - this.__exposedProps__ = ScanResult.api; -} - -// XXX This should probably live in the DOM-facing side, but it's hard to do -// there, so we stick this here. -ScanResult.api = { - bssid: "r", - signalStrength: "r", - relSignalStrength: "r", - connected: "r" -}; - -for (let i in Network.api) { - ScanResult.api[i] = Network.api[i]; -} - -function quote(s) { - return '"' + s + '"'; -} - -function dequote(s) { - if (s[0] != '"' || s[s.length - 1] != '"') - throw "Invalid argument, not a quoted string: " + s; - return s.substr(1, s.length - 2); -} - -function isWepHexKey(s) { - if (s.length != 10 && s.length != 26 && s.length != 58) - return false; - return !/[^a-fA-F0-9]/.test(s); -} - - -var WifiNetworkInterface = { - - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]), - - registered: false, - - // nsINetworkInterface - - NETWORK_STATE_UNKNOWN: Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN, - NETWORK_STATE_CONNECTING: Ci.nsINetworkInfo.CONNECTING, - NETWORK_STATE_CONNECTED: Ci.nsINetworkInfo.CONNECTED, - NETWORK_STATE_DISCONNECTING: Ci.nsINetworkInfo.DISCONNECTING, - NETWORK_STATE_DISCONNECTED: Ci.nsINetworkInfo.DISCONNECTED, - - NETWORK_TYPE_WIFI: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, - NETWORK_TYPE_MOBILE: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, - NETWORK_TYPE_MOBILE_MMS: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS, - NETWORK_TYPE_MOBILE_SUPL: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL, - - info: { - QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo]), - - state: Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN, - - type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, - - name: null, - - ips: [], - - prefixLengths: [], - - dnses: [], - - gateways: [], - - getAddresses: function (ips, prefixLengths) { - ips.value = this.ips.slice(); - prefixLengths.value = this.prefixLengths.slice(); - - return this.ips.length; - }, - - getGateways: function (count) { - if (count) { - count.value = this.gateways.length; - } - return this.gateways.slice(); - }, - - getDnses: function (count) { - if (count) { - count.value = this.dnses.length; - } - return this.dnses.slice(); - } - }, - - httpProxyHost: null, - - httpProxyPort: null -}; - -function WifiScanResult() {} - -// TODO Make the difference between a DOM-based network object and our -// networks objects much clearer. -var netToDOM; -var netFromDOM; - -function WifiWorker() { - var self = this; - - this._mm = Cc["@mozilla.org/parentprocessmessagemanager;1"] - .getService(Ci.nsIMessageListenerManager); - const messages = ["WifiManager:getNetworks", "WifiManager:getKnownNetworks", - "WifiManager:associate", "WifiManager:forget", - "WifiManager:wps", "WifiManager:getState", - "WifiManager:setPowerSavingMode", - "WifiManager:setHttpProxy", - "WifiManager:setStaticIpMode", - "WifiManager:importCert", - "WifiManager:getImportedCerts", - "WifiManager:deleteCert", - "WifiManager:setWifiEnabled", - "WifiManager:setWifiTethering", - "child-process-shutdown"]; - - messages.forEach((function(msgName) { - this._mm.addMessageListener(msgName, this); - }).bind(this)); - - Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false); - Services.obs.addObserver(this, "xpcom-shutdown", false); - - this.wantScanResults = []; - - this._needToEnableNetworks = false; - this._highestPriority = -1; - - // Networks is a map from SSID -> a scan result. - this.networks = Object.create(null); - - // ConfiguredNetworks is a map from SSID -> our view of a network. It only - // lists networks known to the wpa_supplicant. The SSID field (and other - // fields) are quoted for ease of use with WifiManager commands. - // Note that we don't have to worry about escaping embedded quotes since in - // all cases, the supplicant will take the last quotation that we pass it as - // the end of the string. - this.configuredNetworks = Object.create(null); - this._addingNetworks = Object.create(null); - - this.currentNetwork = null; - this.ipAddress = ""; - this.macAddress = null; - - this._lastConnectionInfo = null; - this._connectionInfoTimer = null; - this._reconnectOnDisconnect = false; - - // Create p2pObserver and assign to p2pManager. - if (WifiManager.p2pSupported()) { - this._p2pObserver = WifiP2pWorkerObserver(WifiManager.getP2pManager()); - WifiManager.getP2pManager().setObserver(this._p2pObserver); - - // Add DOM message observerd by p2pObserver to the message listener as well. - this._p2pObserver.getObservedDOMMessages().forEach((function(msgName) { - this._mm.addMessageListener(msgName, this); - }).bind(this)); - } - - // Users of instances of nsITimer should keep a reference to the timer until - // it is no longer needed in order to assure the timer is fired. - this._callbackTimer = null; - - // XXX On some phones (Otoro and Unagi) the wifi driver doesn't play nicely - // with the automatic scans that wpa_supplicant does (it appears that the - // driver forgets that it's returned scan results and then refuses to try to - // rescan. In order to detect this case we start a timer when we enter the - // SCANNING state and reset it whenever we either get scan results or leave - // the SCANNING state. If the timer fires, we assume that we are stuck and - // forceably try to unstick the supplican, also turning on background - // scanning to avoid having to constantly poke the supplicant. - - // How long we wait is controlled by the SCAN_STUCK_WAIT constant. - const SCAN_STUCK_WAIT = 12000; - this._scanStuckTimer = null; - this._turnOnBackgroundScan = false; - - function startScanStuckTimer() { - if (WifiManager.schedScanRecovery) { - self._scanStuckTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - self._scanStuckTimer.initWithCallback(scanIsStuck, SCAN_STUCK_WAIT, - Ci.nsITimer.TYPE_ONE_SHOT); - } - } - - function scanIsStuck() { - // Uh-oh, we've waited too long for scan results. Disconnect (which - // guarantees that we leave the SCANNING state and tells wpa_supplicant to - // wait for our next command) ensure that background scanning is on and - // then try again. - debug("Determined that scanning is stuck, turning on background scanning!"); - WifiManager.handlePostWifiScan(); - WifiManager.disconnect(function(ok) {}); - self._turnOnBackgroundScan = true; - } - - // A list of requests to turn wifi on or off. - this._stateRequests = []; - - // Given a connection status network, takes a network from - // self.configuredNetworks and prepares it for the DOM. - netToDOM = function(net) { - if (!net) { - return null; - } - var ssid = dequote(net.ssid); - var mode = net.mode; - var frequency = net.frequency; - var security = (net.key_mgmt === "NONE" && net.wep_key0) ? ["WEP"] : - (net.key_mgmt && net.key_mgmt !== "NONE") ? [net.key_mgmt.split(" ")[0]] : - []; - var password; - if (("psk" in net && net.psk) || - ("password" in net && net.password) || - ("wep_key0" in net && net.wep_key0)) { - password = "*"; - } - - var pub = new Network(ssid, mode, frequency, security, password); - if (net.identity) - pub.identity = dequote(net.identity); - if ("netId" in net) - pub.known = true; - if (net.scan_ssid === 1) - pub.hidden = true; - if ("ca_cert" in net && net.ca_cert && - net.ca_cert.indexOf("keystore://WIFI_SERVERCERT_" === 0)) { - pub.serverCertificate = net.ca_cert.substr(27); - } - if(net.subject_match) { - pub.subjectMatch = net.subject_match; - } - if ("client_cert" in net && net.client_cert && - net.client_cert.indexOf("keystore://WIFI_USERCERT_" === 0)) { - pub.userCertificate = net.client_cert.substr(25); - } - return pub; - }; - - netFromDOM = function(net, configured) { - // Takes a network from the DOM and makes it suitable for insertion into - // self.configuredNetworks (that is calling addNetwork will do the right - // thing). - // NB: Modifies net in place: safe since we don't share objects between - // the dom and the chrome code. - - // Things that are useful for the UI but not to us. - delete net.bssid; - delete net.signalStrength; - delete net.relSignalStrength; - delete net.security; - delete net.capabilities; - - if (!configured) - configured = {}; - - net.ssid = quote(net.ssid); - - let wep = false; - if ("keyManagement" in net) { - if (net.keyManagement === "WEP") { - wep = true; - net.keyManagement = "NONE"; - } else if (net.keyManagement === "WPA-EAP") { - net.keyManagement += " IEEE8021X"; - } - - configured.key_mgmt = net.key_mgmt = net.keyManagement; // WPA2-PSK, WPA-PSK, etc. - delete net.keyManagement; - } else { - configured.key_mgmt = net.key_mgmt = "NONE"; - } - - if (net.hidden) { - configured.scan_ssid = net.scan_ssid = 1; - delete net.hidden; - } - - function checkAssign(name, checkStar) { - if (name in net) { - let value = net[name]; - if (!value || (checkStar && value === '*')) { - if (name in configured) - net[name] = configured[name]; - else - delete net[name]; - } else { - configured[name] = net[name] = quote(value); - } - } - } - - checkAssign("psk", true); - checkAssign("identity", false); - checkAssign("password", true); - if (wep && net.wep && net.wep != '*') { - configured.wep_key0 = net.wep_key0 = isWepHexKey(net.wep) ? net.wep : quote(net.wep); - configured.auth_alg = net.auth_alg = "OPEN SHARED"; - } - - function hasValidProperty(name) { - return ((name in net) && net[name] != null); - } - - if (hasValidProperty("eap")) { - if (hasValidProperty("pin")) { - net.pin = quote(net.pin); - } - - if (hasValidProperty("phase1")) - net.phase1 = quote(net.phase1); - - if (hasValidProperty("phase2")) { - if (net.phase2 === "TLS") { - net.phase2 = quote("autheap=" + net.phase2); - } else { // PAP, MSCHAPV2, etc. - net.phase2 = quote("auth=" + net.phase2); - } - } - - if (hasValidProperty("serverCertificate")) - net.ca_cert = quote("keystore://WIFI_SERVERCERT_" + net.serverCertificate); - - if (hasValidProperty("subjectMatch")) - net.subject_match = quote(net.subjectMatch); - - if (hasValidProperty("userCertificate")) { - let userCertName = "WIFI_USERCERT_" + net.userCertificate; - net.client_cert = quote("keystore://" + userCertName); - - let wifiCertService = Cc["@mozilla.org/wifi/certservice;1"]. - getService(Ci.nsIWifiCertService); - if (wifiCertService.hasPrivateKey(userCertName)) { - if (WifiManager.sdkVersion() >= 19) { - // Use openssol engine instead of keystore protocol after Kitkat. - net.engine = 1; - net.engine_id = quote("keystore"); - net.key_id = quote("WIFI_USERKEY_" + net.userCertificate); - } else { - net.private_key = quote("keystore://WIFI_USERKEY_" + net.userCertificate); - } - } - } - } - - return net; - }; - - WifiManager.onsupplicantconnection = function() { - debug("Connected to supplicant"); - // Give it a state other than UNINITIALIZED, INITIALIZING or DISABLING - // defined in getter function of WifiManager.enabled. It implies that - // we are ready to accept dom request from applications. - WifiManager.state = "DISCONNECTED"; - self._reloadConfiguredNetworks(function(ok) { - // Prime this.networks. - if (!ok) - return; - - // The select network command we used in associate() disables others networks. - // Enable them here to make sure wpa_supplicant helps to connect to known - // network automatically. - self._enableAllNetworks(); - WifiManager.saveConfig(function() {}) - }); - - // Notify everybody, even if they didn't ask us to come up. - WifiManager.getMacAddress(function (mac) { - self.macAddress = mac; - debug("Got mac: " + mac); - self._fireEvent("wifiUp", { macAddress: mac }); - self.requestDone(); - }); - - if (WifiManager.state === "SCANNING") - startScanStuckTimer(); - }; - - WifiManager.onsupplicantlost = function() { - WifiManager.supplicantStarted = false; - WifiManager.state = "UNINITIALIZED"; - debug("Supplicant died!"); - - // Notify everybody, even if they didn't ask us to come up. - self._fireEvent("wifiDown", {}); - self.requestDone(); - }; - - WifiManager.onpasswordmaybeincorrect = function() { - WifiManager.authenticationFailuresCount++; - }; - - WifiManager.ondisconnected = function() { - // We may fail to establish the connection, re-enable the - // rest of our networks. - if (self._needToEnableNetworks) { - self._enableAllNetworks(); - self._needToEnableNetworks = false; - } - - let connectionInfo = this.connectionInfo; - WifiManager.getNetworkId(connectionInfo.ssid, function(netId) { - // Trying to get netId from current network. - if (!netId && - self.currentNetwork && self.currentNetwork.ssid && - dequote(self.currentNetwork.ssid) == connectionInfo.ssid && - typeof self.currentNetwork.netId !== "undefined") { - netId = self.currentNetwork.netId; - } - if (netId) { - WifiManager.disableNetwork(netId, function() {}); - } - }); - self._fireEvent("onconnectingfailed", {network: netToDOM(self.currentNetwork)}); - } - - WifiManager.onstatechange = function() { - debug("State change: " + this.prevState + " -> " + this.state); - - if (self._connectionInfoTimer && - this.state !== "CONNECTED" && - this.state !== "COMPLETED") { - self._stopConnectionInfoTimer(); - } - - if (this.state !== "SCANNING" && - self._scanStuckTimer) { - self._scanStuckTimer.cancel(); - self._scanStuckTimer = null; - } - - switch (this.state) { - case "DORMANT": - // The dormant state is a bad state to be in since we won't - // automatically connect. Try to knock us out of it. We only - // hit this state when we've failed to run DHCP, so trying - // again isn't the worst thing we can do. Eventually, we'll - // need to detect if we're looping in this state and bail out. - WifiManager.reconnect(function(){}); - break; - case "ASSOCIATING": - // id has not yet been filled in, so we can only report the ssid and - // bssid. mode and frequency are simply made up. - self.currentNetwork = - { bssid: WifiManager.connectionInfo.bssid, - ssid: quote(WifiManager.connectionInfo.ssid), - mode: MODE_ESS, - frequency: 0}; - WifiManager.getNetworkConfiguration(self.currentNetwork, function (){ - // Notify again because we get complete network information. - self._fireEvent("onconnecting", { network: netToDOM(self.currentNetwork) }); - }); - break; - case "ASSOCIATED": - // set to full power mode when ready to do 4 way handsharke. - WifiManager.setPowerSavingMode(false); - if (!self.currentNetwork) { - self.currentNetwork = - { bssid: WifiManager.connectionInfo.bssid, - ssid: quote(WifiManager.connectionInfo.ssid) }; - } - self.currentNetwork.netId = this.id; - WifiManager.getNetworkConfiguration(self.currentNetwork, function (){ - // Notify again because we get complete network information. - self._fireEvent("onconnecting", { network: netToDOM(self.currentNetwork) }); - }); - break; - case "COMPLETED": - // Now that we've successfully completed the connection, re-enable the - // rest of our networks. - // XXX Need to do this eventually if the user entered an incorrect - // password. For now, we require user interaction to break the loop and - // select a better network! - if (self._needToEnableNetworks) { - self._enableAllNetworks(); - self._needToEnableNetworks = false; - } - - var _oncompleted = function() { - // The full authentication process is completed, reset the count. - WifiManager.authenticationFailuresCount = 0; - WifiManager.loopDetectionCount = 0; - self._startConnectionInfoTimer(); - self._fireEvent("onassociate", { network: netToDOM(self.currentNetwork) }); - }; - - // We get the ASSOCIATED event when we've associated but not connected, so - // wait until the handshake is complete. - if (this.fromStatus || !self.currentNetwork) { - // In this case, we connected to an already-connected wpa_supplicant, - // because of that we need to gather information about the current - // network here. - self.currentNetwork = { bssid: WifiManager.connectionInfo.bssid, - ssid: quote(WifiManager.connectionInfo.ssid), - netId: WifiManager.connectionInfo.id }; - WifiManager.getNetworkConfiguration(self.currentNetwork, _oncompleted); - } else { - _oncompleted(); - } - break; - case "CONNECTED": - // wifi connection complete, turn on the power saving mode. - WifiManager.setPowerSavingMode(true); - // BSSID is read after connected, update it. - self.currentNetwork.bssid = WifiManager.connectionInfo.bssid; - break; - case "DISCONNECTED": - // wpa_supplicant may give us a "DISCONNECTED" event even if - // we are already in "DISCONNECTED" state. - if ((WifiNetworkInterface.info.state === - Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED) && - (this.prevState === "INITIALIZING" || - this.prevState === "DISCONNECTED" || - this.prevState === "INTERFACE_DISABLED" || - this.prevState === "INACTIVE" || - this.prevState === "UNINITIALIZED")) { - // When in disconnected mode, need to turn on wifi power saving mode. - WifiManager.setPowerSavingMode(true); - return; - } - - self._fireEvent("ondisconnect", {network: netToDOM(self.currentNetwork)}); - - self.currentNetwork = null; - self.ipAddress = ""; - - if (self._turnOnBackgroundScan) { - self._turnOnBackgroundScan = false; - WifiManager.setBackgroundScan("ON", function(did_something, ok) { - WifiManager.reassociate(function() {}); - }); - } - - WifiManager.connectionDropped(function() { - // We've disconnected from a network because of a call to forgetNetwork. - // Reconnect to the next available network (if any). - if (self._reconnectOnDisconnect) { - self._reconnectOnDisconnect = false; - WifiManager.reconnect(function(){}); - } - }); - - WifiNetworkInterface.info.state = - Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; - - // Update network infterface first then clear properties. - gNetworkManager.updateNetworkInterface(WifiNetworkInterface); - WifiNetworkInterface.info.ips = []; - WifiNetworkInterface.info.prefixLengths = []; - WifiNetworkInterface.info.gateways = []; - WifiNetworkInterface.info.dnses = []; - - - break; - case "WPS_TIMEOUT": - self._fireEvent("onwpstimeout", {}); - break; - case "WPS_FAIL": - self._fireEvent("onwpsfail", {}); - break; - case "WPS_OVERLAP_DETECTED": - self._fireEvent("onwpsoverlap", {}); - break; - case "AUTHENTICATING": - self._fireEvent("onauthenticating", {network: netToDOM(self.currentNetwork)}); - break; - case "SCANNING": - // If we're already scanning in the background, we don't need to worry - // about getting stuck while scanning. - if (!WifiManager.backgroundScanEnabled && WifiManager.enabled) - startScanStuckTimer(); - break; - } - }; - - WifiManager.onnetworkconnected = function() { - if (!this.info || !this.info.ipaddr_str) { - debug("Network information is invalid."); - return; - } - - let maskLength = - netHelpers.getMaskLength(netHelpers.stringToIP(this.info.mask_str)); - if (!maskLength) { - maskLength = 32; // max prefix for IPv4. - } - - let netConnect = WifiManager.getHttpProxyNetwork(self.currentNetwork); - if (netConnect) { - WifiNetworkInterface.httpProxyHost = netConnect.httpProxyHost; - WifiNetworkInterface.httpProxyPort = netConnect.httpProxyPort; - } - - WifiNetworkInterface.info.state = - Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED; - WifiNetworkInterface.info.ips = [this.info.ipaddr_str]; - WifiNetworkInterface.info.prefixLengths = [maskLength]; - WifiNetworkInterface.info.gateways = [this.info.gateway_str]; - if (typeof this.info.dns1_str == "string" && - this.info.dns1_str.length) { - WifiNetworkInterface.info.dnses.push(this.info.dns1_str); - } - if (typeof this.info.dns2_str == "string" && - this.info.dns2_str.length) { - WifiNetworkInterface.info.dnses.push(this.info.dns2_str); - } - gNetworkManager.updateNetworkInterface(WifiNetworkInterface); - - self.ipAddress = this.info.ipaddr_str; - - // We start the connection information timer when we associate, but - // don't have our IP address until here. Make sure that we fire a new - // connectionInformation event with the IP address the next time the - // timer fires. - self._lastConnectionInfo = null; - self._fireEvent("onconnect", { network: netToDOM(self.currentNetwork) }); - }; - - WifiManager.onscanresultsavailable = function() { - if (self._scanStuckTimer) { - // We got scan results! We must not be stuck for now, try again. - self._scanStuckTimer.cancel(); - self._scanStuckTimer.initWithCallback(scanIsStuck, SCAN_STUCK_WAIT, - Ci.nsITimer.TYPE_ONE_SHOT); - } - - if (self.wantScanResults.length === 0) { - debug("Scan results available, but we don't need them"); - return; - } - - debug("Scan results are available! Asking for them."); - WifiManager.getScanResults(function(r) { - // Failure. - if (!r) { - self.wantScanResults.forEach(function(callback) { callback(null) }); - self.wantScanResults = []; - return; - } - - let capabilities = WifiManager.getCapabilities(); - - // Now that we have scan results, there's no more need to continue - // scanning. Ignore any errors from this command. - WifiManager.setScanMode("inactive", function() {}); - let lines = r.split("\n"); - // NB: Skip the header line. - self.networksArray = []; - for (let i = 1; i < lines.length; ++i) { - // bssid / frequency / signal level / flags / ssid - var match = /([\S]+)\s+([\S]+)\s+([\S]+)\s+(\[[\S]+\])?\s(.*)/.exec(lines[i]); - - if (match && match[5]) { - let ssid = match[5], - bssid = match[1], - frequency = match[2], - signalLevel = match[3], - flags = match[4]; - - /* Skip networks with unknown or unsupported modes. */ - if (capabilities.mode.indexOf(getMode(flags)) == -1) - continue; - - // If this is the first time that we've seen this SSID in the scan - // results, add it to the list along with any other information. - // Also, we use the highest signal strength that we see. - let network = new ScanResult(ssid, bssid, frequency, flags, signalLevel); - - let networkKey = getNetworkKey(network); - let eapIndex = -1; - if (networkKey in self.configuredNetworks) { - let known = self.configuredNetworks[networkKey]; - network.known = true; - - if ("identity" in known && known.identity) - network.identity = dequote(known.identity); - - // Note: we don't hand out passwords here! The * marks that there - // is a password that we're hiding. - if (("psk" in known && known.psk) || - ("password" in known && known.password) || - ("wep_key0" in known && known.wep_key0)) { - network.password = "*"; - } - } - - self.networksArray.push(network); - if (network.bssid === WifiManager.connectionInfo.bssid) - network.connected = true; - - let signal = calculateSignal(Number(match[3])); - if (signal > network.relSignalStrength) - network.relSignalStrength = signal; - } else if (!match) { - debug("Match didn't find anything for: " + lines[i]); - } - } - - self.wantScanResults.forEach(function(callback) { callback(self.networksArray) }); - self.wantScanResults = []; - }); - }; - - WifiManager.onstationinfoupdate = function() { - self._fireEvent("stationinfoupdate", { station: this.station }); - }; - - WifiManager.onstopconnectioninfotimer = function() { - self._stopConnectionInfoTimer(); - }; - - // Read the 'wifi.enabled' setting in order to start with a known - // value at boot time. The handle() will be called after reading. - // - // nsISettingsServiceCallback implementation. - var initWifiEnabledCb = { - handle: function handle(aName, aResult) { - if (aName !== SETTINGS_WIFI_ENABLED) - return; - if (aResult === null) - aResult = true; - self.handleWifiEnabled(aResult); - }, - handleError: function handleError(aErrorMessage) { - debug("Error reading the 'wifi.enabled' setting. Default to wifi on."); - self.handleWifiEnabled(true); - } - }; - - var initWifiDebuggingEnabledCb = { - handle: function handle(aName, aResult) { - if (aName !== SETTINGS_WIFI_DEBUG_ENABLED) - return; - if (aResult === null) - aResult = false; - DEBUG = aResult; - updateDebug(); - }, - handleError: function handleError(aErrorMessage) { - debug("Error reading the 'wifi.debugging.enabled' setting. Default to debugging off."); - DEBUG = false; - updateDebug(); - } - }; - - this.initTetheringSettings(); - - let lock = gSettingsService.createLock(); - lock.get(SETTINGS_WIFI_ENABLED, initWifiEnabledCb); - lock.get(SETTINGS_WIFI_DEBUG_ENABLED, initWifiDebuggingEnabledCb); - - lock.get(SETTINGS_WIFI_SSID, this); - lock.get(SETTINGS_WIFI_SECURITY_TYPE, this); - lock.get(SETTINGS_WIFI_SECURITY_PASSWORD, this); - lock.get(SETTINGS_WIFI_IP, this); - lock.get(SETTINGS_WIFI_PREFIX, this); - lock.get(SETTINGS_WIFI_DHCPSERVER_STARTIP, this); - lock.get(SETTINGS_WIFI_DHCPSERVER_ENDIP, this); - lock.get(SETTINGS_WIFI_DNS1, this); - lock.get(SETTINGS_WIFI_DNS2, this); - lock.get(SETTINGS_WIFI_TETHERING_ENABLED, this); - - lock.get(SETTINGS_USB_DHCPSERVER_STARTIP, this); - lock.get(SETTINGS_USB_DHCPSERVER_ENDIP, this); - - this._wifiTetheringSettingsToRead = [SETTINGS_WIFI_SSID, - SETTINGS_WIFI_SECURITY_TYPE, - SETTINGS_WIFI_SECURITY_PASSWORD, - SETTINGS_WIFI_IP, - SETTINGS_WIFI_PREFIX, - SETTINGS_WIFI_DHCPSERVER_STARTIP, - SETTINGS_WIFI_DHCPSERVER_ENDIP, - SETTINGS_WIFI_DNS1, - SETTINGS_WIFI_DNS2, - SETTINGS_WIFI_TETHERING_ENABLED, - SETTINGS_USB_DHCPSERVER_STARTIP, - SETTINGS_USB_DHCPSERVER_ENDIP]; -} - -function translateState(state) { - switch (state) { - case "INTERFACE_DISABLED": - case "INACTIVE": - case "SCANNING": - case "DISCONNECTED": - default: - return "disconnected"; - - case "AUTHENTICATING": - case "ASSOCIATING": - case "ASSOCIATED": - case "FOUR_WAY_HANDSHAKE": - case "GROUP_HANDSHAKE": - return "connecting"; - - case "COMPLETED": - return WifiManager.getDhcpInfo() ? "connected" : "associated"; - } -} - -WifiWorker.prototype = { - classID: WIFIWORKER_CID, - classInfo: XPCOMUtils.generateCI({classID: WIFIWORKER_CID, - contractID: WIFIWORKER_CONTRACTID, - classDescription: "WifiWorker", - interfaces: [Ci.nsIWorkerHolder, - Ci.nsIWifi, - Ci.nsIObserver]}), - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIWorkerHolder, - Ci.nsIWifi, - Ci.nsIObserver, - Ci.nsISettingsServiceCallback]), - - disconnectedByWifi: false, - - disconnectedByWifiTethering: false, - - _wifiTetheringSettingsToRead: [], - - _oldWifiTetheringEnabledState: null, - - tetheringSettings: {}, - - initTetheringSettings: function initTetheringSettings() { - this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = null; - this.tetheringSettings[SETTINGS_WIFI_SSID] = DEFAULT_WIFI_SSID; - this.tetheringSettings[SETTINGS_WIFI_SECURITY_TYPE] = DEFAULT_WIFI_SECURITY_TYPE; - this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD] = DEFAULT_WIFI_SECURITY_PASSWORD; - this.tetheringSettings[SETTINGS_WIFI_IP] = DEFAULT_WIFI_IP; - this.tetheringSettings[SETTINGS_WIFI_PREFIX] = DEFAULT_WIFI_PREFIX; - this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP] = DEFAULT_WIFI_DHCPSERVER_STARTIP; - this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP; - this.tetheringSettings[SETTINGS_WIFI_DNS1] = DEFAULT_DNS1; - this.tetheringSettings[SETTINGS_WIFI_DNS2] = DEFAULT_DNS2; - - this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP] = DEFAULT_USB_DHCPSERVER_STARTIP; - this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP] = DEFAULT_USB_DHCPSERVER_ENDIP; - }, - - // Internal methods. - waitForScan: function(callback) { - this.wantScanResults.push(callback); - }, - - // In order to select a specific network, we disable the rest of the - // networks known to us. However, in general, we want the supplicant to - // connect to which ever network it thinks is best, so when we select the - // proper network (or fail to), we need to re-enable the rest. - _enableAllNetworks: function() { - for (let key in this.configuredNetworks) { - let net = this.configuredNetworks[key]; - WifiManager.enableNetwork(net.netId, false, function(ok) { - net.disabled = ok ? 1 : 0; - }); - } - }, - - _startConnectionInfoTimer: function() { - if (this._connectionInfoTimer) - return; - - var self = this; - function getConnectionInformation() { - WifiManager.getConnectionInfo(function(connInfo) { - // See comments in calculateSignal for information about this. - if (!connInfo) { - self._lastConnectionInfo = null; - return; - } - - let { rssi, linkspeed } = connInfo; - if (rssi > 0) - rssi -= 256; - if (rssi <= MIN_RSSI) - rssi = MIN_RSSI; - else if (rssi >= MAX_RSSI) - rssi = MAX_RSSI; - - let info = { signalStrength: rssi, - relSignalStrength: calculateSignal(rssi), - linkSpeed: linkspeed, - ipAddress: self.ipAddress }; - let last = self._lastConnectionInfo; - - // Only fire the event if the link speed changed or the signal - // strength changed by more than 10%. - function tensPlace(percent) { - return (percent / 10) | 0; - } - - if (last && last.linkSpeed === info.linkSpeed && - last.ipAddress === info.ipAddress && - tensPlace(last.relSignalStrength) === tensPlace(info.relSignalStrength)) { - return; - } - - self._lastConnectionInfo = info; - debug("Firing connectioninfoupdate: " + uneval(info)); - self._fireEvent("connectioninfoupdate", info); - }); - } - - // Prime our _lastConnectionInfo immediately and fire the event at the - // same time. - getConnectionInformation(); - - // Now, set up the timer for regular updates. - this._connectionInfoTimer = - Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - this._connectionInfoTimer.init(getConnectionInformation, 5000, - Ci.nsITimer.TYPE_REPEATING_SLACK); - }, - - _stopConnectionInfoTimer: function() { - if (!this._connectionInfoTimer) - return; - - this._connectionInfoTimer.cancel(); - this._connectionInfoTimer = null; - this._lastConnectionInfo = null; - }, - - _reloadConfiguredNetworks: function(callback) { - WifiManager.getConfiguredNetworks((function(networks) { - if (!networks) { - debug("Unable to get configured networks"); - callback(false); - return; - } - - this._highestPriority = -1; - - // Convert between netId-based and ssid-based indexing. - for (let net in networks) { - let network = networks[net]; - delete networks[net]; - - if (!network.ssid) { - WifiManager.removeNetwork(network.netId, function() {}); - continue; - } - - if (network.hasOwnProperty("priority") && - network.priority > this._highestPriority) { - this._highestPriority = network.priority; - } - - let networkKey = getNetworkKey(network); - // Accept latest config of same network(same SSID and same security). - if (networks[networkKey]) { - WifiManager.removeNetwork(networks[networkKey].netId, function() {}); - } - networks[networkKey] = network; - } - - this.configuredNetworks = networks; - callback(true); - }).bind(this)); - }, - - // Important side effect: calls WifiManager.saveConfig. - _reprioritizeNetworks: function(callback) { - // First, sort the networks in orer of their priority. - var ordered = Object.getOwnPropertyNames(this.configuredNetworks); - let self = this; - ordered.sort(function(a, b) { - var neta = self.configuredNetworks[a], - netb = self.configuredNetworks[b]; - - // Sort unsorted networks to the end of the list. - if (isNaN(neta.priority)) - return isNaN(netb.priority) ? 0 : 1; - if (isNaN(netb.priority)) - return -1; - return netb.priority - neta.priority; - }); - - // Skip unsorted networks. - let newPriority = 0, i; - for (i = ordered.length - 1; i >= 0; --i) { - if (!isNaN(this.configuredNetworks[ordered[i]].priority)) - break; - } - - // No networks we care about? - if (i < 0) { - WifiManager.saveConfig(callback); - return; - } - - // Now assign priorities from 0 to length, starting with the smallest - // priority and heading towards the highest (note the dependency between - // total and i here). - let done = 0, errors = 0, total = i + 1; - for (; i >= 0; --i) { - let network = this.configuredNetworks[ordered[i]]; - network.priority = newPriority++; - - // Note: networkUpdated declared below since it happens logically after - // this loop. - WifiManager.updateNetwork(network, networkUpdated); - } - - function networkUpdated(ok) { - if (!ok) - ++errors; - if (++done === total) { - if (errors > 0) { - callback(false); - return; - } - - WifiManager.saveConfig(function(ok) { - if (!ok) { - callback(false); - return; - } - - self._reloadConfiguredNetworks(function(ok) { - callback(ok); - }); - }); - } - } - }, - - // nsIWifi - - _domManagers: [], - _fireEvent: function(message, data) { - this._domManagers.forEach(function(manager) { - // Note: We should never have a dead message manager here because we - // observe our child message managers shutting down, below. - manager.sendAsyncMessage("WifiManager:" + message, data); - }); - }, - - _sendMessage: function(message, success, data, msg) { - try { - msg.manager.sendAsyncMessage(message + (success ? ":OK" : ":NO"), - { data: data, rid: msg.rid, mid: msg.mid }); - } catch (e) { - debug("sendAsyncMessage error : " + e); - } - this._splicePendingRequest(msg); - }, - - _domRequest: [], - - _splicePendingRequest: function(msg) { - for (let i = 0; i < this._domRequest.length; i++) { - if (this._domRequest[i].msg === msg) { - this._domRequest.splice(i, 1); - return; - } - } - }, - - _clearPendingRequest: function() { - if (this._domRequest.length === 0) return; - this._domRequest.forEach((function(req) { - this._sendMessage(req.name + ":Return", false, "Wifi is disabled", req.msg); - }).bind(this)); - }, - - receiveMessage: function MessageManager_receiveMessage(aMessage) { - let msg = aMessage.data || {}; - msg.manager = aMessage.target; - - if (WifiManager.p2pSupported()) { - // If p2pObserver returns something truthy, return it! - // Otherwise, continue to do the rest of tasks. - var p2pRet = this._p2pObserver.onDOMMessage(aMessage); - if (p2pRet) { - return p2pRet; - } - } - - // Note: By the time we receive child-process-shutdown, the child process - // has already forgotten its permissions so we do this before the - // permissions check. - if (aMessage.name === "child-process-shutdown") { - let i; - if ((i = this._domManagers.indexOf(msg.manager)) != -1) { - this._domManagers.splice(i, 1); - } - for (i = this._domRequest.length - 1; i >= 0; i--) { - if (this._domRequest[i].msg.manager === msg.manager) { - this._domRequest.splice(i, 1); - } - } - return; - } - - if (!aMessage.target.assertPermission("wifi-manage")) { - return; - } - - // We are interested in DOMRequests only. - if (aMessage.name != "WifiManager:getState") { - this._domRequest.push({name: aMessage.name, msg:msg}); - } - - switch (aMessage.name) { - case "WifiManager:setWifiEnabled": - this.setWifiEnabled(msg); - break; - case "WifiManager:getNetworks": - this.getNetworks(msg); - break; - case "WifiManager:getKnownNetworks": - this.getKnownNetworks(msg); - break; - case "WifiManager:associate": - this.associate(msg); - break; - case "WifiManager:forget": - this.forget(msg); - break; - case "WifiManager:wps": - this.wps(msg); - break; - case "WifiManager:setPowerSavingMode": - this.setPowerSavingMode(msg); - break; - case "WifiManager:setHttpProxy": - this.setHttpProxy(msg); - break; - case "WifiManager:setStaticIpMode": - this.setStaticIpMode(msg); - break; - case "WifiManager:importCert": - this.importCert(msg); - break; - case "WifiManager:getImportedCerts": - this.getImportedCerts(msg); - break; - case "WifiManager:deleteCert": - this.deleteCert(msg); - break; - case "WifiManager:setWifiTethering": - this.setWifiTethering(msg); - break; - case "WifiManager:getState": { - let i; - if ((i = this._domManagers.indexOf(msg.manager)) === -1) { - this._domManagers.push(msg.manager); - } - - let net = this.currentNetwork ? netToDOM(this.currentNetwork) : null; - return { network: net, - connectionInfo: this._lastConnectionInfo, - enabled: WifiManager.enabled, - status: translateState(WifiManager.state), - macAddress: this.macAddress, - capabilities: WifiManager.getCapabilities()}; - } - } - }, - - getNetworks: function(msg) { - const message = "WifiManager:getNetworks:Return"; - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - let sent = false; - let callback = (function (networks) { - if (sent) - return; - sent = true; - this._sendMessage(message, networks !== null, networks, msg); - }).bind(this); - this.waitForScan(callback); - - WifiManager.scan(true, (function(ok) { - // If the scan command succeeded, we're done. - if (ok) - return; - - // Avoid sending multiple responses. - if (sent) - return; - - // Otherwise, let the client know that it failed, it's responsible for - // trying again in a few seconds. - sent = true; - this._sendMessage(message, false, "ScanFailed", msg); - }).bind(this)); - }, - - getWifiScanResults: function(callback) { - var count = 0; - var timer = null; - var self = this; - - if (!WifiManager.enabled) { - callback.onfailure(); - return; - } - - self.waitForScan(waitForScanCallback); - doScan(); - function doScan() { - WifiManager.scan(true, (function (ok) { - if (!ok) { - if (!timer) { - count = 0; - timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - } - - if (count++ >= 3) { - timer = null; - self.wantScanResults.splice(self.wantScanResults.indexOf(waitForScanCallback), 1); - callback.onfailure(); - return; - } - - // Else it's still running, continue waiting. - timer.initWithCallback(doScan, 10000, Ci.nsITimer.TYPE_ONE_SHOT); - return; - } - }).bind(this)); - } - - function waitForScanCallback(networks) { - if (networks === null) { - callback.onfailure(); - return; - } - - var wifiScanResults = new Array(); - var net; - for (let net in networks) { - let value = networks[net]; - wifiScanResults.push(transformResult(value)); - } - callback.onready(wifiScanResults.length, wifiScanResults); - } - - function transformResult(element) { - var result = new WifiScanResult(); - result.connected = false; - for (let id in element) { - if (id === "__exposedProps__") { - continue; - } - if (id === "security") { - result[id] = 0; - var security = element[id]; - for (let j = 0; j < security.length; j++) { - if (security[j] === "WPA-PSK") { - result[id] |= Ci.nsIWifiScanResult.WPA_PSK; - } else if (security[j] === "WPA-EAP") { - result[id] |= Ci.nsIWifiScanResult.WPA_EAP; - } else if (security[j] === "WEP") { - result[id] |= Ci.nsIWifiScanResult.WEP; - } else { - result[id] = 0; - } - } - } else { - result[id] = element[id]; - } - } - return result; - } - }, - - getKnownNetworks: function(msg) { - const message = "WifiManager:getKnownNetworks:Return"; - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - this._reloadConfiguredNetworks((function(ok) { - if (!ok) { - this._sendMessage(message, false, "Failed", msg); - return; - } - - var networks = []; - for (let networkKey in this.configuredNetworks) { - networks.push(netToDOM(this.configuredNetworks[networkKey])); - } - - this._sendMessage(message, true, networks, msg); - }).bind(this)); - }, - - _setWifiEnabledCallback: function(status) { - if (status !== 0) { - this.requestDone(); - return; - } - - // If we're enabling ourselves, then wait until we've connected to the - // supplicant to notify. If we're disabling, we take care of this in - // supplicantlost. - if (WifiManager.supplicantStarted) - WifiManager.start(); - }, - - /** - * Compatibility flags for detecting if Gaia is controlling wifi by settings - * or API, once API is called, gecko will no longer accept wifi enable - * control from settings. - * This is used to deal with compatibility issue while Gaia adopted to use - * API but gecko doesn't remove the settings code in time. - * TODO: Remove this flag in Bug 1050147 - */ - ignoreWifiEnabledFromSettings: false, - setWifiEnabled: function(msg) { - const message = "WifiManager:setWifiEnabled:Return"; - let self = this; - let enabled = msg.data; - - self.ignoreWifiEnabledFromSettings = true; - // No change. - if (enabled === WifiManager.enabled) { - this._sendMessage(message, true, true, msg); - return; - } - - // Can't enable wifi while hotspot mode is enabled. - if (enabled && (this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] || - WifiManager.isWifiTetheringEnabled(WifiManager.tetheringState))) { - self._sendMessage(message, false, "Can't enable Wifi while hotspot mode is enabled", msg); - return; - } - - WifiManager.setWifiEnabled(enabled, function(ok) { - if (ok === 0 || ok === "no change") { - self._sendMessage(message, true, true, msg); - - // Reply error to pending requests. - if (!enabled) { - self._clearPendingRequest(); - } else { - WifiManager.start(); - } - } else { - self._sendMessage(message, false, "Set wifi enabled failed", msg); - } - }); - }, - - _setWifiEnabled: function(enabled, callback) { - // Reply error to pending requests. - if (!enabled) { - this._clearPendingRequest(); - } - - WifiManager.setWifiEnabled(enabled, callback); - }, - - // requestDone() must be called to before callback complete(or error) - // so next queue in the request quene can be executed. - // TODO: Remove command queue in Bug 1050147 - queueRequest: function(data, callback) { - if (!callback) { - throw "Try to enqueue a request without callback"; - } - - let optimizeCommandList = ["setWifiEnabled", "setWifiApEnabled"]; - if (optimizeCommandList.indexOf(data.command) != -1) { - this._stateRequests = this._stateRequests.filter(function(element) { - return element.data.command !== data.command; - }); - } - - this._stateRequests.push({ - data: data, - callback: callback - }); - - this.nextRequest(); - }, - - getWifiTetheringParameters: function getWifiTetheringParameters(enable) { - if (this.useTetheringAPI) { - return this.getWifiTetheringConfiguration(enable); - } else { - return this.getWifiTetheringParametersBySetting(enable); - } - }, - - getWifiTetheringConfiguration: function getWifiTetheringConfiguration(enable) { - let config = {}; - let params = this.tetheringConfig; - - let check = function(field, _default) { - config[field] = field in params ? params[field] : _default; - }; - - check("ssid", DEFAULT_WIFI_SSID); - check("security", DEFAULT_WIFI_SECURITY_TYPE); - check("key", DEFAULT_WIFI_SECURITY_PASSWORD); - check("ip", DEFAULT_WIFI_IP); - check("prefix", DEFAULT_WIFI_PREFIX); - check("wifiStartIp", DEFAULT_WIFI_DHCPSERVER_STARTIP); - check("wifiEndIp", DEFAULT_WIFI_DHCPSERVER_ENDIP); - check("usbStartIp", DEFAULT_USB_DHCPSERVER_STARTIP); - check("usbEndIp", DEFAULT_USB_DHCPSERVER_ENDIP); - check("dns1", DEFAULT_DNS1); - check("dns2", DEFAULT_DNS2); - - config.enable = enable; - config.mode = enable ? WIFI_FIRMWARE_AP : WIFI_FIRMWARE_STATION; - config.link = enable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN; - - // Check the format to prevent netd from crash. - if (enable && (!config.ssid || config.ssid == "")) { - debug("Invalid SSID value."); - return null; - } - - if (enable && (config.security != WIFI_SECURITY_TYPE_NONE && !config.key)) { - debug("Invalid security password."); - return null; - } - - // Using the default values here until application supports these settings. - if (config.ip == "" || config.prefix == "" || - config.wifiStartIp == "" || config.wifiEndIp == "" || - config.usbStartIp == "" || config.usbEndIp == "") { - debug("Invalid subnet information."); - return null; - } - - return config; - }, - - getWifiTetheringParametersBySetting: function getWifiTetheringParametersBySetting(enable) { - let ssid; - let securityType; - let securityId; - let interfaceIp; - let prefix; - let wifiDhcpStartIp; - let wifiDhcpEndIp; - let usbDhcpStartIp; - let usbDhcpEndIp; - let dns1; - let dns2; - - ssid = this.tetheringSettings[SETTINGS_WIFI_SSID]; - securityType = this.tetheringSettings[SETTINGS_WIFI_SECURITY_TYPE]; - securityId = this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD]; - interfaceIp = this.tetheringSettings[SETTINGS_WIFI_IP]; - prefix = this.tetheringSettings[SETTINGS_WIFI_PREFIX]; - wifiDhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP]; - wifiDhcpEndIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP]; - usbDhcpStartIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP]; - usbDhcpEndIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP]; - dns1 = this.tetheringSettings[SETTINGS_WIFI_DNS1]; - dns2 = this.tetheringSettings[SETTINGS_WIFI_DNS2]; - - // Check the format to prevent netd from crash. - if (!ssid || ssid == "") { - debug("Invalid SSID value."); - return null; - } - // Truncate ssid if its length of encoded to utf8 is longer than 32. - while (unescape(encodeURIComponent(ssid)).length > 32) - { - ssid = ssid.substring(0, ssid.length-1); - } - - if (securityType != WIFI_SECURITY_TYPE_NONE && - securityType != WIFI_SECURITY_TYPE_WPA_PSK && - securityType != WIFI_SECURITY_TYPE_WPA2_PSK) { - - debug("Invalid security type."); - return null; - } - if (securityType != WIFI_SECURITY_TYPE_NONE && !securityId) { - debug("Invalid security password."); - return null; - } - // Using the default values here until application supports these settings. - if (interfaceIp == "" || prefix == "" || - wifiDhcpStartIp == "" || wifiDhcpEndIp == "" || - usbDhcpStartIp == "" || usbDhcpEndIp == "") { - debug("Invalid subnet information."); - return null; - } - - return { - ssid: ssid, - security: securityType, - key: securityId, - ip: interfaceIp, - prefix: prefix, - wifiStartIp: wifiDhcpStartIp, - wifiEndIp: wifiDhcpEndIp, - usbStartIp: usbDhcpStartIp, - usbEndIp: usbDhcpEndIp, - dns1: dns1, - dns2: dns2, - enable: enable, - mode: enable ? WIFI_FIRMWARE_AP : WIFI_FIRMWARE_STATION, - link: enable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN - }; - }, - - setWifiApEnabled: function(enabled, callback) { - let configuration = this.getWifiTetheringParameters(enabled); - - if (!configuration) { - this.requestDone(); - debug("Invalid Wifi Tethering configuration."); - return; - } - - WifiManager.setWifiApEnabled(enabled, configuration, callback); - }, - - associate: function(msg) { - const MAX_PRIORITY = 9999; - const message = "WifiManager:associate:Return"; - let network = msg.data; - - let privnet = network; - let dontConnect = privnet.dontConnect; - delete privnet.dontConnect; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - let self = this; - function networkReady() { - // saveConfig now before we disable most of the other networks. - function selectAndConnect() { - WifiManager.enableNetwork(privnet.netId, true, function (ok) { - if (ok) - self._needToEnableNetworks = true; - if (WifiManager.state === "DISCONNECTED" || - WifiManager.state === "SCANNING") { - WifiManager.reconnect(function (ok) { - self._sendMessage(message, ok, ok, msg); - }); - } else { - self._sendMessage(message, ok, ok, msg); - } - }); - } - - var selectAndConnectOrReturn = dontConnect ? - function() { - self._sendMessage(message, true, "Wifi has been recorded", msg); - } : selectAndConnect; - if (self._highestPriority >= MAX_PRIORITY) { - self._reprioritizeNetworks(selectAndConnectOrReturn); - } else { - WifiManager.saveConfig(selectAndConnectOrReturn); - } - } - - function connectToNetwork() { - WifiManager.updateNetwork(privnet, (function(ok) { - if (!ok) { - self._sendMessage(message, false, "Network is misconfigured", msg); - return; - } - - networkReady(); - })); - } - - let ssid = privnet.ssid; - let networkKey = getNetworkKey(privnet); - let configured; - - if (networkKey in this._addingNetworks) { - this._sendMessage(message, false, "Racing associates"); - return; - } - - if (networkKey in this.configuredNetworks) - configured = this.configuredNetworks[networkKey]; - - netFromDOM(privnet, configured); - - privnet.priority = ++this._highestPriority; - if (configured) { - privnet.netId = configured.netId; - // Sync priority back to configured so if priority reaches MAX_PRIORITY, - // it can be sorted correctly in _reprioritizeNetworks() because the - // function sort network based on priority in configure list. - configured.priority = privnet.priority; - - // When investigating Bug 1123680, we observed that gaia may unexpectedly - // request to associate with incorrect password before successfully - // forgetting the network. It would cause the network unable to connect - // subsequently. Aside from preventing the racing forget/associate, we - // also try to disable network prior to updating the network. - WifiManager.getNetworkId(dequote(configured.ssid), function(netId) { - if (netId) { - WifiManager.disableNetwork(netId, function() { - connectToNetwork(); - }); - } - else { - connectToNetwork(); - } - }); - } else { - // networkReady, above, calls saveConfig. We want to remember the new - // network as being enabled, which isn't the default, so we explicitly - // set it to being "enabled" before we add it and save the - // configuration. - privnet.disabled = 0; - this._addingNetworks[networkKey] = privnet; - WifiManager.addNetwork(privnet, (function(ok) { - delete this._addingNetworks[networkKey]; - - if (!ok) { - this._sendMessage(message, false, "Network is misconfigured", msg); - return; - } - - this.configuredNetworks[networkKey] = privnet; - networkReady(); - }).bind(this)); - } - }, - - forget: function(msg) { - const message = "WifiManager:forget:Return"; - let network = msg.data; - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - this._reloadConfiguredNetworks((function(ok) { - // Give it a chance to remove the network even if reload is failed. - if (!ok) { - debug("Warning !!! Failed to reload the configured networks"); - } - - let ssid = network.ssid; - let networkKey = getNetworkKey(network); - if (!(networkKey in this.configuredNetworks)) { - this._sendMessage(message, false, "Trying to forget an unknown network", msg); - return; - } - - let self = this; - let configured = this.configuredNetworks[networkKey]; - this._reconnectOnDisconnect = (this.currentNetwork && - (this.currentNetwork.ssid === ssid)); - WifiManager.removeNetwork(configured.netId, function(ok) { - if (self._needToEnableNetworks) { - self._enableAllNetworks(); - self._needToEnableNetworks = false; - } - - if (!ok) { - self._sendMessage(message, false, "Unable to remove the network", msg); - self._reconnectOnDisconnect = false; - return; - } - - WifiManager.saveConfig(function() { - self._reloadConfiguredNetworks(function() { - self._sendMessage(message, true, true, msg); - }); - }); - }); - }).bind(this)); - }, - - wps: function(msg) { - const message = "WifiManager:wps:Return"; - let self = this; - let detail = msg.data; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - if (detail.method === "pbc") { - WifiManager.wpsPbc(function(ok) { - if (ok) - self._sendMessage(message, true, true, msg); - else - self._sendMessage(message, false, "WPS PBC failed", msg); - }); - } else if (detail.method === "pin") { - WifiManager.wpsPin(detail, function(pin) { - if (pin) - self._sendMessage(message, true, pin, msg); - else - self._sendMessage(message, false, "WPS PIN failed", msg); - }); - } else if (detail.method === "cancel") { - WifiManager.wpsCancel(function(ok) { - if (ok) - self._sendMessage(message, true, true, msg); - else - self._sendMessage(message, false, "WPS Cancel failed", msg); - }); - } else { - self._sendMessage(message, false, "Invalid WPS method=" + detail.method, - msg); - } - }, - - setPowerSavingMode: function(msg) { - const message = "WifiManager:setPowerSavingMode:Return"; - let self = this; - let enabled = msg.data; - let mode = enabled ? "AUTO" : "ACTIVE"; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - // Some wifi drivers may not implement this command. Set power mode - // even if suspend optimization command failed. - WifiManager.setSuspendOptimizations(enabled, function(ok) { - WifiManager.setPowerMode(mode, function(ok) { - if (ok) { - self._sendMessage(message, true, true, msg); - } else { - self._sendMessage(message, false, "Set power saving mode failed", msg); - } - }); - }); - }, - - setHttpProxy: function(msg) { - const message = "WifiManager:setHttpProxy:Return"; - let self = this; - let network = msg.data.network; - let info = msg.data.info; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - WifiManager.configureHttpProxy(network, info, function(ok) { - if (ok) { - // If configured network is current connected network - // need update http proxy immediately. - let setNetworkKey = getNetworkKey(network); - let curNetworkKey = self.currentNetwork ? getNetworkKey(self.currentNetwork) : null; - if (setNetworkKey === curNetworkKey) - WifiManager.setHttpProxy(network); - - self._sendMessage(message, true, true, msg); - } else { - self._sendMessage(message, false, "Set http proxy failed", msg); - } - }); - }, - - setStaticIpMode: function(msg) { - const message = "WifiManager:setStaticIpMode:Return"; - let self = this; - let network = msg.data.network; - let info = msg.data.info; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - // To compatiable with DHCP returned info structure, do translation here - info.ipaddr_str = info.ipaddr; - info.proxy_str = info.proxy; - info.gateway_str = info.gateway; - info.dns1_str = info.dns1; - info.dns2_str = info.dns2; - - WifiManager.setStaticIpMode(network, info, function(ok) { - if (ok) { - self._sendMessage(message, true, true, msg); - } else { - self._sendMessage(message, false, "Set static ip mode failed", msg); - } - }); - }, - - importCert: function importCert(msg) { - const message = "WifiManager:importCert:Return"; - let self = this; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - WifiManager.importCert(msg.data, function(data) { - if (data.status === 0) { - let usageString = ["ServerCert", "UserCert"]; - let usageArray = []; - for (let i = 0; i < usageString.length; i++) { - if (data.usageFlag & (0x01 << i)) { - usageArray.push(usageString[i]); - } - } - - self._sendMessage(message, true, { - nickname: data.nickname, - usage: usageArray - }, msg); - } else { - self._sendMessage(message, false, "Import Cert failed", msg); - } - }); - }, - - getImportedCerts: function getImportedCerts(msg) { - const message = "WifiManager:getImportedCerts:Return"; - let self = this; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - let certDB = Cc["@mozilla.org/security/x509certdb;1"] - .getService(Ci.nsIX509CertDB); - if (!certDB) { - self._sendMessage(message, false, "Failed to query NSS DB service", msg); - } - - let certList = certDB.getCerts(); - if (!certList) { - self._sendMessage(message, false, "Failed to get certificate List", msg); - } - - let certListEnum = certList.getEnumerator(); - if (!certListEnum) { - self._sendMessage(message, false, "Failed to get certificate List enumerator", msg); - } - let importedCerts = { - ServerCert: [], - UserCert: [], - }; - let UsageMapping = { - SERVERCERT: "ServerCert", - USERCERT: "UserCert", - }; - - while (certListEnum.hasMoreElements()) { - let certInfo = certListEnum.getNext().QueryInterface(Ci.nsIX509Cert); - let certNicknameInfo = /WIFI\_([A-Z]*)\_(.*)/.exec(certInfo.nickname); - if (!certNicknameInfo) { - continue; - } - importedCerts[UsageMapping[certNicknameInfo[1]]].push(certNicknameInfo[2]); - } - - self._sendMessage(message, true, importedCerts, msg); - }, - - deleteCert: function deleteCert(msg) { - const message = "WifiManager:deleteCert:Return"; - let self = this; - - if (!WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is disabled", msg); - return; - } - - WifiManager.deleteCert(msg.data, function(data) { - self._sendMessage(message, data.status === 0, "Delete Cert failed", msg); - }); - }, - - // TODO : These two variables should be removed once GAIA uses tethering API. - useTetheringAPI : false, - tetheringConfig : {}, - - setWifiTethering: function setWifiTethering(msg) { - const message = "WifiManager:setWifiTethering:Return"; - let self = this; - let enabled = msg.data.enabled; - - this.useTetheringAPI = true; - this.tetheringConfig = msg.data.config; - - if (WifiManager.enabled) { - this._sendMessage(message, false, "Wifi is enabled", msg); - return; - } - - this.setWifiApEnabled(enabled, function() { - if ((enabled && WifiManager.tetheringState == "COMPLETED") || - (!enabled && WifiManager.tetheringState == "UNINITIALIZED")) { - self._sendMessage(message, true, msg.data, msg); - } else { - msg.data.reason = enabled ? - "Enable WIFI tethering faild" : "Disable WIFI tethering faild"; - self._sendMessage(message, false, msg.data, msg); - } - }); - }, - - // This is a bit ugly, but works. In particular, this depends on the fact - // that RadioManager never actually tries to get the worker from us. - get worker() { throw "Not implemented"; }, - - shutdown: function() { - debug("shutting down ..."); - this.queueRequest({command: "setWifiEnabled", value: false}, function(data) { - this._setWifiEnabled(false, this._setWifiEnabledCallback.bind(this)); - }.bind(this)); - }, - - // TODO: Remove command queue in Bug 1050147. - requestProcessing: false, // Hold while dequeue and execution a request. - // Released upon the request is fully executed, - // i.e, mostly after callback is done. - requestDone: function requestDone() { - this.requestProcessing = false; - this.nextRequest(); - }, - - nextRequest: function nextRequest() { - // No request to process - if (this._stateRequests.length === 0) { - return; - } - - // Handling request, wait for it. - if (this.requestProcessing) { - return; - } - - // Hold processing lock - this.requestProcessing = true; - - // Find next valid request - let request = this._stateRequests.shift(); - - request.callback(request.data); - }, - - notifyTetheringOn: function notifyTetheringOn() { - // It's really sad that we don't have an API to notify the wifi - // hotspot status. Toggle settings to let gaia know that wifi hotspot - // is enabled. - let self = this; - this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = true; - this._oldWifiTetheringEnabledState = true; - gSettingsService.createLock().set( - SETTINGS_WIFI_TETHERING_ENABLED, - true, - { - handle: function(aName, aResult) { - self.requestDone(); - }, - handleError: function(aErrorMessage) { - self.requestDone(); - } - }); - }, - - notifyTetheringOff: function notifyTetheringOff() { - // It's really sad that we don't have an API to notify the wifi - // hotspot status. Toggle settings to let gaia know that wifi hotspot - // is disabled. - let self = this; - this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = false; - this._oldWifiTetheringEnabledState = false; - gSettingsService.createLock().set( - SETTINGS_WIFI_TETHERING_ENABLED, - false, - { - handle: function(aName, aResult) { - self.requestDone(); - }, - handleError: function(aErrorMessage) { - self.requestDone(); - } - }); - }, - - handleWifiEnabled: function(enabled) { - if (this.ignoreWifiEnabledFromSettings) { - return; - } - - // Make sure Wifi hotspot is idle before switching to Wifi mode. - if (enabled) { - this.queueRequest({command: "setWifiApEnabled", value: false}, function(data) { - if (this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] || - WifiManager.isWifiTetheringEnabled(WifiManager.tetheringState)) { - this.disconnectedByWifi = true; - this.setWifiApEnabled(false, this.notifyTetheringOff.bind(this)); - } else { - this.requestDone(); - } - }.bind(this)); - } - - this.queueRequest({command: "setWifiEnabled", value: enabled}, function(data) { - this._setWifiEnabled(enabled, this._setWifiEnabledCallback.bind(this)); - }.bind(this)); - - if (!enabled) { - this.queueRequest({command: "setWifiApEnabled", value: true}, function(data) { - if (this.disconnectedByWifi) { - this.setWifiApEnabled(true, this.notifyTetheringOn.bind(this)); - } else { - this.requestDone(); - } - this.disconnectedByWifi = false; - }.bind(this)); - } - }, - - handleWifiTetheringEnabled: function(enabled) { - // Make sure Wifi is idle before switching to Wifi hotspot mode. - if (enabled) { - this.queueRequest({command: "setWifiEnabled", value: false}, function(data) { - if (WifiManager.isWifiEnabled(WifiManager.state)) { - this.disconnectedByWifiTethering = true; - this._setWifiEnabled(false, this._setWifiEnabledCallback.bind(this)); - } else { - this.requestDone(); - } - }.bind(this)); - } - - this.queueRequest({command: "setWifiApEnabled", value: enabled}, function(data) { - this.setWifiApEnabled(enabled, this.requestDone.bind(this)); - }.bind(this)); - - if (!enabled) { - this.queueRequest({command: "setWifiEnabled", value: true}, function(data) { - if (this.disconnectedByWifiTethering) { - this._setWifiEnabled(true, this._setWifiEnabledCallback.bind(this)); - } else { - this.requestDone(); - } - this.disconnectedByWifiTethering = false; - }.bind(this)); - } - }, - - // nsIObserver implementation - observe: function observe(subject, topic, data) { - switch (topic) { - case kMozSettingsChangedObserverTopic: - // To avoid WifiWorker setting the wifi again, don't need to deal with - // the "mozsettings-changed" event fired from internal setting. - if ("wrappedJSObject" in subject) { - subject = subject.wrappedJSObject; - } - if (subject.isInternalChange) { - return; - } - - this.handle(subject.key, subject.value); - break; - - case "xpcom-shutdown": - // Ensure the supplicant is detached from B2G to avoid XPCOM shutdown - // blocks forever. - WifiManager.ensureSupplicantDetached(() => { - let wifiService = Cc["@mozilla.org/wifi/service;1"].getService(Ci.nsIWifiProxyService); - wifiService.shutdown(); - let wifiCertService = Cc["@mozilla.org/wifi/certservice;1"].getService(Ci.nsIWifiCertService); - wifiCertService.shutdown(); - }); - break; - } - }, - - handle: function handle(aName, aResult) { - switch(aName) { - // TODO: Remove function call in Bug 1050147. - case SETTINGS_WIFI_ENABLED: - this.handleWifiEnabled(aResult) - break; - case SETTINGS_WIFI_DEBUG_ENABLED: - if (aResult === null) - aResult = false; - DEBUG = aResult; - updateDebug(); - break; - case SETTINGS_WIFI_TETHERING_ENABLED: - this._oldWifiTetheringEnabledState = this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]; - // Fall through! - case SETTINGS_WIFI_SSID: - case SETTINGS_WIFI_SECURITY_TYPE: - case SETTINGS_WIFI_SECURITY_PASSWORD: - case SETTINGS_WIFI_IP: - case SETTINGS_WIFI_PREFIX: - case SETTINGS_WIFI_DHCPSERVER_STARTIP: - case SETTINGS_WIFI_DHCPSERVER_ENDIP: - case SETTINGS_WIFI_DNS1: - case SETTINGS_WIFI_DNS2: - case SETTINGS_USB_DHCPSERVER_STARTIP: - case SETTINGS_USB_DHCPSERVER_ENDIP: - // TODO: code related to wifi-tethering setting should be removed after GAIA - // use tethering API - if (this.useTetheringAPI) { - break; - } - - if (aResult !== null) { - this.tetheringSettings[aName] = aResult; - } - debug("'" + aName + "'" + " is now " + this.tetheringSettings[aName]); - let index = this._wifiTetheringSettingsToRead.indexOf(aName); - - if (index != -1) { - this._wifiTetheringSettingsToRead.splice(index, 1); - } - - if (this._wifiTetheringSettingsToRead.length) { - debug("We haven't read completely the wifi Tethering data from settings db."); - break; - } - - if (this._oldWifiTetheringEnabledState === this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]) { - debug("No changes for SETTINGS_WIFI_TETHERING_ENABLED flag. Nothing to do."); - break; - } - - if (this._oldWifiTetheringEnabledState === null && - !this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]) { - debug("Do nothing when initial settings for SETTINGS_WIFI_TETHERING_ENABLED flag is false."); - break; - } - - this._oldWifiTetheringEnabledState = this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]; - this.handleWifiTetheringEnabled(aResult) - break; - }; - }, - - handleError: function handleError(aErrorMessage) { - debug("There was an error while reading Tethering settings."); - this.tetheringSettings = {}; - this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = false; - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiWorker]); - -var debug; -function updateDebug() { - if (DEBUG) { - debug = function (s) { - dump("-*- WifiWorker component: " + s + "\n"); - }; - } else { - debug = function (s) {}; - } - WifiManager.syncDebug(); -} -updateDebug(); diff --git a/dom/wifi/WifiWorker.manifest b/dom/wifi/WifiWorker.manifest deleted file mode 100644 index e33d6401a..000000000 --- a/dom/wifi/WifiWorker.manifest +++ /dev/null @@ -1 +0,0 @@ -component {a14e8977-d259-433a-a88d-58dd44657e5b} WifiWorker.js diff --git a/dom/wifi/moz.build b/dom/wifi/moz.build deleted file mode 100644 index d769c649c..000000000 --- a/dom/wifi/moz.build +++ /dev/null @@ -1,41 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -XPIDL_SOURCES += [ - 'nsIWifi.idl', - 'nsIWifiCertService.idl', - 'nsIWifiService.idl', -] - -XPIDL_MODULE = 'dom_wifi' - -EXTRA_COMPONENTS += [ - 'DOMWifiManager.js', - 'DOMWifiManager.manifest', - 'DOMWifiP2pManager.js', - 'DOMWifiP2pManager.manifest', - 'WifiWorker.js', - 'WifiWorker.manifest', -] - -EXTRA_JS_MODULES += [ - 'StateMachine.jsm', - 'WifiCommand.jsm', - 'WifiNetUtil.jsm', - 'WifiP2pManager.jsm', - 'WifiP2pWorkerObserver.jsm', -] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - UNIFIED_SOURCES = [ - 'WifiCertService.cpp', - 'WifiHotspotUtils.cpp', - 'WifiProxyService.cpp', - 'WifiUtils.cpp', - ] - DEFINES['CERT_AddTempCertToPerm'] = '__CERT_AddTempCertToPerm' - -FINAL_LIBRARY = 'xul' diff --git a/dom/wifi/nsIWifi.idl b/dom/wifi/nsIWifi.idl deleted file mode 100644 index 82ab9a75b..000000000 --- a/dom/wifi/nsIWifi.idl +++ /dev/null @@ -1,60 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" -#include "nsIDOMDOMRequest.idl" -#include "nsIDOMEvent.idl" - -interface nsIVariant; - -[scriptable, uuid(cf1ac02b-1f39-446e-815b-651ac78d2233)] -interface nsIWifiScanResult : nsISupports { - readonly attribute DOMString ssid; - readonly attribute DOMString bssid; - - const int32_t WPA_PSK = 0x01; - const int32_t WPA_EAP = 0x02; - const int32_t WEP = 0x04; - readonly attribute uint32_t capabilities; - - /** - * Strength of the signal to network. - */ - readonly attribute uint32_t signalStrength; - - readonly attribute uint32_t relSignalStrength; - readonly attribute boolean connected; -}; - -[scriptable, uuid(a6931ebf-8493-4014-90e2-99f406999982)] -interface nsIWifiScanResultsReady : nsISupports { - - /** - * Callback with list of networks. - */ - void onready(in uint32_t count, [array, size_is(count)] in nsIWifiScanResult results); - - /** - * Callback if scanning for networks failed after 3 retry attempts. - */ - void onfailure(); -}; - -[scriptable, uuid(08dfefed-5c5d-4468-8c5d-2c65c24692d9)] -interface nsIWifi : nsISupports -{ - /** - * Shutdown the wifi system. - */ - void shutdown(); - - /** - * Returns the list of currently available networks as well as the list of - * currently configured networks. - * - * On success a callback is notified with the list of networks. - * On failure after 3 scan retry attempts a callback is notified of failure. - */ - void getWifiScanResults(in nsIWifiScanResultsReady callback); -}; diff --git a/dom/wifi/nsIWifiCertService.idl b/dom/wifi/nsIWifiCertService.idl deleted file mode 100644 index fce2dd719..000000000 --- a/dom/wifi/nsIWifiCertService.idl +++ /dev/null @@ -1,54 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIDOMBlob; -interface nsIWifiEventListener; - -[scriptable, uuid(5d0edcd3-c2f1-4946-aae5-06adcbdf0992)] -interface nsIWifiCertService : nsISupports -{ - const unsigned short WIFI_CERT_USAGE_FLAG_SERVER = 0x01; - const unsigned short WIFI_CERT_USAGE_FLAG_USER = 0x02; - - void start(in nsIWifiEventListener listener); - void shutdown(); - - /** - * Import a certificate file. - * - * @param id - * Request ID. - * @param certBlob - * A Blob object containing raw data of certificate to be imported. - * @param certPassword - * Password of certificate. - * @param certNickname - * User assigned nickname for imported certificate. - */ - void importCert(in long id, - in nsIDOMBlob certBlob, - in DOMString certPassword, - in DOMString certNickname); - - /** - * Delete an imported certificate file - * - * @param id - * Request ID. - * @param certNickname - * Certificate nickname to delete. - */ - void deleteCert(in long id, - in DOMString certNickname); - - /** - * Check if certificate has private key. - * - * @param certNickname - * Certificate nickname to check for private key. - */ - boolean hasPrivateKey(in DOMString certNickname); -}; diff --git a/dom/wifi/nsIWifiService.idl b/dom/wifi/nsIWifiService.idl deleted file mode 100644 index 0f320ddda..000000000 --- a/dom/wifi/nsIWifiService.idl +++ /dev/null @@ -1,22 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -[scriptable, uuid(4d4389e0-1547-11e3-8ffd-0800200c9a66)] -interface nsIWifiEventListener : nsISupports { - void onWaitEvent(in AString event, in ACString aInterface); - void onCommand(in jsval result, in ACString aInterface); -}; - -[scriptable, uuid(5e2bd8c0-1547-11e3-8ffd-0800200c9a66)] -interface nsIWifiProxyService : nsISupports { - void start(in nsIWifiEventListener listener, - [array, size_is(aNumOfInterface)] in string aInterfaces, - in unsigned long aNumOfInterface); - void shutdown(); - [implicit_jscontext] - void sendCommand(in jsval parameters, in ACString aInterface); - void waitForEvent(in ACString aInterface); -}; diff --git a/dom/wifi/test/marionette/head.js b/dom/wifi/test/marionette/head.js deleted file mode 100644 index f4a212b11..000000000 --- a/dom/wifi/test/marionette/head.js +++ /dev/null @@ -1,1486 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -// Emulate Promise.jsm semantics. -Promise.defer = function() { return new Deferred(); } -function Deferred() { - this.promise = new Promise(function(resolve, reject) { - this.resolve = resolve; - this.reject = reject; - }.bind(this)); - Object.freeze(this); -} - -const STOCK_HOSTAPD_NAME = 'goldfish-hostapd'; -const HOSTAPD_CONFIG_PATH = '/data/misc/wifi/remote-hostapd/'; - -const SETTINGS_RIL_DATA_ENABLED = 'ril.data.enabled'; -const SETTINGS_TETHERING_WIFI_ENABLED = 'tethering.wifi.enabled'; -const SETTINGS_TETHERING_WIFI_IP = 'tethering.wifi.ip'; -const SETTINGS_TETHERING_WIFI_SECURITY = 'tethering.wifi.security.type'; - -const HOSTAPD_COMMON_CONFIG = { - driver: 'test', - ctrl_interface: '/data/misc/wifi/remote-hostapd', - test_socket: 'DIR:/data/misc/wifi/sockets', - hw_mode: 'b', - channel: '2', -}; - -const HOSTAPD_CONFIG_LIST = [ - { ssid: 'ap0' }, - - { ssid: 'ap1', - wpa: 1, - wpa_pairwise: 'TKIP CCMP', - wpa_passphrase: '12345678' - }, - - { ssid: 'ap2', - wpa: 2, - rsn_pairwise: 'CCMP', - wpa_passphrase: '12345678', - }, -]; - -var gTestSuite = (function() { - let suite = {}; - - // Private member variables of the returned object |suite|. - let wifiManager; - let wifiOrigEnabled; - let pendingEmulatorShellCount = 0; - let sdkVersion; - - /** - * A wrapper function of "is". - * - * Calls the marionette function "is" as well as throws an exception - * if the givens values are not equal. - * - * @param value1 - * Any type of value to compare. - * - * @param value2 - * Any type of value to compare. - * - * @param message - * Debug message for this check. - * - */ - function isOrThrow(value1, value2, message) { - is(value1, value2, message); - if (value1 !== value2) { - throw message; - } - } - - /** - * Send emulator shell command with safe guard. - * - * We should only call |finish()| after all emulator command transactions - * end, so here comes with the pending counter. Resolve when the emulator - * gives positive response, and reject otherwise. - * - * Fulfill params: - * result -- an array of emulator response lines. - * Reject params: - * result -- an array of emulator response lines. - * - * @param aCommand - * A string command to be passed to emulator through its telnet console. - * - * @return A deferred promise. - */ - function runEmulatorShellSafe(aCommand) { - let deferred = Promise.defer(); - - ++pendingEmulatorShellCount; - runEmulatorShell(aCommand, function(aResult) { - --pendingEmulatorShellCount; - - ok(true, "Emulator shell response: " + JSON.stringify(aResult)); - if (Array.isArray(aResult)) { - deferred.resolve(aResult); - } else { - deferred.reject(aResult); - } - }); - - return deferred.promise; - } - - /** - * Wait for one named MozWifiManager event. - * - * Resolve if that named event occurs. Never reject. - * - * Fulfill params: the DOMEvent passed. - * - * @param aEventName - * A string event name. - * - * @return A deferred promise. - */ - function waitForWifiManagerEventOnce(aEventName) { - let deferred = Promise.defer(); - - wifiManager.addEventListener(aEventName, function onevent(aEvent) { - wifiManager.removeEventListener(aEventName, onevent); - - ok(true, "WifiManager event '" + aEventName + "' got."); - deferred.resolve(aEvent); - }); - - return deferred.promise; - } - - /** - * Wait for one named MozMobileConnection event. - * - * Resolve if that named event occurs. Never reject. - * - * Fulfill params: the DOMEvent passed. - * - * @param aEventName - * A string event name. - * - * @return A deferred promise. - */ - function waitForMobileConnectionEventOnce(aEventName, aServiceId) { - aServiceId = aServiceId || 0; - - let deferred = Promise.defer(); - let mobileconnection = navigator.mozMobileConnections[aServiceId]; - - mobileconnection.addEventListener(aEventName, function onevent(aEvent) { - mobileconnection.removeEventListener(aEventName, onevent); - - ok(true, "Mobile connection event '" + aEventName + "' got."); - deferred.resolve(aEvent); - }); - - return deferred.promise; - } - - /** - * Get the detail of currently running processes containing the given name. - * - * Use shell command 'ps' to get the desired process's detail. Never reject. - * - * Fulfill params: - * result -- an array of { pname, pid } - * - * @param aProcessName - * The process to get the detail. - * - * @return A deferred promise. - */ - function getProcessDetail(aProcessName) { - return runEmulatorShellSafe(['ps']) - .then(processes => { - // Sample 'ps' output: - // - // USER PID PPID VSIZE RSS WCHAN PC NAME - // root 1 0 284 204 c009e6c4 0000deb4 S /init - // root 2 0 0 0 c0052c64 00000000 S kthreadd - // root 3 2 0 0 c0044978 00000000 S ksoftirqd/0 - // - let detail = []; - - processes.shift(); // Skip the first line. - for (let i = 0; i < processes.length; i++) { - let tokens = processes[i].split(/\s+/); - let pname = tokens[tokens.length - 1]; - let pid = tokens[1]; - if (-1 !== pname.indexOf(aProcessName)) { - detail.push({ pname: pname, pid: pid }); - } - } - - return detail; - }); - } - - /** - * Add required permissions for wifi testing. Never reject. - * - * The permissions required for wifi testing are 'wifi-manage' and 'settings-write'. - * Never reject. - * - * Fulfill params: (none) - * - * @return A deferred promise. - */ - function addRequiredPermissions() { - let deferred = Promise.defer(); - - let permissions = [{ 'type': 'wifi-manage', 'allow': 1, 'context': window.document }, - { 'type': 'settings-write', 'allow': 1, 'context': window.document }, - { 'type': 'settings-read', 'allow': 1, 'context': window.document }, - { 'type': 'settings-api-write', 'allow': 1, 'context': window.document }, - { 'type': 'settings-api-read', 'allow': 1, 'context': window.document }, - { 'type': 'mobileconnection', 'allow': 1, 'context': window.document }]; - - SpecialPowers.pushPermissions(permissions, function() { - deferred.resolve(); - }); - - return deferred.promise; - } - - /** - * Wrap DOMRequest onsuccess/onerror events to Promise resolve/reject. - * - * Fulfill params: A DOMEvent. - * Reject params: A DOMEvent. - * - * @param aRequest - * A DOMRequest instance. - * - * @return A deferred promise. - */ - function wrapDomRequestAsPromise(aRequest) { - let deferred = Promise.defer(); - - ok(aRequest instanceof DOMRequest, - "aRequest is instanceof " + aRequest.constructor); - - aRequest.addEventListener("success", function(aEvent) { - deferred.resolve(aEvent); - }); - aRequest.addEventListener("error", function(aEvent) { - deferred.reject(aEvent); - }); - - return deferred.promise; - } - - /** - * Ensure wifi is enabled/disabled. - * - * Issue a wifi enable/disable request if wifi is not in the desired state; - * return a resolved promise otherwise. Note that you cannot rely on this - * function to test the correctness of enabling/disabling wifi. - * (use requestWifiEnabled instead) - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return a resolved promise or deferred promise. - */ - function ensureWifiEnabled(aEnabled, useAPI) { - if (wifiManager.enabled === aEnabled) { - log('Already ' + (aEnabled ? 'enabled' : 'disabled')); - return Promise.resolve(); - } - return requestWifiEnabled(aEnabled, useAPI); - } - - /** - * Issue a request to enable/disable wifi. - * - * This function will attempt to enable/disable wifi, by calling API or by - * writing settings 'wifi.enabled' regardless of the wifi state, based on the - * value of |userAPI| parameter. - * Default is using settings. - * - * Note there's a limitation of co-existance of both method, per bug 930355, - * that once enable/disable wifi by API, the settings method won't work until - * reboot. So the test of wifi enable API should be executed last. - * TODO: Remove settings method after enable/disable wifi by settings is - * removed after bug 1050147. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function requestWifiEnabled(aEnabled, useAPI) { - return Promise.all([ - waitForWifiManagerEventOnce(aEnabled ? 'enabled' : 'disabled'), - useAPI ? - wrapDomRequestAsPromise(wifiManager.setWifiEnabled(aEnabled)) : - setSettings({ 'wifi.enabled': aEnabled }), - ]); - } - - /** - * Wait for RIL data being connected. - * - * This function will check |MozMobileConnection.data.connected| on - * every 'datachange' event. Resolve when |MozMobileConnection.data.connected| - * becomes the expected state. Never reject. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aConnected - * Boolean that indicates the desired data state. - * - * @param aServiceId [optional] - * A numeric DSDS service id. Default: 0. - * - * @return A deferred promise. - */ - function waitForRilDataConnected(aConnected, aServiceId) { - aServiceId = aServiceId || 0; - return waitForMobileConnectionEventOnce('datachange', aServiceId) - .then(function () { - let mobileconnection = navigator.mozMobileConnections[aServiceId]; - if (mobileconnection.data.connected !== aConnected) { - return waitForRilDataConnected(aConnected, aServiceId); - } - }); - } - - /** - * Request to enable/disable wifi tethering. - * - * Enable/disable wifi tethering by changing the settings value 'tethering.wifi.enabled'. - * Resolve when the routing is verified to set up successfully in 20 seconds. The polling - * period is 1 second. - * - * Fulfill params: (none) - * Reject params: The error message. - * - * @param aEnabled - * Boolean that indicates to enable or disable wifi tethering. - * - * @return A deferred promise. - */ - function requestTetheringEnabled(aEnabled) { - let RETRY_INTERVAL_MS = 1000; - let retryCnt = 20; - - return setSettings1(SETTINGS_TETHERING_WIFI_ENABLED, aEnabled) - .then(function waitForRoutingVerified() { - return verifyTetheringRouting(aEnabled) - .then(null, function onreject(aReason) { - - log('verifyTetheringRouting rejected due to ' + aReason + - ' (' + retryCnt + ')'); - - if (!retryCnt--) { - throw aReason; - } - - return waitForTimeout(RETRY_INTERVAL_MS).then(waitForRoutingVerified); - }); - }); - } - - /** - * Forget the given network. - * - * Resolve when we successfully forget the given network; reject when any error - * occurs. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aNetwork - * An object of MozWifiNetwork. - * - * @return A deferred promise. - */ - function forgetNetwork(aNetwork) { - let request = wifiManager.forget(aNetwork); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Forget all known networks. - * - * Resolve when we successfully forget all the known network; - * reject when any error occurs. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function forgetAllKnownNetworks() { - - function createForgetNetworkChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - chain = chain.then(() => forgetNetwork(aNetwork)); - }); - - return chain; - } - - return getKnownNetworks() - .then(networks => createForgetNetworkChain(networks)); - } - - /** - * Get all known networks. - * - * Resolve when we get all the known networks; reject when any error - * occurs. - * - * Fulfill params: An array of MozWifiNetwork - * Reject params: (none) - * - * @return A deferred promise. - */ - function getKnownNetworks() { - let request = wifiManager.getKnownNetworks(); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Set the given network to static ip mode. - * - * Resolve when we set static ip mode successfully; reject when any error - * occurs. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function setStaticIpMode(aNetwork, aConfig) { - let request = wifiManager.setStaticIpMode(aNetwork, aConfig); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Issue a request to scan all wifi available networks. - * - * Resolve when we get the scan result; reject when any error - * occurs. - * - * Fulfill params: An array of MozWifiNetwork - * Reject params: (none) - * - * @return A deferred promise. - */ - function requestWifiScan() { - let request = wifiManager.getNetworks(); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Import a certificate with nickname and password. - * - * Resolve when we import certificate successfully; reject when any error - * occurs. - * - * Fulfill params: An object of certificate information. - * Reject params: (none) - * - * @return A deferred promise. - */ - function importCert(certBlob, password, nickname) { - let request = wifiManager.importCert(certBlob, password, nickname); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Delete certificate of nickname. - * - * Resolve when we delete certificate successfully; reject when any error - * occurs. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function deleteCert(nickname) { - let request = wifiManager.deleteCert(nickname); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Get list of imported certificates. - * - * Resolve when we get certificate list successfully; reject when any error - * occurs. - * - * Fulfill params: Nickname of imported certificate arranged by usage. - * Reject params: (none) - * - * @return A deferred promise. - */ - function getImportedCerts() { - let request = wifiManager.getImportedCerts(); - return wrapDomRequestAsPromise(request) - .then(event => event.target.result); - } - - /** - * Request wifi scan and verify the scan result as well. - * - * Issue a wifi scan request and check if the result is expected. - * Since the old APs may be cached and the newly added APs may be - * still not scan-able, a couple of attempts are acceptable. - * Resolve if we eventually get the expected scan result; reject otherwise. - * - * Fulfill params: The scan result, which is an array of MozWifiNetwork - * Reject params: (none) - * - * @param aRetryCnt - * The maxmimum number of attempts until we get the expected scan result. - * @param aExpectedNetworks - * An array of object, each of which contains at least the |ssid| property. - * - * @return A deferred promise. - */ - function testWifiScanWithRetry(aRetryCnt, aExpectedNetworks) { - - // Check if every single ssid of each |aScanResult| exists in |aExpectedNetworks| - // as well as the length of |aScanResult| equals to |aExpectedNetworks|. - function isScanResultExpected(aScanResult) { - if (aScanResult.length !== aExpectedNetworks.length) { - return false; - } - - for (let i = 0; i < aScanResult.length; i++) { - if (-1 === getFirstIndexBySsid(aScanResult[i].ssid, aExpectedNetworks)) { - return false; - } - } - return true; - } - - return requestWifiScan() - .then(function (networks) { - if (isScanResultExpected(networks, aExpectedNetworks)) { - return networks; - } - if (aRetryCnt > 0) { - return testWifiScanWithRetry(aRetryCnt - 1, aExpectedNetworks); - } - throw 'Unexpected scan result!'; - }); - } - - /** - * Test wifi association. - * - * Associate with the given network object which is obtained by - * MozWifiManager.getNetworks() (i.e. MozWifiNetwork). - * Resolve when the 'connected' status change event is received. - * Note that we might see other events like 'connecting' - * before 'connected'. So we need to call |waitForWifiManagerEventOnce| - * again whenever non 'connected' event is seen. Never reject. - * - * Fulfill params: (none) - * - * @param aNetwork - * An object of MozWifiNetwork. - * - * @return A deferred promise. - */ - function testAssociate(aNetwork) { - setPasswordIfNeeded(aNetwork); - - let promises = []; - - // Register the event listerner to wait for 'connected' event first - // to avoid racing issue. - promises.push(waitForConnected(aNetwork)); - - // Then we do the association. - let request = wifiManager.associate(aNetwork); - promises.push(wrapDomRequestAsPromise(request)); - - return Promise.all(promises); - } - - function waitForConnected(aExpectedNetwork) { - return waitForWifiManagerEventOnce('statuschange') - .then(function onstatuschange(event) { - log("event.status: " + event.status); - log("event.network.ssid: " + (event.network ? event.network.ssid : '')); - - if ("connected" === event.status && - event.network.ssid === aExpectedNetwork.ssid) { - return; // Got expected 'connected' event from aNetwork.ssid. - } - - log('Not expected "connected" statuschange event. Wait again!'); - return waitForConnected(aExpectedNetwork); - }); - } - - /** - * Set the password for associating the given network if needed. - * - * Set the password by looking up HOSTAPD_CONFIG_LIST. This function - * will also set |keyManagement| properly. - * - * @param aNetwork - * The MozWifiNetwork object. - */ - function setPasswordIfNeeded(aNetwork) { - let i = getFirstIndexBySsid(aNetwork.ssid, HOSTAPD_CONFIG_LIST); - if (-1 === i) { - log('unknown ssid: ' + aNetwork.ssid); - return; // Unknown network. Assume insecure. - } - - if (!aNetwork.security.length) { - return; // No need to set password. - } - - let security = aNetwork.security[0]; - if (/PSK$/.test(security)) { - aNetwork.psk = HOSTAPD_CONFIG_LIST[i].wpa_passphrase; - aNetwork.keyManagement = 'WPA-PSK'; - } else if (/WEP$/.test(security)) { - aNetwork.wep = HOSTAPD_CONFIG_LIST[i].wpa_passphrase; - aNetwork.keyManagement = 'WEP'; - } - } - - /** - * Set mozSettings values. - * - * Resolve if that mozSettings value is set successfully, reject otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aSettings - * An object of format |{key1: value1, key2: value2, ...}|. - * @param aAllowError [optional] - * A boolean value. If set to true, an error response won't be treated - * as test failure. Default: false. - * - * @return A deferred promise. - */ - function setSettings(aSettings) { - let lock = window.navigator.mozSettings.createLock(); - let request = lock.set(aSettings); - let deferred = Promise.defer(); - lock.onsettingstransactionsuccess = function () { - ok(true, "setSettings(" + JSON.stringify(aSettings) + ")"); - deferred.resolve(); - }; - lock.onsettingstransactionfailure = function (aEvent) { - ok(false, "setSettings(" + JSON.stringify(aSettings) + ")"); - deferred.reject(); - throw aEvent.target.error; - }; - return deferred.promise; - } - - /** - * Set mozSettings value with only one key. - * - * Resolve if that mozSettings value is set successfully, reject otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aKey - * A string key. - * @param aValue - * An object value. - * @param aAllowError [optional] - * A boolean value. If set to true, an error response won't be treated - * as test failure. Default: false. - * - * @return A deferred promise. - */ - function setSettings1(aKey, aValue, aAllowError) { - let settings = {}; - settings[aKey] = aValue; - return setSettings(settings, aAllowError); - } - - /** - * Get mozSettings value specified by @aKey. - * - * Resolve if that mozSettings value is retrieved successfully, reject - * otherwise. - * - * Fulfill params: - * The corresponding mozSettings value of the key. - * Reject params: (none) - * - * @param aKey - * A string. - * @param aAllowError [optional] - * A boolean value. If set to true, an error response won't be treated - * as test failure. Default: false. - * - * @return A deferred promise. - */ - function getSettings(aKey, aAllowError) { - let request = - navigator.mozSettings.createLock().get(aKey); - return wrapDomRequestAsPromise(request) - .then(function resolve(aEvent) { - ok(true, "getSettings(" + aKey + ") - success"); - return aEvent.target.result[aKey]; - }, function reject(aEvent) { - ok(aAllowError, "getSettings(" + aKey + ") - error"); - }); - } - - - /** - * Start hostapd processes with given configuration list. - * - * For starting one hostapd, we need to generate a specific config file - * then launch a hostapd process with the confg file path passed. The - * config file is generated by two sources: one is the common - * part (HOSTAPD_COMMON_CONFIG) and the other is from the given |aConfigList|. - * Resolve when all the hostpads are requested to start. It is not guaranteed - * that all the hostapds will be up and running successfully. Never reject. - * - * Fulfill params: (none) - * - * @param aConfigList - * An array of config objects, each property in which will be - * output to the confg file with the format: [key]=[value] in one line. - * See http://hostap.epitest.fi/cgit/hostap/plain/hostapd/hostapd.conf - * for more information. - * - * @return A deferred promise. - */ - function startHostapds(aConfigList) { - - function createConfigFromCommon(aIndex) { - // Create an copy of HOSTAPD_COMMON_CONFIG. - let config = JSON.parse(JSON.stringify(HOSTAPD_COMMON_CONFIG)); - - // Add user config. - for (let key in aConfigList[aIndex]) { - config[key] = aConfigList[aIndex][key]; - } - - // 'interface' is a required field but no need of being configurable - // for a test case. So we initialize this field on our own. - config.interface = 'AP-' + aIndex; - - return config; - } - - function startOneHostapd(aIndex) { - let configFileName = HOSTAPD_CONFIG_PATH + 'ap' + aIndex + '.conf'; - return writeHostapdConfFile(configFileName, createConfigFromCommon(aIndex)) - .then(() => runEmulatorShellSafe(['hostapd', '-B', configFileName])) - .then(function (reply) { - // It may fail at the first time due to the previous ungracefully terminated one. - if (reply.length === 0) { - // The hostapd starts successfully - return; - } - - if (reply[0].indexOf('bind(PF_UNIX): Address already in use') !== -1) { - return startOneHostapd(aIndex); - } - }); - } - - return Promise.all(aConfigList.map(function(aConfig, aIndex) { - return startOneHostapd(aIndex); - })); - } - - /** - * Kill all the running hostapd processes. - * - * Use shell command 'kill -9' to kill all hostapds. Never reject. - * - * Fulfill params: (none) - * - * @return A deferred promise. - */ - function killAllHostapd() { - return getProcessDetail('hostapd') - .then(function (runningHostapds) { - let promises = runningHostapds.map(runningHostapd => { - return runEmulatorShellSafe(['kill', '-9', runningHostapd.pid]); - }); - return Promise.all(promises); - }); - } - - /** - * Write out the config file to the given path. - * - * For each key/value pair in |aConfig|, - * - * [key]=[value] - * - * will be output to one new line. Never reject. - * - * Fulfill params: (none) - * - * @param aFilePath - * The file path that we desire the config file to be located. - * - * @param aConfig - * The config object. - * - * @return A deferred promise. - */ - function writeHostapdConfFile(aFilePath, aConfig) { - let content = ''; - for (let key in aConfig) { - if (aConfig.hasOwnProperty(key)) { - content += (key + '=' + aConfig[key] + '\n'); - } - } - return writeFile(aFilePath, content); - } - - /** - * Write file to the given path filled with given content. - * - * For now it is implemented by shell command 'echo'. Also, if the - * content contains whitespace, we need to quote the content to - * avoid error. Never reject. - * - * Fulfill params: (none) - * - * @param aFilePath - * The file path that we desire the file to be located. - * - * @param aContent - * The content as string which should be written to the file. - * - * @return A deferred promise. - */ - function writeFile(aFilePath, aContent) { - const CONTENT_MAX_LENGTH = 900; - var commands = []; - for (var i = 0; i < aContent.length; i += CONTENT_MAX_LENGTH) { - var content = aContent.substr(i, CONTENT_MAX_LENGTH); - if (-1 === content.indexOf(' ')) { - content = '"' + content + '"'; - } - commands.push(['echo', '-n', content, i === 0 ? '>' : '>>', aFilePath]); - } - - let chain = Promise.resolve(); - commands.forEach(function (command) { - chain = chain.then(() => runEmulatorShellSafe(command)); - }); - return chain; - } - - /** - * Check if a init service is running or not. - * - * Check the android property 'init.svc.[aServiceName]' to determine if - * a init service is running. Reject if the propery is neither 'running' - * nor 'stopped'. - * - * Fulfill params: - * result -- |true| if the init service is running; |false| otherwise. - * Reject params: (none) - * - * @param aServiceName - * The init service name. - * - * @return A deferred promise. - */ - function isInitServiceRunning(aServiceName) { - return runEmulatorShellSafe(['getprop', 'init.svc.' + aServiceName]) - .then(function (result) { - if ('running' !== result[0] && 'stopped' !== result[0]) { - throw 'Init service running state should be "running" or "stopped".'; - } - return 'running' === result[0]; - }); - } - - /** - * Wait for timeout. - * - * Resolve when the given duration elapsed. Never reject. - * - * Fulfill params: (none) - * - * @param aTimeoutMs - * The duration after which the timeout event should occurs. - * - * @return A deferred promise. - */ - function waitForTimeout(aTimeoutMs) { - let deferred = Promise.defer(); - - setTimeout(function() { - deferred.resolve(); - }, aTimeoutMs); - - return deferred.promise; - } - - /** - * Start or stop an init service. - * - * Use shell command 'start'/'stop' to start/stop an init service. - * The running state will also be checked after we start/stop the service. - * Resolve if the service is successfully started/stopped; Reject otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aServiceName - * The name of the service we want to start/stop. - * - * @param aStart - * |true| for starting the init service. |false| for stopping. - * - * @return A deferred promise. - */ - function startStopInitService(aServiceName, aStart) { - let retryCnt = 5; - - return runEmulatorShellSafe([aStart ? 'start' : 'stop', aServiceName]) - .then(() => isInitServiceRunning(aServiceName)) - .then(function onIsServiceRunningResolved(aIsRunning) { - if (aStart === aIsRunning) { - return; - } - - if (retryCnt-- > 0) { - log('Failed to ' + (aStart ? 'start ' : 'stop ') + aServiceName + - '. Retry: ' + retryCnt); - - return waitForTimeout(500) - .then(() => isInitServiceRunning(aServiceName)) - .then(onIsServiceRunningResolved); - } - - throw 'Failed to ' + (aStart ? 'start' : 'stop') + ' ' + aServiceName; - }); - } - - /** - * Start the stock hostapd. - * - * Since the stock hostapd is an init service, use |startStopInitService| to - * start it. Note that we might fail to start the stock hostapd at the first time - * for unknown reason so give it the second chance to start again. - * Resolve when we are eventually successful to start the stock hostapd; Reject - * otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function startStockHostapd() { - return startStopInitService(STOCK_HOSTAPD_NAME, true) - .then(null, function onreject() { - log('Failed to restart goldfish-hostapd at the first time. Try again!'); - return startStopInitService((STOCK_HOSTAPD_NAME), true); - }); - } - - /** - * Stop the stock hostapd. - * - * Since the stock hostapd is an init service, use |startStopInitService| to - * stop it. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function stopStockHostapd() { - return startStopInitService(STOCK_HOSTAPD_NAME, false); - } - - /** - * Get the index of the first matching entry by |ssid|. - * - * Find the index of the first entry of |aArray| which property |ssid| - * is same as |aSsid|. - * - * @param aSsid - * The ssid that we want to match. - * @param aArray - * An array of objects, each of which should have the property |ssid|. - * - * @return The 0-based index of first matching entry if found; -1 otherwise. - */ - function getFirstIndexBySsid(aSsid, aArray) { - for (let i = 0; i < aArray.length; i++) { - if (aArray[i].ssid === aSsid) { - return i; - } - } - return -1; - } - - /** - * Count the number of running process and verify if the count is expected. - * - * Return a promise that resolves when the process has expected number - * of running instances and rejects otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aOrigWifiEnabled - * Boolean which indicates wifi was originally enabled. - * - * @return A deferred promise. - */ - function verifyNumOfProcesses(aProcessName, aExpectedNum) { - return getProcessDetail(aProcessName) - .then(function (detail) { - if (detail.length === aExpectedNum) { - return; - } - throw 'Unexpected number of running processes:' + aProcessName + - ', expected: ' + aExpectedNum + ', actual: ' + detail.length; - }); - } - - /** - * Execute 'netcfg' shell and parse the result. - * - * Resolve when the executing is successful and reject otherwise. - * - * Fulfill params: Command result object, each key of which is the interface - * name and value is { ip(string), prefix(string) }. - * Reject params: String that indicates the reason of rejection. - * - * @return A deferred promise. - */ - function exeAndParseNetcfg() { - return runEmulatorShellSafe(['netcfg']) - .then(function (aLines) { - // Sample output: - // - // lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00 - // eth0 UP 10.0.2.15/24 0x00001043 52:54:00:12:34:56 - // rmnet1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:58 - // rmnet2 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:59 - // rmnet3 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:5a - // wlan0 UP 192.168.1.1/24 0x00001043 52:54:00:12:34:5b - // sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00 - // rmnet0 UP 10.0.2.100/24 0x00001043 52:54:00:12:34:57 - // - let netcfgResult = {}; - aLines.forEach(function (aLine) { - let tokens = aLine.split(/\s+/); - if (tokens.length < 5) { - return; - } - let ifname = tokens[0]; - let [ip, prefix] = tokens[2].split('/'); - netcfgResult[ifname] = { ip: ip, prefix: prefix }; - }); - log("netcfg result:" + JSON.stringify(netcfgResult)); - - return netcfgResult; - }); - } - - /** - * Execute 'ip route' and parse the result. - * - * Resolve when the executing is successful and reject otherwise. - * - * Fulfill params: Command result object, each key of which is the interface - * name and value is { src(string), gateway(string), - * default(boolean) }. - * Reject params: String that indicates the reason of rejection. - * - * @return A deferred promise. - */ - function exeAndParseIpRoute() { - return runEmulatorShellSafe(['ip', 'route']) - .then(function (aLines) { - // Sample output: - // - // 10.0.2.4 via 10.0.2.2 dev rmnet0 - // 10.0.2.3 via 10.0.2.2 dev rmnet0 - // 192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.1 - // 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 - // 10.0.2.0/24 dev rmnet0 proto kernel scope link src 10.0.2.100 - // default via 10.0.2.2 dev rmnet0 - // default via 10.0.2.2 dev eth0 metric 2 - // - - let ipRouteResult = {}; - - // Parse source ip for each interface. - aLines.forEach(function (aLine) { - let tokens = aLine.trim().split(/\s+/); - let srcIndex = tokens.indexOf('src'); - if (srcIndex < 0 || srcIndex + 1 >= tokens.length) { - return; - } - let ifname = tokens[2]; - let src = tokens[srcIndex + 1]; - ipRouteResult[ifname] = { src: src, default: false, gateway: null }; - }); - - // Parse default interfaces. - aLines.forEach(function (aLine) { - let tokens = aLine.split(/\s+/); - if (tokens.length < 2) { - return; - } - if ('default' === tokens[0]) { - let ifnameIndex = tokens.indexOf('dev'); - if (ifnameIndex < 0 || ifnameIndex + 1 >= tokens.length) { - return; - } - let ifname = tokens[ifnameIndex + 1]; - if (!ipRouteResult[ifname]) { - return; - } - ipRouteResult[ifname].default = true; - let gwIndex = tokens.indexOf('via'); - if (gwIndex < 0 || gwIndex + 1 >= tokens.length) { - return; - } - ipRouteResult[ifname].gateway = tokens[gwIndex + 1]; - return; - } - }); - log("ip route result:" + JSON.stringify(ipRouteResult)); - - return ipRouteResult; - }); - } - - /** - * Verify everything about routing when the wifi tethering is either on or off. - * - * We use two unix commands to verify the routing: 'netcfg' and 'ip route'. - * For now the following two things will be checked: - * 1) The default route interface should be 'rmnet0'. - * 2) wlan0 is up and its ip is set to a private subnet. - * - * We also verify iptables output as netd's NatController will execute - * $ iptables -t nat -A POSTROUTING -o rmnet0 -j MASQUERADE - * - * Resolve when the verification is successful and reject otherwise. - * - * Fulfill params: (none) - * Reject params: String that indicates the reason of rejection. - * - * @return A deferred promise. - */ - function verifyTetheringRouting(aEnabled) { - let netcfgResult; - let ipRouteResult; - - // Find MASQUERADE in POSTROUTING section. 'MASQUERADE' should be found - // when tethering is enabled. 'MASQUERADE' shouldn't be found when tethering - // is disabled. - function verifyIptables() { - let MASQUERADE_checkSection = 'POSTROUTING'; - if (sdkVersion > 15) { - // Check 'natctrl_nat_POSTROUTING' section after ICS. - MASQUERADE_checkSection = 'natctrl_nat_POSTROUTING'; - } - - return runEmulatorShellSafe(['iptables', '-t', 'nat', '-L', MASQUERADE_checkSection]) - .then(function(aLines) { - // $ iptables -t nat -L POSTROUTING - // - // Sample output (tethering on): - // - // Chain POSTROUTING (policy ACCEPT) - // target prot opt source destination - // MASQUERADE all -- anywhere anywhere - // - let found = (function find_MASQUERADE() { - // Skip first two lines. - for (let i = 2; i < aLines.length; i++) { - if (-1 !== aLines[i].indexOf('MASQUERADE')) { - return true; - } - } - return false; - })(); - - if ((aEnabled && !found) || (!aEnabled && found)) { - throw 'MASQUERADE' + (found ? '' : ' not') + ' found while tethering is ' + - (aEnabled ? 'enabled' : 'disabled'); - } - }); - } - - function verifyDefaultRouteAndIp(aExpectedWifiTetheringIp) { - if (aEnabled) { - isOrThrow(ipRouteResult['rmnet0'].src, netcfgResult['rmnet0'].ip, 'rmnet0.ip'); - isOrThrow(ipRouteResult['rmnet0'].default, true, 'rmnet0.default'); - - isOrThrow(ipRouteResult['wlan0'].src, netcfgResult['wlan0'].ip, 'wlan0.ip'); - isOrThrow(ipRouteResult['wlan0'].src, aExpectedWifiTetheringIp, 'expected ip'); - isOrThrow(ipRouteResult['wlan0'].default, false, 'wlan0.default'); - } - } - - return verifyIptables() - .then(exeAndParseNetcfg) - .then((aResult) => { netcfgResult = aResult; }) - .then(exeAndParseIpRoute) - .then((aResult) => { ipRouteResult = aResult; }) - .then(() => getSettings(SETTINGS_TETHERING_WIFI_IP)) - .then(ip => verifyDefaultRouteAndIp(ip)); - } - - /** - * Clean up all the allocated resources and running services for the test. - * - * After the test no matter success or failure, we should - * 1) Restore to the wifi original state (enabled or disabled) - * 2) Wait until all pending emulator shell commands are done. - * - * |finsih| will be called in the end. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @return A deferred promise. - */ - function cleanUp() { - waitFor(function() { - return ensureWifiEnabled(true) - .then(forgetAllKnownNetworks) - .then(() => ensureWifiEnabled(wifiOrigEnabled)) - .then(finish); - }, function() { - return pendingEmulatorShellCount === 0; - }); - } - - /** - * Init the test environment. - * - * Mainly add the required permissions and initialize the wifiManager - * and the orignal state of wifi. Reject if failing to create - * window.navigator.mozWifiManager; resolve if all is well. - * - * |finsih| will be called in the end. - * - * Fulfill params: (none) - * Reject params: The reject reason. - * - * @return A deferred promise. - */ - function initTestEnvironment() { - return addRequiredPermissions() - .then(function() { - wifiManager = window.navigator.mozWifiManager; - if (!wifiManager) { - throw 'window.navigator.mozWifiManager is NULL'; - } - wifiOrigEnabled = wifiManager.enabled; - }) - .then(() => runEmulatorShellSafe(['getprop', 'ro.build.version.sdk'])) - .then(aLines => { - sdkVersion = parseInt(aLines[0]); - }); - } - - //--------------------------------------------------- - // Public test suite functions - //--------------------------------------------------- - suite.getWifiManager = (() => wifiManager); - suite.ensureWifiEnabled = ensureWifiEnabled; - suite.requestWifiEnabled = requestWifiEnabled; - suite.startHostapds = startHostapds; - suite.getProcessDetail = getProcessDetail; - suite.killAllHostapd = killAllHostapd; - suite.wrapDomRequestAsPromise = wrapDomRequestAsPromise; - suite.waitForWifiManagerEventOnce = waitForWifiManagerEventOnce; - suite.verifyNumOfProcesses = verifyNumOfProcesses; - suite.testWifiScanWithRetry = testWifiScanWithRetry; - suite.getFirstIndexBySsid = getFirstIndexBySsid; - suite.testAssociate = testAssociate; - suite.getKnownNetworks = getKnownNetworks; - suite.setStaticIpMode = setStaticIpMode; - suite.requestWifiScan = requestWifiScan; - suite.waitForConnected = waitForConnected; - suite.forgetNetwork = forgetNetwork; - suite.waitForTimeout = waitForTimeout; - suite.waitForRilDataConnected = waitForRilDataConnected; - suite.requestTetheringEnabled = requestTetheringEnabled; - suite.importCert = importCert; - suite.getImportedCerts = getImportedCerts; - suite.deleteCert = deleteCert; - suite.writeFile = writeFile; - suite.exeAndParseNetcfg = exeAndParseNetcfg; - suite.exeAndParseIpRoute = exeAndParseIpRoute; - - /** - * Common test routine. - * - * Start a test with the given test case chain. The test environment will be - * settled down before the test. After the test, all the affected things will - * be restored. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.doTest = function(aTestCaseChain) { - return initTestEnvironment() - .then(aTestCaseChain) - .then(function onresolve() { - cleanUp(); - }, function onreject(aReason) { - ok(false, 'Promise rejects during test' + (aReason ? '(' + aReason + ')' : '')); - cleanUp(); - }); - }; - - /** - * Common test routine without the presence of stock hostapd. - * - * Same as doTest except stopping the stock hostapd before test - * and restarting it after test. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.doTestWithoutStockAp = function(aTestCaseChain) { - return suite.doTest(function() { - return stopStockHostapd() - .then(aTestCaseChain) - .then(startStockHostapd); - }); - }; - - /** - * The common test routine for wifi tethering. - * - * Similar as doTest except that it will set 'ril.data.enabled' to true - * before testing and restore it afterward. It will also verify 'ril.data.enabled' - * and 'tethering.wifi.enabled' to be false in the beginning. Note that this routine - * will NOT change the state of 'tethering.wifi.enabled' so the user should enable - * than disable on his/her own. This routine will only check if tethering is turned - * off after testing. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.doTestTethering = function(aTestCaseChain) { - - function verifyInitialState() { - return getSettings(SETTINGS_RIL_DATA_ENABLED) - .then(enabled => isOrThrow(enabled, false, SETTINGS_RIL_DATA_ENABLED)) - .then(() => getSettings(SETTINGS_TETHERING_WIFI_ENABLED)) - .then(enabled => isOrThrow(enabled, false, SETTINGS_TETHERING_WIFI_ENABLED)); - } - - function initTetheringTestEnvironment() { - // Enable ril data. - return Promise.all([waitForRilDataConnected(true), - setSettings1(SETTINGS_RIL_DATA_ENABLED, true)]) - .then(setSettings1(SETTINGS_TETHERING_WIFI_SECURITY, 'open')); - } - - function restoreToInitialState() { - return setSettings1(SETTINGS_RIL_DATA_ENABLED, false) - .then(() => getSettings(SETTINGS_TETHERING_WIFI_ENABLED)) - .then(enabled => is(enabled, false, 'Tethering should be turned off.')); - } - - return suite.doTest(function() { - return verifyInitialState() - .then(initTetheringTestEnvironment) - // Since stock hostapd is not reliable after ICS, we just - // turn off potential stock hostapd during testing to avoid - // interference. - .then(stopStockHostapd) - .then(aTestCaseChain) - .then(startStockHostapd) - .then(restoreToInitialState, function onreject(aReason) { - return restoreToInitialState() - .then(() => { throw aReason; }); // Re-throw the orignal reject reason. - }); - }); - }; - - /** - * Run test with imported certificate. - * - * Certificate will be imported and confirmed before running test, and be - * deleted after running test. - * - * Fulfill params: (none) - * - * @param certBlob - * Certificate content as Blob. - * @param password - * Password for importing certificate, only used for importing PKCS#12. - * @param nickanem - * Nickname for imported certificate. - * @param usage - * Expected usage of imported certificate. - * @param aTestCaseChain - * The test case entry point, which can be a function or a promise. - * - * @return A deferred promise. - */ - suite.doTestWithCertificate = function(certBlob, password, nickname, usage, aTestCaseChain) { - return suite.doTestWithoutStockAp(function() { - return ensureWifiEnabled(true) - // Import test certificate. - .then(() => importCert(certBlob, password, nickname)) - .then(function(info) { - // Check import result. - is(info.nickname, nickname, "Imported nickname"); - for (let i = 0; i < usage.length; i++) { - isnot(info.usage.indexOf(usage[i]), -1, "Usage " + usage[i]); - } - }) - // Get imported certificate list. - .then(getImportedCerts) - // Check if certificate exists in imported certificate list. - .then(function(list) { - for (let i = 0; i < usage.length; i++) { - isnot(list[usage[i]].indexOf(nickname), -1, - "Certificate \"" + nickname + "\" of usage " + usage[i] + " is imported"); - } - }) - // Run test case. - .then(aTestCaseChain) - // Delete imported certificates. - .then(() => deleteCert(nickname)) - // Check if certificate doesn't exist in imported certificate list. - .then(getImportedCerts) - .then(function(list) { - for (let i = 0; i < usage.length; i++) { - is(list[usage[i]].indexOf(nickname), -1, "Certificate is deleted"); - } - }) - }); - }; - - return suite; -})(); diff --git a/dom/wifi/test/marionette/manifest.ini b/dom/wifi/test/marionette/manifest.ini deleted file mode 100644 index 5d719e4b6..000000000 --- a/dom/wifi/test/marionette/manifest.ini +++ /dev/null @@ -1,22 +0,0 @@ -[DEFAULT] -run-if = buildapp == 'b2g' - -[test_wifi_enable.js] -[test_wifi_scan.js] -[test_wifi_associate.js] -[test_wifi_associate_wo_connect.js] -[test_wifi_auto_connect.js] -[test_wifi_static_ip.js] -[test_wifi_tethering_wifi_disabled.js] -[test_wifi_tethering_wifi_inactive.js] -[test_wifi_tethering_wifi_active.js] -[test_wifi_manage_server_certificate.js] -[test_wifi_manage_user_certificate.js] -[test_wifi_manage_pkcs12_certificate.js] -[test_wifi_associate_WPA_EAP_PEAP.js] -skip-if = android_version < '16' # EAP test not working before KK. -[test_wifi_associate_WPA_EAP_TTLS.js] -skip-if = android_version < '16' -[test_wifi_associate_WPA_EAP_TLS.js] -skip-if = android_version < '16' -[test_wifi_enable_api.js] diff --git a/dom/wifi/test/marionette/test_wifi_associate.js b/dom/wifi/test/marionette/test_wifi_associate.js deleted file mode 100644 index 0c00c583b..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate.js +++ /dev/null @@ -1,35 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -/** - * Convert the given MozWifiNetwork object array to testAssociate chain. - * - * @param aNetworks - * An array of MozWifiNetwork which we want to convert. - * - * @return A promise chain which "then"s testAssociate accordingly. - */ -function convertToTestAssociateChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - chain = chain.then(() => gTestSuite.testAssociate(aNetwork)); - }); - - return chain; -} - -gTestSuite.doTestWithoutStockAp(function() { - return gTestSuite.ensureWifiEnabled(true) - .then(() => gTestSuite.startHostapds(HOSTAPD_CONFIG_LIST)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', HOSTAPD_CONFIG_LIST.length)) - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, HOSTAPD_CONFIG_LIST)) - .then(networks => convertToTestAssociateChain(networks)) - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)); -}); diff --git a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_PEAP.js b/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_PEAP.js deleted file mode 100644 index ce53da2d7..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_PEAP.js +++ /dev/null @@ -1,623 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -const EAP_USERNAME = 'username'; -const EAP_PASSWORD = 'password'; - -const SERVER_EAP_USER_CONF = { - path: HOSTAPD_CONFIG_PATH + 'hostapd.eap_user', - content: '* PEAP,TTLS,TLS\n' + - '"' + EAP_USERNAME + '" MSCHAPV2,TTLS-MSCHAPV2 "' + EAP_PASSWORD + '" [2]\n' -}; -const CA_CERT = { - path: HOSTAPD_CONFIG_PATH + 'ca.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIIDsTCCApmgAwIBAgIJAKxTf+8X8qngMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV\n' + - 'BAYTAlRXMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTER\n' + - 'MA8GA1UEAwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdt\n' + - 'YWlsLmNvbTAgFw0xNDEyMjQxMTI4NTBaGA8yMjg4MTAwNzExMjg1MFowbjELMAkG\n' + - 'A1UEBhMCVFcxEzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAoMCGNodWNrbGVl\n' + - 'MREwDwYDVQQDDAhjaHVja2xlZTEkMCIGCSqGSIb3DQEJARYVY2h1Y2tsaTA3MDZA\n' + - 'Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3c2yFxY\n' + - 'o6gGg0I83jy00ME+MAfzCd+4ShL45ZLqysQP93jRBfPzU9ZuZ29ysVwgWIdqkZao\n' + - 'XTuV/NAW2GMGd8W1jQJ3J81fjb9wvhlny3rrACwvUn1N1S1BnM+BAAiDLGxEmvAQ\n' + - 'onp2aaa6HsHsYS8ONX+d2Qh4LEA4vupeSGAqJychCZv/l+aq/ErFZhFYB3CPUQEt\n' + - 'cClO24ucsIYP95lA0zhscnmAj06qplFD4Bv6IVrdDqujy1zNwCQwsJq/8OQdaTN/\n' + - 'h3y9pWvNKMBMM2niOUAjtuNpqsSK/lTS1WAT3PdtVECX9fYBi0Bg+HM92xs/6gt6\n' + - 'kh9jPV8keXHvSwIDAQABo1AwTjAdBgNVHQ4EFgQU7hBqhuG04xeCzrQ3ngx18ZJ3\n' + - 'lUswHwYDVR0jBBgwFoAU7hBqhuG04xeCzrQ3ngx18ZJ3lUswDAYDVR0TBAUwAwEB\n' + - '/zANBgkqhkiG9w0BAQsFAAOCAQEAFYX2iy680GAnBTttk0gyX6gk+8pYr3D22k/G\n' + - '6rvcjefzS7ELQPRKr6mfmwXq3mMf/4jiS2zI5zmXsestPYzHYxf2viQ6t7vr9XiJ\n' + - '3WfFjNw4ERlRisAvg0aqqTNNQq5v2VME4sdFZagy217f73C7azwCHl0bqOLH05rl\n' + - '8RubOxiHEj7ZybJqnRciK/bht4D+rZkwf4bBBmoloqH7xT0+rFQclpYXDGGjNUQB\n' + - 'LcHLF10xcr7g3ZVVu82fe6+d85gIGOIMR9+TKhdw6gO3CNcnDAj6gxksghgtcxmh\n' + - 'OzOggCn7nlIwImtsg2sZkpWB4lEi9hdv4lkNuyFjOL3bnuc+NA==\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_CERT = { - path: HOSTAPD_CONFIG_PATH + 'server.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIID1DCCArygAwIBAgIBADANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJUVzET\n' + - 'MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIY2h1Y2tsZWUxETAPBgNVBAMM\n' + - 'CGNodWNrbGVlMSQwIgYJKoZIhvcNAQkBFhVjaHVja2xpMDcwNkBnbWFpbC5jb20w\n' + - 'IBcNMTQxMjI0MTEyOTQ5WhgPMjI4ODEwMDcxMTI5NDlaMG4xCzAJBgNVBAYTAlRX\n' + - 'MRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTERMA8GA1UE\n' + - 'AwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdtYWlsLmNv\n' + - 'bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdhQmKilTJbWZRxTiSV\n' + - 'rqIU+LYW1RKghx5o+0JpNRJVLuz5kBMaNskbbfUSNuHbEq0QA9BDKAZWIc4LSotk\n' + - 'lCo8TbcO9CJvJPQGGjGdHcohWX5vy6BE/OVE46CUteMFyZF6F8R2fNUww08iR/u1\n' + - 'YZebL5pWO1j43sPpAzEy6Tij2ACPt6EZcFaZG3SF2mVJWkCQnBqrojP65WUvZQqp\n' + - 'seUhW2YAS8Nu0Yrohgxz6VYk+cNDuDZVGs6qWRStZzJfYrfc76DtkHof5B14M+xp\n' + - 'XJaBLxN+whvnYkDTfinaCxnW1O7eXUltr87fLc5zmeBkgwaiaQuIdcfZm7vDUiz8\n' + - 'vnUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH\n' + - 'ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKK4f9/YavTHOfEiAB83Deac\n' + - '6gT5MB8GA1UdIwQYMBaAFO4QaobhtOMXgs60N54MdfGSd5VLMA0GCSqGSIb3DQEB\n' + - 'CwUAA4IBAQBWnO9o9KSJIqjoz5Nwll63ULOdcvgGdOeJIw1fcKQ817Rsp+TVcjcH\n' + - 'IrIADsT/QZGXRO/l6p1750e2iFtJEo1hsRaxtA1wWn2I9HO3+av2spQhr3jpYGPf\n' + - 'zpsMTp4RNYV7Q8+q1kZIz9PY4V1T0p6lveK8+fUj2hSLnxSj0QiGSJJtnEC3w4Rv\n' + - 'C9T6oUwIeToULmi+8FXQFdEqwKRU98DPq3eLzN28ZxUgoPE1C8+42D2UW8uyp/Gm\n' + - 'tGOa/k7nzkCdVqZI7lX7f0AjEvQgjtAMQ/k7Mhxx7TzW2HO+1YPMoKji6Z4WkNwt\n' + - 'JEj9ZUBSNt8B26UksJMBDkcvSegF3a7o\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_KEY = { - path: HOSTAPD_CONFIG_PATH + 'server.key', - content: '-----BEGIN RSA PRIVATE KEY-----\n' + - 'MIIEpAIBAAKCAQEAx2FCYqKVMltZlHFOJJWuohT4thbVEqCHHmj7Qmk1ElUu7PmQ\n' + - 'Exo2yRtt9RI24dsSrRAD0EMoBlYhzgtKi2SUKjxNtw70Im8k9AYaMZ0dyiFZfm/L\n' + - 'oET85UTjoJS14wXJkXoXxHZ81TDDTyJH+7Vhl5svmlY7WPjew+kDMTLpOKPYAI+3\n' + - 'oRlwVpkbdIXaZUlaQJCcGquiM/rlZS9lCqmx5SFbZgBLw27RiuiGDHPpViT5w0O4\n' + - 'NlUazqpZFK1nMl9it9zvoO2Qeh/kHXgz7GlcloEvE37CG+diQNN+KdoLGdbU7t5d\n' + - 'SW2vzt8tznOZ4GSDBqJpC4h1x9mbu8NSLPy+dQIDAQABAoIBAASG4Mr8hgaurEoC\n' + - 'iJOsElr7vunjetMBcg/uskW/vcS8ymP3Bp5oafYG+WgnEbfvEW18f5mq7K24JuxW\n' + - 'tUqU7ghHdjxByqk9fMlNmiqmNpbwSufkAeuRpWxPNBvhRH/zEbCL5R5A0nTEtqqF\n' + - 'TL0aUSzwCRSoAJD0lZo9ICVt0n3GsDyM9rqQg/uZmh1qsRdwPsRuYORND9g48rKq\n' + - '6WN9leskSxhhsYE2D9ocOFd9bNt8Zxejh9ppVSnG/KsIdt18iBzcabatgAQ046fb\n' + - 'Z3vprcZJLg93Sg2gSuVqlSTs3M2W8VQnm22/EBMb1y0M48MSRCgnbPLG/CcCLLfF\n' + - 'LwxCOgECgYEA/eYt67xyJ6JeAdxdwOZuT1WWGbFpLiG9+2OgiHumyRQ5969XMTWo\n' + - 'fIhMKchDdjoy9RR236\/\/EFCs7UEyB7+a7ODRzNiK2zCD8Smjp+21fUPSthEeQesk\n' + - 'eiMYICIu5Ay35x9sxIX+XOUVvRhPOGcD29GVeRnKh1inTHOz2dje8LkCgYEAyQeY\n' + - 'STi9jjCEcHkM1E/UeDiLfHHepLXi8wS41JNRHl5Jacp7XB5djAjKu/jf367/VpFy\n' + - 'GDDMetE7n8eWkrnAvovxOwZ000YDMtL1sUYSjL+XtBS5s6VY1p4qaSAY9nUUGrJh\n' + - 'JvtvsuI7SKTtL+60vjBOH7zDnvOdBgAp0utLhZ0CgYEAuLzzqrPKB8afShFSchn4\n' + - 'J2dpuLYahsNsXW7HDqeR2nsKFosRETAusLXnXPtnAq4kB6jlOarwFqnsuRCX24Vx\n' + - 'r2uBm9/vYL7zMdUPTA+s30ErHuhjsKjsOKYyVqcooSwT32pBFNk+E89nutfmRG7I\n' + - 'IvhjHuNCNqqtx/Xj5d1jkZkCgYBQicppC2Jl5OoqZVTOem0U/RJk+PnJ41TZJ7sk\n' + - '7yBAmmWvDH\/\/l+rCf4M5a6vFYcbKV9rt9h711X2dtciNX/3oWQh8LUoAmrwNUJc+\n' + - 'PmSQHvIYI3WCk2vUD+nN1B4sHxu+1lg11eYaNKiroeeknG2tBI1ICcgVlmQCU25u\n' + - 'IfZPwQKBgQCdO6QHhPLtcHUDNFA6FQ1jKL1iEd7G0JLVRz4Xkpkn1Vrr5MD6JFDa\n' + - '5ccabADyl0lpFqDIVJQIzLku2hOD2i9aBNCY0pL391HeOS7CkZX+TdOY1tquoBq5\n' + - 'MnmixZjDCVd2VcrVyTA6ntOBoharKFW0rH1PqU+qu7dZF7CBPbAdEw==\n' + - '-----END RSA PRIVATE KEY-----\n' -}; - -const WPA_EAP_AP_LIST = [ - { - ssid: 'WPA-EAP-PEAP', - ieee8021x: 1, - eapol_version: 1, - eap_server: 1, - eapol_key_index_workaround: 0, - eap_user_file: SERVER_EAP_USER_CONF.path, - ca_cert: CA_CERT.path, - server_cert: SERVER_CERT.path, - private_key: SERVER_KEY.path, - wpa: 3, - wpa_key_mgmt: 'WPA-EAP' - } -]; - -const CLIENT_PKCS12_CERT = { - nickname: 'client', - password: 'password', - usage: ['UserCert', 'ServerCert'], - content: [0x30, 0x82, 0x0E, 0x01, 0x02, 0x01, 0x03, 0x30, - 0x82, 0x0D, 0xC7, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, - 0x0D, 0xB8, 0x04, 0x82, 0x0D, 0xB4, 0x30, 0x82, - 0x0D, 0xB0, 0x30, 0x82, 0x08, 0x67, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, - 0x06, 0xA0, 0x82, 0x08, 0x58, 0x30, 0x82, 0x08, - 0x54, 0x02, 0x01, 0x00, 0x30, 0x82, 0x08, 0x4D, - 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, - 0x06, 0x30, 0x0E, 0x04, 0x08, 0x67, 0x7A, 0xF3, - 0x61, 0xBE, 0xE0, 0x51, 0xC1, 0x02, 0x02, 0x08, - 0x00, 0x80, 0x82, 0x08, 0x20, 0xFC, 0x6A, 0x79, - 0xA1, 0x6C, 0xAF, 0xBE, 0xEE, 0x62, 0x45, 0x33, - 0xB8, 0x48, 0xE1, 0x68, 0xA1, 0x15, 0x11, 0x4B, - 0x95, 0xCB, 0x77, 0xC0, 0x5D, 0xA2, 0xCB, 0xDB, - 0xD1, 0x83, 0x74, 0x60, 0xD7, 0xEC, 0x42, 0xA6, - 0x3A, 0x23, 0xF7, 0x85, 0xEB, 0xC1, 0xFE, 0x6A, - 0x57, 0x8E, 0xC1, 0x44, 0xF3, 0x1F, 0xFE, 0xB8, - 0x2D, 0x8C, 0x4D, 0xC9, 0x5B, 0xAE, 0x21, 0x2E, - 0x4C, 0x1A, 0xEB, 0x84, 0x09, 0xF3, 0x40, 0x92, - 0x39, 0x7F, 0x56, 0x02, 0x46, 0x61, 0x16, 0xDE, - 0x5C, 0x48, 0xB6, 0x0C, 0x1D, 0xD3, 0x5F, 0x10, - 0x9A, 0x39, 0xB8, 0x66, 0x31, 0xFC, 0x39, 0x71, - 0x87, 0x23, 0x46, 0x9D, 0xE8, 0x3C, 0x2B, 0xA1, - 0x39, 0x8A, 0xD3, 0xFF, 0xD9, 0x43, 0xB6, 0x61, - 0xC6, 0x67, 0x70, 0x40, 0xBD, 0xFE, 0xD3, 0xC1, - 0x68, 0xF5, 0xF7, 0xC8, 0x89, 0xD8, 0x17, 0xC5, - 0xE8, 0x3D, 0x29, 0xD5, 0x91, 0xDF, 0x1F, 0x56, - 0x74, 0x5A, 0xC4, 0xA8, 0x14, 0xBA, 0xD4, 0xFA, - 0x13, 0x49, 0x2A, 0x9F, 0x63, 0xF1, 0xB2, 0x45, - 0xF1, 0xF0, 0x2A, 0xDD, 0x75, 0x66, 0x8A, 0xF7, - 0xAB, 0x73, 0x86, 0x26, 0x9D, 0x1F, 0x07, 0xAD, - 0xD3, 0xFE, 0xE0, 0xA3, 0xED, 0xA0, 0x96, 0x3E, - 0x1E, 0x89, 0x86, 0x02, 0x4C, 0x28, 0xFD, 0x57, - 0xA1, 0x67, 0x55, 0xF0, 0x82, 0x3B, 0x7F, 0xCC, - 0x2A, 0x32, 0x01, 0x93, 0x1D, 0x8B, 0x66, 0x8A, - 0x20, 0x52, 0x84, 0xDD, 0x2C, 0xFD, 0xEE, 0x72, - 0xF3, 0x8C, 0x58, 0xB9, 0x99, 0xE5, 0xC1, 0x22, - 0x63, 0x59, 0x00, 0xE2, 0x76, 0xC5, 0x3A, 0x17, - 0x7F, 0x93, 0xE9, 0x67, 0x61, 0xAA, 0x10, 0xC3, - 0xD9, 0xC8, 0x24, 0x46, 0x5B, 0xBE, 0x8C, 0x1F, - 0x2D, 0x66, 0x48, 0xD2, 0x02, 0x11, 0xFB, 0x74, - 0x14, 0x76, 0x76, 0x5A, 0x98, 0x54, 0x35, 0xA7, - 0x85, 0x66, 0x20, 0x26, 0x8B, 0x13, 0x6F, 0x68, - 0xE3, 0xC9, 0x58, 0x7D, 0x1C, 0x3E, 0x01, 0x8D, - 0xF8, 0xD6, 0x7F, 0xCF, 0xA2, 0x07, 0xB7, 0x95, - 0xFD, 0xF0, 0x02, 0x34, 0x32, 0x30, 0xE8, 0xD4, - 0x57, 0x5E, 0x53, 0xFB, 0x54, 0xE2, 0x03, 0x32, - 0xCC, 0x52, 0x2E, 0xD2, 0x35, 0xD9, 0x58, 0x85, - 0x2D, 0xEC, 0x2D, 0x71, 0xD1, 0x8A, 0x29, 0xD0, - 0xB0, 0x24, 0xBD, 0x24, 0xDC, 0x1A, 0x28, 0x3F, - 0xA0, 0x12, 0x81, 0x15, 0x24, 0xC9, 0xB5, 0x4A, - 0x23, 0xB6, 0xA3, 0x45, 0x50, 0x2D, 0x73, 0x99, - 0x6B, 0x1C, 0xFB, 0xA4, 0x53, 0xD7, 0x5C, 0xF4, - 0x6C, 0xB0, 0xE5, 0x74, 0xB3, 0x76, 0xF8, 0xB1, - 0x0D, 0x59, 0x70, 0x9F, 0xCA, 0xDE, 0xF2, 0xAA, - 0x4C, 0x7D, 0x11, 0x54, 0xC4, 0x19, 0x0F, 0x36, - 0x4A, 0x62, 0xFF, 0x8B, 0x10, 0xCB, 0x93, 0x50, - 0xDA, 0x79, 0x5E, 0x4E, 0x09, 0x1F, 0x22, 0xC8, - 0x19, 0x85, 0xE9, 0xEE, 0xB7, 0x71, 0x65, 0xB9, - 0x10, 0xD2, 0x0A, 0x73, 0x5B, 0xA6, 0xDA, 0x37, - 0x46, 0x02, 0x00, 0x98, 0x9E, 0x20, 0x6C, 0x7D, - 0xC7, 0x69, 0xBB, 0xC2, 0x00, 0x40, 0x9C, 0x57, - 0x00, 0xC2, 0x36, 0x76, 0xE8, 0x2A, 0x8D, 0xAD, - 0x62, 0x57, 0xC8, 0xD0, 0x9D, 0x66, 0x27, 0x5A, - 0xD8, 0x0D, 0x35, 0x60, 0x28, 0x38, 0x62, 0x94, - 0x78, 0x36, 0x25, 0x58, 0xFD, 0xF8, 0x66, 0x1F, - 0x68, 0x04, 0x0F, 0xD8, 0x00, 0xDF, 0xA0, 0x6C, - 0x25, 0x42, 0x9A, 0x4C, 0xEB, 0x80, 0x13, 0x51, - 0x7D, 0x2D, 0xA8, 0x89, 0xD6, 0x1B, 0x67, 0x72, - 0x01, 0xF3, 0x2D, 0x16, 0x77, 0xFE, 0x22, 0xBC, - 0x8A, 0x45, 0x09, 0x1F, 0x9C, 0x2F, 0x2A, 0xA9, - 0x61, 0x5B, 0x4A, 0xE6, 0x64, 0x2C, 0x62, 0x1A, - 0x3A, 0x96, 0xE6, 0x0A, 0xAE, 0x05, 0x1A, 0xC8, - 0xCB, 0xD6, 0x8F, 0x3A, 0x4B, 0xE0, 0x7F, 0x82, - 0xB4, 0x98, 0xF1, 0x9D, 0xD7, 0x14, 0x76, 0x5E, - 0x77, 0x85, 0x87, 0xEC, 0x13, 0xDA, 0xFD, 0xAF, - 0xCB, 0xA3, 0x1C, 0x99, 0xC1, 0xFE, 0x17, 0x0C, - 0x40, 0x4D, 0x3C, 0x8F, 0x70, 0x86, 0x63, 0x64, - 0xB7, 0x75, 0xA8, 0x71, 0x36, 0xDC, 0x54, 0x10, - 0x57, 0x0C, 0xA8, 0xF2, 0xA1, 0xBB, 0xED, 0x03, - 0x41, 0x57, 0x34, 0x2C, 0x8F, 0x7C, 0xA0, 0x09, - 0xF3, 0x9E, 0x41, 0xB7, 0xA8, 0xD4, 0x66, 0x0D, - 0x0D, 0xC0, 0x6A, 0xFC, 0x6A, 0xA2, 0xAC, 0xE2, - 0x60, 0x00, 0xE3, 0xF7, 0x75, 0x43, 0x23, 0xEB, - 0xC8, 0x61, 0xFA, 0xB3, 0xB8, 0x28, 0xCE, 0xCA, - 0xF4, 0x47, 0x7F, 0x30, 0x6D, 0x61, 0x89, 0x47, - 0xA1, 0x4A, 0xFE, 0xD1, 0x21, 0x0B, 0x6D, 0xF4, - 0x3F, 0x00, 0x86, 0x30, 0x8E, 0x33, 0x21, 0x6F, - 0xDA, 0x15, 0xFD, 0x5F, 0xEC, 0x8E, 0xF1, 0x12, - 0x3F, 0xC9, 0x83, 0x0C, 0xCA, 0x22, 0x01, 0xF1, - 0x70, 0x5F, 0x1F, 0x66, 0xB5, 0xF8, 0x3E, 0x7A, - 0x6F, 0xDE, 0xDB, 0xA7, 0x8D, 0x18, 0x9E, 0xBE, - 0xDB, 0xAD, 0x3D, 0x66, 0x30, 0xC1, 0x6C, 0x0C, - 0x87, 0xB4, 0x65, 0x75, 0xE0, 0x9D, 0xEA, 0x16, - 0x0D, 0x07, 0x37, 0x33, 0xC5, 0xEC, 0x97, 0x93, - 0x37, 0xEB, 0x8E, 0x65, 0x9C, 0x40, 0x63, 0x6C, - 0x43, 0x60, 0xB0, 0x40, 0x4D, 0x85, 0xEF, 0xC2, - 0x47, 0x5F, 0xE7, 0x6B, 0xCB, 0x40, 0xE8, 0xEA, - 0xD8, 0xAB, 0xB1, 0x9A, 0x72, 0xDC, 0x4C, 0x14, - 0xFA, 0x43, 0x61, 0x5F, 0xA6, 0x5C, 0x3A, 0x05, - 0x17, 0x2E, 0x74, 0xF3, 0x5E, 0x45, 0xD9, 0x47, - 0xAA, 0x59, 0xB6, 0x8F, 0x42, 0x66, 0x42, 0x29, - 0x90, 0x95, 0x48, 0x46, 0x91, 0x88, 0x3C, 0x8C, - 0xDE, 0xCC, 0xED, 0xB3, 0xAA, 0x62, 0xEA, 0xBC, - 0xB4, 0x0C, 0x48, 0x4C, 0x53, 0x23, 0x5E, 0x24, - 0x85, 0xBF, 0x92, 0xDA, 0x14, 0xDB, 0x1A, 0x3D, - 0xEF, 0x30, 0xD9, 0x49, 0x64, 0x4D, 0xE5, 0x01, - 0xFC, 0xA4, 0x4B, 0xD1, 0x9F, 0xDE, 0x96, 0x7F, - 0x50, 0xBC, 0x4D, 0x38, 0x44, 0xE9, 0x23, 0x5F, - 0x37, 0x57, 0x1A, 0xA6, 0x52, 0x5A, 0x0F, 0x4F, - 0x87, 0x33, 0x4A, 0x7B, 0x66, 0xEE, 0x3D, 0x66, - 0x0A, 0x63, 0x39, 0x1F, 0x23, 0x38, 0x35, 0x73, - 0x60, 0x5E, 0x47, 0x20, 0x4F, 0xC0, 0xC8, 0x3C, - 0x09, 0xF9, 0x29, 0x4F, 0x5E, 0x55, 0x69, 0xC4, - 0x6B, 0xE8, 0xF8, 0x91, 0xC0, 0x22, 0x65, 0x15, - 0x1E, 0xFB, 0xB9, 0x61, 0xCE, 0x45, 0xBE, 0x2B, - 0xEE, 0xB9, 0x04, 0x2B, 0xFD, 0xAE, 0x61, 0x1C, - 0x3D, 0x3D, 0x7C, 0xBF, 0xC1, 0xF7, 0x3C, 0x4E, - 0x9E, 0x0E, 0x54, 0xC8, 0xAD, 0xA9, 0xDF, 0x43, - 0x49, 0xB9, 0x41, 0x05, 0xE5, 0xF1, 0x49, 0xAA, - 0x77, 0x6C, 0x34, 0x5B, 0x93, 0x24, 0x24, 0x23, - 0x74, 0x68, 0x11, 0xCE, 0x15, 0x80, 0xA1, 0xA4, - 0x1F, 0x8D, 0x81, 0xCD, 0xB2, 0x98, 0xCA, 0x14, - 0x0B, 0x0C, 0x61, 0x50, 0x69, 0x72, 0xAE, 0xFA, - 0x8B, 0xC0, 0x3F, 0x0D, 0xE7, 0xF2, 0x0F, 0xEB, - 0xC1, 0x11, 0xB9, 0x10, 0x03, 0x6A, 0xF5, 0x97, - 0x3C, 0x53, 0x2F, 0x67, 0x86, 0x09, 0x6A, 0xE3, - 0x28, 0xC0, 0x78, 0xC8, 0xB4, 0x39, 0x8E, 0xD1, - 0xCE, 0x25, 0xE8, 0x66, 0xF7, 0x09, 0x40, 0x7D, - 0x81, 0xFB, 0xAF, 0xFA, 0x59, 0xC4, 0x9B, 0x2B, - 0x83, 0x45, 0x5B, 0xA8, 0x66, 0x9E, 0x38, 0xC8, - 0xFD, 0xAC, 0xF2, 0x2D, 0x21, 0xDE, 0x50, 0x4C, - 0x03, 0xCB, 0x88, 0x42, 0xDD, 0x84, 0x09, 0x99, - 0x8E, 0x8B, 0x40, 0x97, 0x1B, 0x14, 0x85, 0x37, - 0x11, 0x01, 0xE0, 0x74, 0x6B, 0x33, 0x52, 0x8C, - 0x68, 0x3A, 0x89, 0xB2, 0xAF, 0x35, 0xE6, 0x65, - 0xC3, 0x58, 0x70, 0xD2, 0xE7, 0x1F, 0x1F, 0xF6, - 0xE5, 0x0A, 0xB1, 0xFE, 0xD0, 0xC9, 0x51, 0x50, - 0xE7, 0xFD, 0x58, 0xF5, 0xC4, 0x58, 0x65, 0x94, - 0xD1, 0x57, 0x55, 0x5E, 0xD2, 0x27, 0x98, 0xAF, - 0xE7, 0x55, 0x0B, 0x87, 0x50, 0x9B, 0xEF, 0xE8, - 0x2B, 0xFC, 0xE7, 0x3B, 0x4E, 0xD7, 0xB7, 0x4D, - 0xF4, 0xBC, 0xF4, 0x88, 0x63, 0xE4, 0x8A, 0x20, - 0x4B, 0x22, 0xB0, 0xA0, 0x53, 0x7F, 0xA8, 0xC9, - 0x0C, 0xF8, 0xD7, 0xBD, 0x46, 0x39, 0xA7, 0x7D, - 0xDD, 0x10, 0x91, 0x50, 0x54, 0x06, 0x47, 0xF0, - 0x3C, 0xAA, 0x43, 0x40, 0xF8, 0x54, 0xDD, 0x8A, - 0xEA, 0x8A, 0x0B, 0xA5, 0x7F, 0xCD, 0x5E, 0xAA, - 0x02, 0x2E, 0x1F, 0xC6, 0x50, 0x15, 0xF8, 0x0A, - 0x0C, 0x1B, 0x3C, 0x55, 0x3A, 0xC3, 0x6F, 0x88, - 0xD7, 0xBF, 0xB1, 0x02, 0xCC, 0xE0, 0x08, 0x29, - 0x97, 0xD2, 0xAA, 0x23, 0xC4, 0x6D, 0xE3, 0xE3, - 0x76, 0x39, 0x92, 0xC3, 0x2E, 0x7A, 0xE2, 0x98, - 0xD1, 0xFC, 0xAE, 0xCC, 0x95, 0xD8, 0xB4, 0xDC, - 0x92, 0xEA, 0x6A, 0x5F, 0xF2, 0x92, 0x17, 0x0B, - 0x8D, 0xC3, 0xFA, 0x9C, 0x62, 0xCE, 0x44, 0x8D, - 0xC3, 0x1E, 0xC3, 0xB2, 0xD5, 0x00, 0xCD, 0xB4, - 0x9E, 0x2D, 0x7B, 0xF2, 0x98, 0xA3, 0x00, 0x8B, - 0x81, 0x30, 0x77, 0x5B, 0x02, 0x99, 0xB1, 0xCD, - 0xC3, 0x1D, 0x74, 0x74, 0xEF, 0x41, 0xCB, 0x69, - 0x63, 0x8E, 0xA6, 0xD3, 0x2D, 0x3E, 0x1F, 0x1D, - 0x12, 0x9E, 0xD9, 0x18, 0x67, 0x06, 0xAF, 0x37, - 0x29, 0xAD, 0x65, 0xD8, 0xEB, 0x71, 0xC4, 0x7D, - 0x94, 0x3D, 0xEA, 0xCC, 0xDF, 0x72, 0x41, 0x51, - 0x3C, 0xA1, 0x66, 0x98, 0x32, 0x32, 0x40, 0x54, - 0xB0, 0x2F, 0xEB, 0xCE, 0xDF, 0x4A, 0x64, 0xFB, - 0x9A, 0x90, 0xDC, 0xF6, 0x6F, 0xA9, 0xD4, 0xCA, - 0xCB, 0x91, 0xC4, 0xFE, 0xEE, 0x9C, 0x01, 0x50, - 0x2E, 0xAC, 0xCC, 0x5F, 0x89, 0xD0, 0x91, 0xA3, - 0xD9, 0xF9, 0x4B, 0x8D, 0xDE, 0x6C, 0x60, 0x21, - 0x19, 0xB1, 0xD3, 0x4D, 0x75, 0x56, 0x6F, 0xB8, - 0x25, 0xA4, 0x92, 0x4F, 0x12, 0xF5, 0x8F, 0xC1, - 0x17, 0x4B, 0xB3, 0x34, 0x21, 0x22, 0xAC, 0x52, - 0xD2, 0x64, 0xC9, 0x9A, 0x7D, 0xFC, 0xC0, 0x0A, - 0x89, 0x34, 0xFF, 0x08, 0xD3, 0x04, 0xDC, 0xFE, - 0x7C, 0xB3, 0xB8, 0xFD, 0x85, 0xDD, 0x79, 0x51, - 0xA7, 0x89, 0xE8, 0xF1, 0x23, 0xB1, 0xDF, 0xD7, - 0x1F, 0x7B, 0xB1, 0x5D, 0x42, 0xF9, 0x61, 0xF8, - 0xDC, 0x81, 0x04, 0xF1, 0xCC, 0xFA, 0xD7, 0xED, - 0xBF, 0x47, 0xAC, 0xBD, 0xE5, 0xFA, 0xAC, 0xB3, - 0x1C, 0xD9, 0xA1, 0xB3, 0x60, 0xEE, 0x9C, 0x8A, - 0x36, 0x57, 0xB4, 0x2F, 0xA1, 0xA2, 0xF3, 0xE2, - 0x09, 0x9A, 0x6E, 0x43, 0x9B, 0xE5, 0x93, 0xB8, - 0x3D, 0x9E, 0x9F, 0xC1, 0xC6, 0x0D, 0x02, 0xEB, - 0x4D, 0x38, 0xE9, 0xB4, 0x9F, 0xEA, 0x33, 0x8C, - 0x07, 0xD8, 0xB4, 0x71, 0xAD, 0xE5, 0x43, 0xB2, - 0xCC, 0x55, 0x93, 0x6A, 0xDB, 0x1E, 0x80, 0xDB, - 0xC2, 0xEA, 0x42, 0x8E, 0xFC, 0x86, 0x44, 0xC9, - 0x8A, 0xC4, 0xF2, 0x46, 0xA7, 0x39, 0x50, 0x0D, - 0x1A, 0xAA, 0x07, 0x04, 0xBE, 0xD4, 0xCE, 0x62, - 0x4D, 0x0F, 0x91, 0x7D, 0x29, 0x88, 0x9C, 0x4C, - 0xAF, 0xF7, 0xD8, 0x40, 0x93, 0x88, 0xC7, 0x20, - 0xD2, 0x17, 0x2A, 0xC4, 0x92, 0x72, 0xD0, 0xC0, - 0x4E, 0x56, 0x47, 0xB1, 0x27, 0x02, 0xE6, 0x61, - 0x82, 0x5E, 0xC8, 0x2E, 0x90, 0xD2, 0x31, 0x22, - 0xE2, 0xA9, 0x4A, 0x91, 0x45, 0x69, 0xB1, 0xA5, - 0x0F, 0x66, 0x2C, 0x30, 0xAD, 0x7F, 0x1B, 0x0E, - 0x22, 0x17, 0x60, 0x2E, 0x3D, 0x7F, 0x7F, 0x8C, - 0x33, 0x51, 0xA0, 0x25, 0xDE, 0xFD, 0x75, 0xBC, - 0xEF, 0xE6, 0xE7, 0x20, 0x04, 0x5A, 0xEC, 0x50, - 0x21, 0x48, 0x56, 0x98, 0xE2, 0x33, 0x6D, 0x22, - 0x5C, 0xC3, 0xFB, 0xFC, 0x6F, 0xB3, 0xA7, 0x8E, - 0x6F, 0x67, 0x70, 0x9D, 0xDA, 0x02, 0x01, 0x59, - 0x7B, 0x3D, 0x2B, 0x38, 0xCC, 0x0F, 0x44, 0x3D, - 0xFB, 0x9A, 0xB3, 0x23, 0x15, 0x50, 0x6E, 0xBF, - 0x8B, 0xA1, 0x94, 0x33, 0xE5, 0x7B, 0x88, 0x4E, - 0xCB, 0x6D, 0x9F, 0xBF, 0xBC, 0x7A, 0xA8, 0x1E, - 0x68, 0x25, 0xED, 0x8E, 0x53, 0x21, 0x72, 0xC5, - 0x70, 0xB3, 0xE4, 0xA6, 0xA1, 0x5A, 0x2D, 0xC8, - 0x43, 0x9D, 0x60, 0x77, 0x78, 0xE0, 0xC4, 0xAF, - 0xC8, 0x29, 0xBA, 0xD0, 0x4D, 0x39, 0x83, 0x51, - 0xA7, 0x10, 0x7F, 0x0C, 0x34, 0x0E, 0x6C, 0x75, - 0x26, 0xD7, 0xD6, 0xC7, 0x32, 0x53, 0xAF, 0x4E, - 0xBE, 0xF2, 0xC2, 0x0F, 0x99, 0x23, 0xB9, 0xE1, - 0xC8, 0xB4, 0xBC, 0x5A, 0xC6, 0xCB, 0xEB, 0x4D, - 0x28, 0x56, 0x72, 0xFE, 0x1B, 0x2C, 0x5D, 0xE3, - 0xBC, 0xC7, 0xA3, 0xC0, 0x7D, 0x27, 0xF0, 0xD0, - 0x4F, 0x3F, 0x1F, 0xF7, 0x87, 0x15, 0xF2, 0xEA, - 0xD4, 0x03, 0x6D, 0x2F, 0xD4, 0x8E, 0x50, 0x4B, - 0x05, 0xBF, 0xF7, 0x8C, 0x67, 0x5A, 0xDC, 0x4D, - 0xCD, 0xCF, 0x9D, 0x02, 0xB6, 0xE7, 0xAE, 0x49, - 0xD1, 0x7C, 0x00, 0xE7, 0x3B, 0xEA, 0xFB, 0x0D, - 0x2A, 0x7B, 0x41, 0x33, 0x66, 0xD0, 0x29, 0x9F, - 0xB3, 0x8A, 0x71, 0xB0, 0xE2, 0x76, 0xA9, 0xDB, - 0xFD, 0x64, 0x04, 0x69, 0xDF, 0x89, 0x1F, 0x56, - 0x86, 0x92, 0xD9, 0xD9, 0xB9, 0xF3, 0x4F, 0xAC, - 0xAE, 0x61, 0x48, 0x20, 0xCE, 0x3C, 0x2B, 0x44, - 0xAB, 0x42, 0xFA, 0xAB, 0x2E, 0x94, 0x82, 0xC8, - 0xD9, 0x97, 0xCF, 0x27, 0xDF, 0xAC, 0xAC, 0xE7, - 0xCA, 0xB2, 0x84, 0xAB, 0xF2, 0x5D, 0xDF, 0x56, - 0x0C, 0x8C, 0x07, 0x3C, 0x3D, 0xA8, 0xDD, 0xBE, - 0xFF, 0x4E, 0x28, 0x0D, 0xB2, 0x2D, 0xE6, 0x9D, - 0x44, 0x21, 0xCB, 0xE7, 0x33, 0x63, 0x22, 0x8F, - 0x4C, 0xFF, 0xB6, 0x1D, 0x9A, 0x71, 0x3F, 0xB1, - 0x29, 0xAE, 0x3A, 0x35, 0xEE, 0x9C, 0x97, 0x68, - 0xA7, 0x52, 0x66, 0x01, 0xD8, 0x9A, 0x5D, 0xF4, - 0xB3, 0x2F, 0x5C, 0xD4, 0x0E, 0xF9, 0xCF, 0x07, - 0xF6, 0x8C, 0xBA, 0xA6, 0x8D, 0x6B, 0xC6, 0x01, - 0xC2, 0x69, 0xAE, 0x60, 0x08, 0x1A, 0x0E, 0x3F, - 0xAE, 0x60, 0x29, 0xF3, 0x48, 0x0D, 0xE0, 0xD0, - 0xAE, 0x52, 0x44, 0xE9, 0x7F, 0x1F, 0x92, 0x5F, - 0x71, 0xAD, 0xEC, 0x6B, 0x47, 0x66, 0x92, 0x22, - 0x27, 0xAE, 0x6E, 0x25, 0xCD, 0xF3, 0x5F, 0x55, - 0x59, 0xBD, 0x73, 0xCE, 0x2B, 0x7E, 0x99, 0x44, - 0x56, 0x70, 0xA3, 0xE7, 0x7A, 0x59, 0x75, 0xD8, - 0x48, 0x0C, 0x39, 0x2B, 0xD7, 0x53, 0xC6, 0xAD, - 0x4A, 0x6F, 0xB4, 0x14, 0x96, 0xDF, 0xF2, 0x4A, - 0x0C, 0xA2, 0xD5, 0x29, 0x98, 0x7C, 0x42, 0x87, - 0xD9, 0x1F, 0x97, 0x61, 0xD9, 0xBF, 0x99, 0x4F, - 0x2C, 0x4C, 0x75, 0xAC, 0xB8, 0x06, 0x75, 0xD6, - 0x87, 0x76, 0x7E, 0xE3, 0x23, 0x4B, 0xEA, 0x1A, - 0x1A, 0xF4, 0xB7, 0x09, 0xAF, 0x53, 0xEB, 0xA6, - 0x39, 0x10, 0xFE, 0xD4, 0xEB, 0x1B, 0xAE, 0x38, - 0x31, 0x33, 0xBA, 0x68, 0xEE, 0xC7, 0x65, 0x76, - 0xFB, 0x49, 0x77, 0xD4, 0x19, 0xC4, 0xE6, 0xA7, - 0x05, 0xFE, 0x2A, 0xDA, 0x39, 0x99, 0x1A, 0x92, - 0xD2, 0xF0, 0x61, 0x97, 0xF6, 0x06, 0x6C, 0x88, - 0x7B, 0x6F, 0x60, 0xE6, 0x70, 0x08, 0xF0, 0xB4, - 0x6B, 0x39, 0x6F, 0x05, 0x41, 0x81, 0xF9, 0xBE, - 0x7A, 0x51, 0xC4, 0x75, 0xB0, 0x6A, 0x89, 0xA0, - 0xA6, 0x9A, 0x5B, 0xEE, 0x7D, 0x78, 0x17, 0x5F, - 0x9F, 0x3B, 0x7D, 0xDD, 0x8A, 0x9E, 0xAA, 0x1A, - 0xDA, 0x49, 0x08, 0xE9, 0xFD, 0x91, 0xA6, 0xFA, - 0xCE, 0xCF, 0x67, 0xDF, 0x0F, 0xC9, 0xD6, 0x38, - 0xD9, 0xD5, 0xD1, 0xC0, 0x76, 0x59, 0x42, 0x53, - 0xBF, 0x48, 0xE9, 0x11, 0x74, 0xC7, 0x11, 0xD8, - 0xE7, 0x8E, 0xD3, 0xC8, 0x25, 0xA1, 0x26, 0x50, - 0xBB, 0xB4, 0x35, 0xAF, 0xAF, 0x06, 0x23, 0x69, - 0x3E, 0x30, 0xFD, 0x7B, 0x34, 0x83, 0x07, 0xD0, - 0xF0, 0x0F, 0x6C, 0x9A, 0x13, 0x5D, 0xC2, 0x7B, - 0xDF, 0x6F, 0xDD, 0x8E, 0xF4, 0x30, 0x82, 0x05, - 0x41, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x05, 0x32, - 0x04, 0x82, 0x05, 0x2E, 0x30, 0x82, 0x05, 0x2A, - 0x30, 0x82, 0x05, 0x26, 0x06, 0x0B, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, - 0x02, 0xA0, 0x82, 0x04, 0xEE, 0x30, 0x82, 0x04, - 0xEA, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, - 0x0E, 0x04, 0x08, 0x74, 0xC0, 0x84, 0x8F, 0xC7, - 0x74, 0x5E, 0x21, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x04, 0xC8, 0x1E, 0xF4, 0xE9, 0x07, 0x27, - 0x9E, 0x5A, 0xC9, 0x39, 0x1D, 0x37, 0x2C, 0x06, - 0x4B, 0x57, 0xEA, 0xC5, 0x42, 0x9A, 0x60, 0xD5, - 0x42, 0xB2, 0x34, 0x2D, 0xD3, 0x88, 0x7C, 0x78, - 0x87, 0xB6, 0xE9, 0x42, 0x44, 0x1F, 0x67, 0x32, - 0x92, 0x54, 0x22, 0xDA, 0xB2, 0x43, 0xE7, 0x40, - 0xBE, 0x1F, 0xAF, 0x3A, 0xCD, 0x2A, 0x9F, 0xD7, - 0x44, 0x5B, 0x37, 0x69, 0x85, 0xDF, 0xEB, 0x2A, - 0xB9, 0xE2, 0x92, 0x3B, 0xEA, 0xD5, 0x42, 0x53, - 0x95, 0x4A, 0xB0, 0x1B, 0xA5, 0xEF, 0xA6, 0x0D, - 0x29, 0xF4, 0x33, 0xFE, 0xD7, 0x49, 0x04, 0x1E, - 0x8C, 0xAD, 0x63, 0x1E, 0x79, 0x63, 0x74, 0x0C, - 0xE5, 0x5E, 0xA2, 0x2C, 0xBE, 0xB8, 0x90, 0xCE, - 0x06, 0x25, 0xBF, 0xD1, 0x5A, 0x50, 0xCF, 0x3B, - 0x52, 0xE2, 0xA7, 0xFF, 0x19, 0x02, 0xCF, 0xD0, - 0x9B, 0xD9, 0xF7, 0x28, 0x07, 0x38, 0x1F, 0xF2, - 0xAF, 0x44, 0x91, 0x3F, 0x0F, 0xB6, 0x6E, 0x8C, - 0xC0, 0x32, 0x92, 0xC0, 0xCD, 0x25, 0x98, 0x67, - 0xF1, 0x47, 0x52, 0x50, 0xF0, 0xA3, 0x7B, 0xE6, - 0x74, 0xDC, 0x72, 0x28, 0xC8, 0xAB, 0xB3, 0x31, - 0x7D, 0xA3, 0xF7, 0xC7, 0xD1, 0xE6, 0x99, 0xB4, - 0xB6, 0x5A, 0x3A, 0x4D, 0x83, 0x4F, 0xB8, 0xB5, - 0x86, 0xF8, 0x37, 0x7F, 0xA0, 0x16, 0x2F, 0x3C, - 0x62, 0x7A, 0xD4, 0x3A, 0xEB, 0xC2, 0xE8, 0x03, - 0x49, 0x17, 0x9E, 0xFB, 0xD7, 0xAF, 0x91, 0x32, - 0xFD, 0xEA, 0x4F, 0x64, 0xC6, 0x6E, 0x02, 0xEA, - 0xC4, 0xC8, 0x1F, 0x16, 0xC5, 0x4C, 0xFB, 0xC5, - 0x42, 0xF5, 0x85, 0x05, 0x92, 0x59, 0x4B, 0x31, - 0xE5, 0xE9, 0x69, 0xE7, 0x02, 0x98, 0x33, 0xBA, - 0x4C, 0x17, 0x09, 0xEF, 0x89, 0x20, 0xFA, 0x83, - 0x9F, 0xAE, 0x0E, 0x1B, 0x7D, 0x98, 0xB9, 0xF2, - 0x3C, 0x0F, 0xB7, 0x1C, 0x72, 0xDF, 0x17, 0x84, - 0x7F, 0x0A, 0xFD, 0x12, 0x3C, 0x6F, 0x68, 0x5D, - 0x45, 0xEB, 0xB8, 0xD6, 0x24, 0x65, 0x42, 0x75, - 0x5C, 0xC2, 0xF3, 0x3A, 0x6A, 0x4E, 0x51, 0x34, - 0x1B, 0xB6, 0x81, 0xB2, 0x8A, 0xEF, 0x28, 0xA4, - 0xC5, 0x88, 0x9A, 0x97, 0xE0, 0xEF, 0x31, 0x12, - 0x01, 0x7E, 0x1B, 0x43, 0x0F, 0x27, 0x80, 0x87, - 0x98, 0xC5, 0xD5, 0x83, 0xCB, 0x4B, 0xB7, 0x01, - 0x79, 0x60, 0xA1, 0x1A, 0x03, 0x05, 0xC6, 0x36, - 0x04, 0x31, 0x3C, 0x06, 0xDB, 0x08, 0xA8, 0xDA, - 0x8E, 0x32, 0x19, 0x91, 0xF1, 0x0D, 0x61, 0x6F, - 0xE4, 0xB2, 0x79, 0x8A, 0xDE, 0xF4, 0xF7, 0xFB, - 0x2C, 0x23, 0x5B, 0xD9, 0x64, 0x2F, 0xB7, 0xB3, - 0x8B, 0xCA, 0xB8, 0x8C, 0x1D, 0x3B, 0x49, 0x05, - 0x38, 0xA1, 0xE5, 0x8C, 0x1A, 0xDC, 0xA5, 0x61, - 0xFE, 0xF4, 0x2B, 0xDC, 0x77, 0x28, 0xF6, 0x19, - 0xE7, 0xB7, 0x8F, 0x4D, 0x27, 0x2D, 0xED, 0x8A, - 0x3F, 0x3D, 0xDC, 0x9F, 0xD1, 0x30, 0xFF, 0xD6, - 0xC3, 0xBE, 0x41, 0x25, 0xE3, 0xA5, 0x9B, 0x73, - 0xDF, 0x6A, 0xD9, 0xF9, 0x70, 0x84, 0x02, 0x4C, - 0x35, 0xD4, 0x3E, 0x05, 0x76, 0x3A, 0xDC, 0x6D, - 0x5A, 0x81, 0xB3, 0x94, 0xF7, 0x22, 0xF7, 0xDC, - 0xC1, 0x43, 0x31, 0x57, 0x5B, 0x42, 0x9A, 0x0B, - 0xF4, 0x95, 0x30, 0xA9, 0xBB, 0xD8, 0x06, 0xFB, - 0x1D, 0x6F, 0x9B, 0xC3, 0xBB, 0xF3, 0xBF, 0xFB, - 0xB4, 0x9F, 0x35, 0x64, 0x0A, 0x69, 0xB7, 0xD1, - 0x3E, 0xCA, 0x78, 0x07, 0x04, 0x03, 0x79, 0xD4, - 0xF3, 0xA8, 0xEC, 0x18, 0xDB, 0x03, 0x5E, 0x47, - 0xD7, 0xD0, 0x56, 0x2C, 0x74, 0x94, 0x86, 0x04, - 0x46, 0xB8, 0xD4, 0x35, 0x0A, 0x7B, 0xE6, 0x78, - 0xC4, 0x43, 0x3C, 0x56, 0xCC, 0x37, 0x8B, 0xFD, - 0xE8, 0xF4, 0x57, 0xEA, 0xAE, 0xCF, 0x36, 0x97, - 0x12, 0xAC, 0x39, 0xCF, 0x7C, 0xEF, 0x22, 0x67, - 0x01, 0xEC, 0xD8, 0x09, 0x49, 0x4E, 0xE3, 0x74, - 0xDD, 0x39, 0xE1, 0x39, 0xD7, 0x0C, 0x5F, 0x1B, - 0xCE, 0x69, 0xBC, 0x72, 0x44, 0x87, 0x64, 0x1C, - 0x08, 0x05, 0x93, 0x69, 0x6D, 0x7F, 0x90, 0x0A, - 0x2C, 0xCB, 0x8A, 0xBB, 0x7F, 0xE3, 0xE0, 0x80, - 0x31, 0xD0, 0x0A, 0x3A, 0x95, 0xFF, 0xF7, 0xB4, - 0x36, 0x38, 0x93, 0xE0, 0x0C, 0x11, 0x37, 0x12, - 0x06, 0xF6, 0xAD, 0xE9, 0xB1, 0x7A, 0x00, 0xF5, - 0xD2, 0x32, 0x6B, 0xD0, 0x27, 0xA5, 0x1B, 0x3D, - 0xE8, 0xDB, 0xCC, 0xA9, 0x1F, 0x1F, 0xB1, 0x99, - 0x3D, 0x7C, 0xB7, 0xCA, 0xDA, 0x27, 0x2C, 0x64, - 0x1C, 0x49, 0xB6, 0x87, 0x44, 0x06, 0x94, 0x9D, - 0xBC, 0x6B, 0x20, 0xA2, 0x68, 0x15, 0x1F, 0xE2, - 0xF2, 0xAD, 0x6D, 0x23, 0x2E, 0x2B, 0x74, 0xE2, - 0x5D, 0xE4, 0xB0, 0xC7, 0x84, 0xCB, 0x64, 0xBF, - 0xE0, 0xA8, 0x18, 0x83, 0xB4, 0xC9, 0xD9, 0x73, - 0xA8, 0xE6, 0xA9, 0x36, 0xD5, 0x63, 0x1E, 0x2C, - 0x2A, 0x55, 0x09, 0x77, 0x5E, 0xB3, 0x4B, 0xEA, - 0xB5, 0xD0, 0x14, 0x5F, 0xEB, 0x50, 0x7B, 0xAA, - 0xEF, 0x94, 0xBA, 0x2B, 0xD7, 0x8A, 0x07, 0xF1, - 0xF9, 0x5E, 0x12, 0x12, 0x21, 0x52, 0xE5, 0x0A, - 0x3E, 0xC0, 0xBC, 0x5D, 0x4C, 0xE2, 0x12, 0x7C, - 0x39, 0xF9, 0x16, 0x9D, 0xBD, 0x96, 0x83, 0x3B, - 0x7F, 0x3D, 0x6A, 0xEC, 0xF1, 0x25, 0xD2, 0xB0, - 0xB0, 0xEB, 0x20, 0x06, 0x07, 0xD6, 0xD9, 0x4C, - 0x07, 0x9A, 0x82, 0xC1, 0xFC, 0xF7, 0x66, 0x15, - 0xBD, 0x62, 0x65, 0xD8, 0x6C, 0xF6, 0x33, 0x7B, - 0x5A, 0x28, 0xEC, 0x90, 0xA1, 0x26, 0x9F, 0xC3, - 0x28, 0x4A, 0x64, 0x50, 0x5F, 0xCA, 0xE2, 0x6D, - 0xB8, 0x0F, 0xE2, 0x94, 0xB5, 0x8E, 0x1F, 0x8A, - 0x8F, 0x6B, 0xA6, 0x86, 0x1F, 0xEE, 0xDC, 0x24, - 0xB4, 0xB8, 0x25, 0xEC, 0x28, 0x2D, 0xF9, 0xCB, - 0x7D, 0x38, 0xFF, 0xC7, 0x74, 0x2E, 0xD3, 0x10, - 0xEC, 0x03, 0x31, 0xEE, 0x83, 0xE7, 0xA4, 0xF7, - 0xBA, 0x28, 0x21, 0xE0, 0x7F, 0xB4, 0xB7, 0xE1, - 0x7A, 0xF9, 0x2B, 0xB0, 0x2C, 0x3B, 0x80, 0x5F, - 0xE0, 0x5D, 0xB2, 0x7E, 0x59, 0xFF, 0x59, 0x07, - 0x58, 0x42, 0x57, 0xEE, 0x44, 0xF1, 0xB1, 0xAD, - 0xBA, 0xDE, 0xCB, 0x1D, 0x8A, 0x36, 0x67, 0xE8, - 0x45, 0xFF, 0x07, 0x8D, 0xEE, 0xA4, 0x51, 0x9C, - 0x4C, 0x83, 0x5D, 0x2E, 0x2F, 0xE1, 0x5B, 0x75, - 0xE8, 0x29, 0xCD, 0x0B, 0x07, 0x62, 0xE0, 0xC3, - 0x0D, 0x1D, 0xEA, 0xCF, 0xF0, 0x8A, 0x65, 0x27, - 0x70, 0x42, 0x9F, 0x26, 0x00, 0x15, 0x70, 0xC5, - 0x4A, 0xF6, 0x25, 0xD0, 0x40, 0x72, 0xE9, 0xC1, - 0x73, 0xFD, 0x48, 0x94, 0xA3, 0x8D, 0x66, 0x63, - 0x96, 0x4F, 0xF7, 0xEE, 0xFB, 0x4C, 0xC7, 0xB8, - 0x6B, 0xE9, 0x90, 0xE1, 0x2A, 0x66, 0x80, 0x99, - 0x3B, 0xB0, 0x1A, 0x6C, 0xF9, 0x0E, 0x72, 0xDA, - 0x8E, 0x4F, 0x46, 0xC2, 0x6A, 0x4B, 0x7A, 0x16, - 0xE5, 0x26, 0x0B, 0x5C, 0xD4, 0x47, 0x34, 0xE5, - 0x37, 0xBE, 0x68, 0x6C, 0xDA, 0xD3, 0x9B, 0x6F, - 0xAE, 0x51, 0x9C, 0x99, 0x0A, 0x5B, 0xF8, 0x37, - 0xBC, 0xDE, 0xFC, 0x93, 0xC5, 0xE7, 0x0F, 0xEF, - 0x0B, 0xA6, 0x07, 0xC2, 0xA6, 0xE6, 0xDA, 0x2D, - 0x1B, 0x49, 0xC9, 0xDE, 0x6B, 0x27, 0xDC, 0x00, - 0xEF, 0x23, 0x87, 0x0E, 0xEB, 0xD1, 0x48, 0x7D, - 0xB4, 0xF2, 0x58, 0xC6, 0x3C, 0xE2, 0x89, 0xBA, - 0xB0, 0x05, 0xAC, 0x94, 0x41, 0x9A, 0xA8, 0xFF, - 0x3E, 0xBC, 0x3A, 0x52, 0x9C, 0xF9, 0x7F, 0x07, - 0x8B, 0xB0, 0x2C, 0x71, 0x83, 0x7B, 0xCF, 0x2E, - 0x7F, 0x7C, 0x96, 0x65, 0xD9, 0x08, 0x17, 0xEC, - 0xFA, 0xDE, 0x4E, 0x40, 0x12, 0x26, 0x70, 0x71, - 0x65, 0xA5, 0xDC, 0x98, 0x47, 0xA3, 0xFC, 0xE0, - 0x9A, 0x16, 0xED, 0x45, 0x56, 0x72, 0x50, 0x05, - 0x28, 0x2C, 0x99, 0xEC, 0x20, 0x2E, 0x40, 0xC0, - 0x26, 0x69, 0xCD, 0x49, 0x45, 0x17, 0xA4, 0xA3, - 0x42, 0x0D, 0x14, 0x65, 0x87, 0x33, 0x8C, 0x92, - 0xC5, 0xC4, 0x61, 0xFD, 0xE8, 0x68, 0x56, 0x20, - 0x57, 0xF5, 0x8E, 0x5F, 0xCF, 0x7E, 0x97, 0xF6, - 0x49, 0x97, 0x0A, 0xFE, 0xD3, 0x60, 0x1A, 0x5B, - 0x0C, 0x75, 0xDD, 0x8E, 0x31, 0x78, 0x29, 0xA6, - 0xB1, 0x4D, 0xAA, 0xDF, 0x8A, 0xD1, 0xE6, 0x91, - 0xE3, 0x32, 0x3F, 0xEC, 0x8A, 0x1F, 0x0E, 0x35, - 0x07, 0x6E, 0x4B, 0x83, 0x3B, 0xE5, 0x67, 0x34, - 0x1F, 0x0C, 0x81, 0xD8, 0xD5, 0x25, 0x68, 0xE5, - 0x28, 0x1B, 0x5C, 0x81, 0x3E, 0xE3, 0x5C, 0xB4, - 0xB6, 0xBD, 0x62, 0x6A, 0x70, 0x33, 0xC2, 0xC5, - 0x75, 0x27, 0xF4, 0x30, 0xE1, 0x1D, 0xC1, 0x4C, - 0xC5, 0x02, 0x12, 0x46, 0xAC, 0xEC, 0xF9, 0xE8, - 0xE7, 0x58, 0x24, 0x11, 0xB1, 0xF3, 0xB7, 0x8C, - 0x3C, 0xA4, 0x0A, 0x94, 0xA6, 0x7C, 0x68, 0x54, - 0x5B, 0xB9, 0x4D, 0x57, 0x9C, 0xE7, 0x28, 0x09, - 0x6B, 0x89, 0x26, 0x5D, 0xE7, 0x50, 0xA9, 0x95, - 0x90, 0x91, 0x8E, 0x00, 0x59, 0xF8, 0x3A, 0x70, - 0xAF, 0x48, 0x2E, 0xE8, 0xC4, 0x34, 0x8C, 0xF4, - 0x5F, 0x7F, 0xCB, 0x07, 0xAA, 0xF0, 0xD9, 0xFB, - 0x5C, 0x32, 0x90, 0x22, 0x1A, 0xD2, 0x1A, 0xCF, - 0x92, 0x06, 0x02, 0xCF, 0x10, 0x18, 0x7B, 0x93, - 0xCC, 0x07, 0x4A, 0x31, 0x25, 0x30, 0x23, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xD1, 0xDE, - 0x23, 0x16, 0x9F, 0x6E, 0xF4, 0x42, 0x21, 0x23, - 0xE1, 0x11, 0xAA, 0xC8, 0x7C, 0x60, 0x4A, 0x78, - 0x9D, 0x24, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, - 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, - 0x00, 0x04, 0x14, 0xD6, 0x4A, 0xBB, 0x75, 0xB1, - 0xF9, 0x9E, 0xD3, 0x58, 0x6D, 0xD1, 0x74, 0x9F, - 0x00, 0x8A, 0xF2, 0xC8, 0xAA, 0x52, 0x4D, 0x04, - 0x08, 0x77, 0x46, 0xE7, 0xBA, 0x25, 0x4B, 0xDA, - 0x41, 0x02, 0x02, 0x08, 0x00] -}; - -const WPA_EAP_CLIENT_LIST = [ - { - ssid: 'WPA-EAP-PEAP', - keyManagement: 'WPA-EAP', - eap: 'PEAP', - identity: EAP_USERNAME, - password: EAP_PASSWORD, - serverCertificate: CLIENT_PKCS12_CERT.nickname, - phase2: 'MSCHAPV2' - } -]; - -/** - * Convert the given MozWifiNetwork object array to testAssociate chain. - * - * @param aNetworks - * An array of MozWifiNetwork which we want to convert. - * - * @return A promise chain which "then"s testAssociate accordingly. - */ -function convertToTestAssociateChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - network = new window.MozWifiNetwork(aNetwork); - chain = chain.then(() => gTestSuite.testAssociate(network)); - }); - - return chain; -} - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(CLIENT_PKCS12_CERT.content)]), - CLIENT_PKCS12_CERT.password, - CLIENT_PKCS12_CERT.nickname, - CLIENT_PKCS12_CERT.usage, - function() { - return gTestSuite.ensureWifiEnabled(true) - // Load required server files. - .then(() => gTestSuite.writeFile(SERVER_EAP_USER_CONF.path, SERVER_EAP_USER_CONF.content)) - .then(() => gTestSuite.writeFile(CA_CERT.path, CA_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_CERT.path, SERVER_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_KEY.path, SERVER_KEY.content)) - // Start AP. - .then(() => gTestSuite.startHostapds(WPA_EAP_AP_LIST)) - // Scan test. - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, WPA_EAP_AP_LIST)) - // Associate test. - .then(() => convertToTestAssociateChain(WPA_EAP_CLIENT_LIST)) - // Tear down. - .then(gTestSuite.killAllHostapd) -}); diff --git a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TLS.js b/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TLS.js deleted file mode 100644 index 35b942f8e..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TLS.js +++ /dev/null @@ -1,622 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -const EAP_USERNAME = 'username'; -const EAP_PASSWORD = 'password'; - -const SERVER_EAP_USER_CONF = { - path: HOSTAPD_CONFIG_PATH + 'hostapd.eap_user', - content: '* PEAP,TTLS,TLS\n' + - '"' + EAP_USERNAME + '" MSCHAPV2,TTLS-MSCHAPV2 "' + EAP_PASSWORD + '" [2]\n' -}; -const CA_CERT = { - path: HOSTAPD_CONFIG_PATH + 'ca.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIIDsTCCApmgAwIBAgIJAKxTf+8X8qngMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV\n' + - 'BAYTAlRXMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTER\n' + - 'MA8GA1UEAwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdt\n' + - 'YWlsLmNvbTAgFw0xNDEyMjQxMTI4NTBaGA8yMjg4MTAwNzExMjg1MFowbjELMAkG\n' + - 'A1UEBhMCVFcxEzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAoMCGNodWNrbGVl\n' + - 'MREwDwYDVQQDDAhjaHVja2xlZTEkMCIGCSqGSIb3DQEJARYVY2h1Y2tsaTA3MDZA\n' + - 'Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3c2yFxY\n' + - 'o6gGg0I83jy00ME+MAfzCd+4ShL45ZLqysQP93jRBfPzU9ZuZ29ysVwgWIdqkZao\n' + - 'XTuV/NAW2GMGd8W1jQJ3J81fjb9wvhlny3rrACwvUn1N1S1BnM+BAAiDLGxEmvAQ\n' + - 'onp2aaa6HsHsYS8ONX+d2Qh4LEA4vupeSGAqJychCZv/l+aq/ErFZhFYB3CPUQEt\n' + - 'cClO24ucsIYP95lA0zhscnmAj06qplFD4Bv6IVrdDqujy1zNwCQwsJq/8OQdaTN/\n' + - 'h3y9pWvNKMBMM2niOUAjtuNpqsSK/lTS1WAT3PdtVECX9fYBi0Bg+HM92xs/6gt6\n' + - 'kh9jPV8keXHvSwIDAQABo1AwTjAdBgNVHQ4EFgQU7hBqhuG04xeCzrQ3ngx18ZJ3\n' + - 'lUswHwYDVR0jBBgwFoAU7hBqhuG04xeCzrQ3ngx18ZJ3lUswDAYDVR0TBAUwAwEB\n' + - '/zANBgkqhkiG9w0BAQsFAAOCAQEAFYX2iy680GAnBTttk0gyX6gk+8pYr3D22k/G\n' + - '6rvcjefzS7ELQPRKr6mfmwXq3mMf/4jiS2zI5zmXsestPYzHYxf2viQ6t7vr9XiJ\n' + - '3WfFjNw4ERlRisAvg0aqqTNNQq5v2VME4sdFZagy217f73C7azwCHl0bqOLH05rl\n' + - '8RubOxiHEj7ZybJqnRciK/bht4D+rZkwf4bBBmoloqH7xT0+rFQclpYXDGGjNUQB\n' + - 'LcHLF10xcr7g3ZVVu82fe6+d85gIGOIMR9+TKhdw6gO3CNcnDAj6gxksghgtcxmh\n' + - 'OzOggCn7nlIwImtsg2sZkpWB4lEi9hdv4lkNuyFjOL3bnuc+NA==\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_CERT = { - path: HOSTAPD_CONFIG_PATH + 'server.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIID1DCCArygAwIBAgIBADANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJUVzET\n' + - 'MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIY2h1Y2tsZWUxETAPBgNVBAMM\n' + - 'CGNodWNrbGVlMSQwIgYJKoZIhvcNAQkBFhVjaHVja2xpMDcwNkBnbWFpbC5jb20w\n' + - 'IBcNMTQxMjI0MTEyOTQ5WhgPMjI4ODEwMDcxMTI5NDlaMG4xCzAJBgNVBAYTAlRX\n' + - 'MRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTERMA8GA1UE\n' + - 'AwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdtYWlsLmNv\n' + - 'bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdhQmKilTJbWZRxTiSV\n' + - 'rqIU+LYW1RKghx5o+0JpNRJVLuz5kBMaNskbbfUSNuHbEq0QA9BDKAZWIc4LSotk\n' + - 'lCo8TbcO9CJvJPQGGjGdHcohWX5vy6BE/OVE46CUteMFyZF6F8R2fNUww08iR/u1\n' + - 'YZebL5pWO1j43sPpAzEy6Tij2ACPt6EZcFaZG3SF2mVJWkCQnBqrojP65WUvZQqp\n' + - 'seUhW2YAS8Nu0Yrohgxz6VYk+cNDuDZVGs6qWRStZzJfYrfc76DtkHof5B14M+xp\n' + - 'XJaBLxN+whvnYkDTfinaCxnW1O7eXUltr87fLc5zmeBkgwaiaQuIdcfZm7vDUiz8\n' + - 'vnUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH\n' + - 'ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKK4f9/YavTHOfEiAB83Deac\n' + - '6gT5MB8GA1UdIwQYMBaAFO4QaobhtOMXgs60N54MdfGSd5VLMA0GCSqGSIb3DQEB\n' + - 'CwUAA4IBAQBWnO9o9KSJIqjoz5Nwll63ULOdcvgGdOeJIw1fcKQ817Rsp+TVcjcH\n' + - 'IrIADsT/QZGXRO/l6p1750e2iFtJEo1hsRaxtA1wWn2I9HO3+av2spQhr3jpYGPf\n' + - 'zpsMTp4RNYV7Q8+q1kZIz9PY4V1T0p6lveK8+fUj2hSLnxSj0QiGSJJtnEC3w4Rv\n' + - 'C9T6oUwIeToULmi+8FXQFdEqwKRU98DPq3eLzN28ZxUgoPE1C8+42D2UW8uyp/Gm\n' + - 'tGOa/k7nzkCdVqZI7lX7f0AjEvQgjtAMQ/k7Mhxx7TzW2HO+1YPMoKji6Z4WkNwt\n' + - 'JEj9ZUBSNt8B26UksJMBDkcvSegF3a7o\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_KEY = { - path: HOSTAPD_CONFIG_PATH + 'server.key', - content: '-----BEGIN RSA PRIVATE KEY-----\n' + - 'MIIEpAIBAAKCAQEAx2FCYqKVMltZlHFOJJWuohT4thbVEqCHHmj7Qmk1ElUu7PmQ\n' + - 'Exo2yRtt9RI24dsSrRAD0EMoBlYhzgtKi2SUKjxNtw70Im8k9AYaMZ0dyiFZfm/L\n' + - 'oET85UTjoJS14wXJkXoXxHZ81TDDTyJH+7Vhl5svmlY7WPjew+kDMTLpOKPYAI+3\n' + - 'oRlwVpkbdIXaZUlaQJCcGquiM/rlZS9lCqmx5SFbZgBLw27RiuiGDHPpViT5w0O4\n' + - 'NlUazqpZFK1nMl9it9zvoO2Qeh/kHXgz7GlcloEvE37CG+diQNN+KdoLGdbU7t5d\n' + - 'SW2vzt8tznOZ4GSDBqJpC4h1x9mbu8NSLPy+dQIDAQABAoIBAASG4Mr8hgaurEoC\n' + - 'iJOsElr7vunjetMBcg/uskW/vcS8ymP3Bp5oafYG+WgnEbfvEW18f5mq7K24JuxW\n' + - 'tUqU7ghHdjxByqk9fMlNmiqmNpbwSufkAeuRpWxPNBvhRH/zEbCL5R5A0nTEtqqF\n' + - 'TL0aUSzwCRSoAJD0lZo9ICVt0n3GsDyM9rqQg/uZmh1qsRdwPsRuYORND9g48rKq\n' + - '6WN9leskSxhhsYE2D9ocOFd9bNt8Zxejh9ppVSnG/KsIdt18iBzcabatgAQ046fb\n' + - 'Z3vprcZJLg93Sg2gSuVqlSTs3M2W8VQnm22/EBMb1y0M48MSRCgnbPLG/CcCLLfF\n' + - 'LwxCOgECgYEA/eYt67xyJ6JeAdxdwOZuT1WWGbFpLiG9+2OgiHumyRQ5969XMTWo\n' + - 'fIhMKchDdjoy9RR236\/\/EFCs7UEyB7+a7ODRzNiK2zCD8Smjp+21fUPSthEeQesk\n' + - 'eiMYICIu5Ay35x9sxIX+XOUVvRhPOGcD29GVeRnKh1inTHOz2dje8LkCgYEAyQeY\n' + - 'STi9jjCEcHkM1E/UeDiLfHHepLXi8wS41JNRHl5Jacp7XB5djAjKu/jf367/VpFy\n' + - 'GDDMetE7n8eWkrnAvovxOwZ000YDMtL1sUYSjL+XtBS5s6VY1p4qaSAY9nUUGrJh\n' + - 'JvtvsuI7SKTtL+60vjBOH7zDnvOdBgAp0utLhZ0CgYEAuLzzqrPKB8afShFSchn4\n' + - 'J2dpuLYahsNsXW7HDqeR2nsKFosRETAusLXnXPtnAq4kB6jlOarwFqnsuRCX24Vx\n' + - 'r2uBm9/vYL7zMdUPTA+s30ErHuhjsKjsOKYyVqcooSwT32pBFNk+E89nutfmRG7I\n' + - 'IvhjHuNCNqqtx/Xj5d1jkZkCgYBQicppC2Jl5OoqZVTOem0U/RJk+PnJ41TZJ7sk\n' + - '7yBAmmWvDH\/\/l+rCf4M5a6vFYcbKV9rt9h711X2dtciNX/3oWQh8LUoAmrwNUJc+\n' + - 'PmSQHvIYI3WCk2vUD+nN1B4sHxu+1lg11eYaNKiroeeknG2tBI1ICcgVlmQCU25u\n' + - 'IfZPwQKBgQCdO6QHhPLtcHUDNFA6FQ1jKL1iEd7G0JLVRz4Xkpkn1Vrr5MD6JFDa\n' + - '5ccabADyl0lpFqDIVJQIzLku2hOD2i9aBNCY0pL391HeOS7CkZX+TdOY1tquoBq5\n' + - 'MnmixZjDCVd2VcrVyTA6ntOBoharKFW0rH1PqU+qu7dZF7CBPbAdEw==\n' + - '-----END RSA PRIVATE KEY-----\n' -}; - -const WPA_EAP_AP_LIST = [ - { - ssid: 'WPA-EAP-TLS', - ieee8021x: 1, - eapol_version: 1, - eap_server: 1, - eapol_key_index_workaround: 0, - eap_user_file: SERVER_EAP_USER_CONF.path, - ca_cert: CA_CERT.path, - server_cert: SERVER_CERT.path, - private_key: SERVER_KEY.path, - wpa: 2, - wpa_key_mgmt: 'WPA-EAP' - } -]; - -const CLIENT_PKCS12_CERT = { - nickname: 'client', - password: 'password', - usage: ['UserCert', 'ServerCert'], - content: [0x30, 0x82, 0x0E, 0x01, 0x02, 0x01, 0x03, 0x30, - 0x82, 0x0D, 0xC7, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, - 0x0D, 0xB8, 0x04, 0x82, 0x0D, 0xB4, 0x30, 0x82, - 0x0D, 0xB0, 0x30, 0x82, 0x08, 0x67, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, - 0x06, 0xA0, 0x82, 0x08, 0x58, 0x30, 0x82, 0x08, - 0x54, 0x02, 0x01, 0x00, 0x30, 0x82, 0x08, 0x4D, - 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, - 0x06, 0x30, 0x0E, 0x04, 0x08, 0x67, 0x7A, 0xF3, - 0x61, 0xBE, 0xE0, 0x51, 0xC1, 0x02, 0x02, 0x08, - 0x00, 0x80, 0x82, 0x08, 0x20, 0xFC, 0x6A, 0x79, - 0xA1, 0x6C, 0xAF, 0xBE, 0xEE, 0x62, 0x45, 0x33, - 0xB8, 0x48, 0xE1, 0x68, 0xA1, 0x15, 0x11, 0x4B, - 0x95, 0xCB, 0x77, 0xC0, 0x5D, 0xA2, 0xCB, 0xDB, - 0xD1, 0x83, 0x74, 0x60, 0xD7, 0xEC, 0x42, 0xA6, - 0x3A, 0x23, 0xF7, 0x85, 0xEB, 0xC1, 0xFE, 0x6A, - 0x57, 0x8E, 0xC1, 0x44, 0xF3, 0x1F, 0xFE, 0xB8, - 0x2D, 0x8C, 0x4D, 0xC9, 0x5B, 0xAE, 0x21, 0x2E, - 0x4C, 0x1A, 0xEB, 0x84, 0x09, 0xF3, 0x40, 0x92, - 0x39, 0x7F, 0x56, 0x02, 0x46, 0x61, 0x16, 0xDE, - 0x5C, 0x48, 0xB6, 0x0C, 0x1D, 0xD3, 0x5F, 0x10, - 0x9A, 0x39, 0xB8, 0x66, 0x31, 0xFC, 0x39, 0x71, - 0x87, 0x23, 0x46, 0x9D, 0xE8, 0x3C, 0x2B, 0xA1, - 0x39, 0x8A, 0xD3, 0xFF, 0xD9, 0x43, 0xB6, 0x61, - 0xC6, 0x67, 0x70, 0x40, 0xBD, 0xFE, 0xD3, 0xC1, - 0x68, 0xF5, 0xF7, 0xC8, 0x89, 0xD8, 0x17, 0xC5, - 0xE8, 0x3D, 0x29, 0xD5, 0x91, 0xDF, 0x1F, 0x56, - 0x74, 0x5A, 0xC4, 0xA8, 0x14, 0xBA, 0xD4, 0xFA, - 0x13, 0x49, 0x2A, 0x9F, 0x63, 0xF1, 0xB2, 0x45, - 0xF1, 0xF0, 0x2A, 0xDD, 0x75, 0x66, 0x8A, 0xF7, - 0xAB, 0x73, 0x86, 0x26, 0x9D, 0x1F, 0x07, 0xAD, - 0xD3, 0xFE, 0xE0, 0xA3, 0xED, 0xA0, 0x96, 0x3E, - 0x1E, 0x89, 0x86, 0x02, 0x4C, 0x28, 0xFD, 0x57, - 0xA1, 0x67, 0x55, 0xF0, 0x82, 0x3B, 0x7F, 0xCC, - 0x2A, 0x32, 0x01, 0x93, 0x1D, 0x8B, 0x66, 0x8A, - 0x20, 0x52, 0x84, 0xDD, 0x2C, 0xFD, 0xEE, 0x72, - 0xF3, 0x8C, 0x58, 0xB9, 0x99, 0xE5, 0xC1, 0x22, - 0x63, 0x59, 0x00, 0xE2, 0x76, 0xC5, 0x3A, 0x17, - 0x7F, 0x93, 0xE9, 0x67, 0x61, 0xAA, 0x10, 0xC3, - 0xD9, 0xC8, 0x24, 0x46, 0x5B, 0xBE, 0x8C, 0x1F, - 0x2D, 0x66, 0x48, 0xD2, 0x02, 0x11, 0xFB, 0x74, - 0x14, 0x76, 0x76, 0x5A, 0x98, 0x54, 0x35, 0xA7, - 0x85, 0x66, 0x20, 0x26, 0x8B, 0x13, 0x6F, 0x68, - 0xE3, 0xC9, 0x58, 0x7D, 0x1C, 0x3E, 0x01, 0x8D, - 0xF8, 0xD6, 0x7F, 0xCF, 0xA2, 0x07, 0xB7, 0x95, - 0xFD, 0xF0, 0x02, 0x34, 0x32, 0x30, 0xE8, 0xD4, - 0x57, 0x5E, 0x53, 0xFB, 0x54, 0xE2, 0x03, 0x32, - 0xCC, 0x52, 0x2E, 0xD2, 0x35, 0xD9, 0x58, 0x85, - 0x2D, 0xEC, 0x2D, 0x71, 0xD1, 0x8A, 0x29, 0xD0, - 0xB0, 0x24, 0xBD, 0x24, 0xDC, 0x1A, 0x28, 0x3F, - 0xA0, 0x12, 0x81, 0x15, 0x24, 0xC9, 0xB5, 0x4A, - 0x23, 0xB6, 0xA3, 0x45, 0x50, 0x2D, 0x73, 0x99, - 0x6B, 0x1C, 0xFB, 0xA4, 0x53, 0xD7, 0x5C, 0xF4, - 0x6C, 0xB0, 0xE5, 0x74, 0xB3, 0x76, 0xF8, 0xB1, - 0x0D, 0x59, 0x70, 0x9F, 0xCA, 0xDE, 0xF2, 0xAA, - 0x4C, 0x7D, 0x11, 0x54, 0xC4, 0x19, 0x0F, 0x36, - 0x4A, 0x62, 0xFF, 0x8B, 0x10, 0xCB, 0x93, 0x50, - 0xDA, 0x79, 0x5E, 0x4E, 0x09, 0x1F, 0x22, 0xC8, - 0x19, 0x85, 0xE9, 0xEE, 0xB7, 0x71, 0x65, 0xB9, - 0x10, 0xD2, 0x0A, 0x73, 0x5B, 0xA6, 0xDA, 0x37, - 0x46, 0x02, 0x00, 0x98, 0x9E, 0x20, 0x6C, 0x7D, - 0xC7, 0x69, 0xBB, 0xC2, 0x00, 0x40, 0x9C, 0x57, - 0x00, 0xC2, 0x36, 0x76, 0xE8, 0x2A, 0x8D, 0xAD, - 0x62, 0x57, 0xC8, 0xD0, 0x9D, 0x66, 0x27, 0x5A, - 0xD8, 0x0D, 0x35, 0x60, 0x28, 0x38, 0x62, 0x94, - 0x78, 0x36, 0x25, 0x58, 0xFD, 0xF8, 0x66, 0x1F, - 0x68, 0x04, 0x0F, 0xD8, 0x00, 0xDF, 0xA0, 0x6C, - 0x25, 0x42, 0x9A, 0x4C, 0xEB, 0x80, 0x13, 0x51, - 0x7D, 0x2D, 0xA8, 0x89, 0xD6, 0x1B, 0x67, 0x72, - 0x01, 0xF3, 0x2D, 0x16, 0x77, 0xFE, 0x22, 0xBC, - 0x8A, 0x45, 0x09, 0x1F, 0x9C, 0x2F, 0x2A, 0xA9, - 0x61, 0x5B, 0x4A, 0xE6, 0x64, 0x2C, 0x62, 0x1A, - 0x3A, 0x96, 0xE6, 0x0A, 0xAE, 0x05, 0x1A, 0xC8, - 0xCB, 0xD6, 0x8F, 0x3A, 0x4B, 0xE0, 0x7F, 0x82, - 0xB4, 0x98, 0xF1, 0x9D, 0xD7, 0x14, 0x76, 0x5E, - 0x77, 0x85, 0x87, 0xEC, 0x13, 0xDA, 0xFD, 0xAF, - 0xCB, 0xA3, 0x1C, 0x99, 0xC1, 0xFE, 0x17, 0x0C, - 0x40, 0x4D, 0x3C, 0x8F, 0x70, 0x86, 0x63, 0x64, - 0xB7, 0x75, 0xA8, 0x71, 0x36, 0xDC, 0x54, 0x10, - 0x57, 0x0C, 0xA8, 0xF2, 0xA1, 0xBB, 0xED, 0x03, - 0x41, 0x57, 0x34, 0x2C, 0x8F, 0x7C, 0xA0, 0x09, - 0xF3, 0x9E, 0x41, 0xB7, 0xA8, 0xD4, 0x66, 0x0D, - 0x0D, 0xC0, 0x6A, 0xFC, 0x6A, 0xA2, 0xAC, 0xE2, - 0x60, 0x00, 0xE3, 0xF7, 0x75, 0x43, 0x23, 0xEB, - 0xC8, 0x61, 0xFA, 0xB3, 0xB8, 0x28, 0xCE, 0xCA, - 0xF4, 0x47, 0x7F, 0x30, 0x6D, 0x61, 0x89, 0x47, - 0xA1, 0x4A, 0xFE, 0xD1, 0x21, 0x0B, 0x6D, 0xF4, - 0x3F, 0x00, 0x86, 0x30, 0x8E, 0x33, 0x21, 0x6F, - 0xDA, 0x15, 0xFD, 0x5F, 0xEC, 0x8E, 0xF1, 0x12, - 0x3F, 0xC9, 0x83, 0x0C, 0xCA, 0x22, 0x01, 0xF1, - 0x70, 0x5F, 0x1F, 0x66, 0xB5, 0xF8, 0x3E, 0x7A, - 0x6F, 0xDE, 0xDB, 0xA7, 0x8D, 0x18, 0x9E, 0xBE, - 0xDB, 0xAD, 0x3D, 0x66, 0x30, 0xC1, 0x6C, 0x0C, - 0x87, 0xB4, 0x65, 0x75, 0xE0, 0x9D, 0xEA, 0x16, - 0x0D, 0x07, 0x37, 0x33, 0xC5, 0xEC, 0x97, 0x93, - 0x37, 0xEB, 0x8E, 0x65, 0x9C, 0x40, 0x63, 0x6C, - 0x43, 0x60, 0xB0, 0x40, 0x4D, 0x85, 0xEF, 0xC2, - 0x47, 0x5F, 0xE7, 0x6B, 0xCB, 0x40, 0xE8, 0xEA, - 0xD8, 0xAB, 0xB1, 0x9A, 0x72, 0xDC, 0x4C, 0x14, - 0xFA, 0x43, 0x61, 0x5F, 0xA6, 0x5C, 0x3A, 0x05, - 0x17, 0x2E, 0x74, 0xF3, 0x5E, 0x45, 0xD9, 0x47, - 0xAA, 0x59, 0xB6, 0x8F, 0x42, 0x66, 0x42, 0x29, - 0x90, 0x95, 0x48, 0x46, 0x91, 0x88, 0x3C, 0x8C, - 0xDE, 0xCC, 0xED, 0xB3, 0xAA, 0x62, 0xEA, 0xBC, - 0xB4, 0x0C, 0x48, 0x4C, 0x53, 0x23, 0x5E, 0x24, - 0x85, 0xBF, 0x92, 0xDA, 0x14, 0xDB, 0x1A, 0x3D, - 0xEF, 0x30, 0xD9, 0x49, 0x64, 0x4D, 0xE5, 0x01, - 0xFC, 0xA4, 0x4B, 0xD1, 0x9F, 0xDE, 0x96, 0x7F, - 0x50, 0xBC, 0x4D, 0x38, 0x44, 0xE9, 0x23, 0x5F, - 0x37, 0x57, 0x1A, 0xA6, 0x52, 0x5A, 0x0F, 0x4F, - 0x87, 0x33, 0x4A, 0x7B, 0x66, 0xEE, 0x3D, 0x66, - 0x0A, 0x63, 0x39, 0x1F, 0x23, 0x38, 0x35, 0x73, - 0x60, 0x5E, 0x47, 0x20, 0x4F, 0xC0, 0xC8, 0x3C, - 0x09, 0xF9, 0x29, 0x4F, 0x5E, 0x55, 0x69, 0xC4, - 0x6B, 0xE8, 0xF8, 0x91, 0xC0, 0x22, 0x65, 0x15, - 0x1E, 0xFB, 0xB9, 0x61, 0xCE, 0x45, 0xBE, 0x2B, - 0xEE, 0xB9, 0x04, 0x2B, 0xFD, 0xAE, 0x61, 0x1C, - 0x3D, 0x3D, 0x7C, 0xBF, 0xC1, 0xF7, 0x3C, 0x4E, - 0x9E, 0x0E, 0x54, 0xC8, 0xAD, 0xA9, 0xDF, 0x43, - 0x49, 0xB9, 0x41, 0x05, 0xE5, 0xF1, 0x49, 0xAA, - 0x77, 0x6C, 0x34, 0x5B, 0x93, 0x24, 0x24, 0x23, - 0x74, 0x68, 0x11, 0xCE, 0x15, 0x80, 0xA1, 0xA4, - 0x1F, 0x8D, 0x81, 0xCD, 0xB2, 0x98, 0xCA, 0x14, - 0x0B, 0x0C, 0x61, 0x50, 0x69, 0x72, 0xAE, 0xFA, - 0x8B, 0xC0, 0x3F, 0x0D, 0xE7, 0xF2, 0x0F, 0xEB, - 0xC1, 0x11, 0xB9, 0x10, 0x03, 0x6A, 0xF5, 0x97, - 0x3C, 0x53, 0x2F, 0x67, 0x86, 0x09, 0x6A, 0xE3, - 0x28, 0xC0, 0x78, 0xC8, 0xB4, 0x39, 0x8E, 0xD1, - 0xCE, 0x25, 0xE8, 0x66, 0xF7, 0x09, 0x40, 0x7D, - 0x81, 0xFB, 0xAF, 0xFA, 0x59, 0xC4, 0x9B, 0x2B, - 0x83, 0x45, 0x5B, 0xA8, 0x66, 0x9E, 0x38, 0xC8, - 0xFD, 0xAC, 0xF2, 0x2D, 0x21, 0xDE, 0x50, 0x4C, - 0x03, 0xCB, 0x88, 0x42, 0xDD, 0x84, 0x09, 0x99, - 0x8E, 0x8B, 0x40, 0x97, 0x1B, 0x14, 0x85, 0x37, - 0x11, 0x01, 0xE0, 0x74, 0x6B, 0x33, 0x52, 0x8C, - 0x68, 0x3A, 0x89, 0xB2, 0xAF, 0x35, 0xE6, 0x65, - 0xC3, 0x58, 0x70, 0xD2, 0xE7, 0x1F, 0x1F, 0xF6, - 0xE5, 0x0A, 0xB1, 0xFE, 0xD0, 0xC9, 0x51, 0x50, - 0xE7, 0xFD, 0x58, 0xF5, 0xC4, 0x58, 0x65, 0x94, - 0xD1, 0x57, 0x55, 0x5E, 0xD2, 0x27, 0x98, 0xAF, - 0xE7, 0x55, 0x0B, 0x87, 0x50, 0x9B, 0xEF, 0xE8, - 0x2B, 0xFC, 0xE7, 0x3B, 0x4E, 0xD7, 0xB7, 0x4D, - 0xF4, 0xBC, 0xF4, 0x88, 0x63, 0xE4, 0x8A, 0x20, - 0x4B, 0x22, 0xB0, 0xA0, 0x53, 0x7F, 0xA8, 0xC9, - 0x0C, 0xF8, 0xD7, 0xBD, 0x46, 0x39, 0xA7, 0x7D, - 0xDD, 0x10, 0x91, 0x50, 0x54, 0x06, 0x47, 0xF0, - 0x3C, 0xAA, 0x43, 0x40, 0xF8, 0x54, 0xDD, 0x8A, - 0xEA, 0x8A, 0x0B, 0xA5, 0x7F, 0xCD, 0x5E, 0xAA, - 0x02, 0x2E, 0x1F, 0xC6, 0x50, 0x15, 0xF8, 0x0A, - 0x0C, 0x1B, 0x3C, 0x55, 0x3A, 0xC3, 0x6F, 0x88, - 0xD7, 0xBF, 0xB1, 0x02, 0xCC, 0xE0, 0x08, 0x29, - 0x97, 0xD2, 0xAA, 0x23, 0xC4, 0x6D, 0xE3, 0xE3, - 0x76, 0x39, 0x92, 0xC3, 0x2E, 0x7A, 0xE2, 0x98, - 0xD1, 0xFC, 0xAE, 0xCC, 0x95, 0xD8, 0xB4, 0xDC, - 0x92, 0xEA, 0x6A, 0x5F, 0xF2, 0x92, 0x17, 0x0B, - 0x8D, 0xC3, 0xFA, 0x9C, 0x62, 0xCE, 0x44, 0x8D, - 0xC3, 0x1E, 0xC3, 0xB2, 0xD5, 0x00, 0xCD, 0xB4, - 0x9E, 0x2D, 0x7B, 0xF2, 0x98, 0xA3, 0x00, 0x8B, - 0x81, 0x30, 0x77, 0x5B, 0x02, 0x99, 0xB1, 0xCD, - 0xC3, 0x1D, 0x74, 0x74, 0xEF, 0x41, 0xCB, 0x69, - 0x63, 0x8E, 0xA6, 0xD3, 0x2D, 0x3E, 0x1F, 0x1D, - 0x12, 0x9E, 0xD9, 0x18, 0x67, 0x06, 0xAF, 0x37, - 0x29, 0xAD, 0x65, 0xD8, 0xEB, 0x71, 0xC4, 0x7D, - 0x94, 0x3D, 0xEA, 0xCC, 0xDF, 0x72, 0x41, 0x51, - 0x3C, 0xA1, 0x66, 0x98, 0x32, 0x32, 0x40, 0x54, - 0xB0, 0x2F, 0xEB, 0xCE, 0xDF, 0x4A, 0x64, 0xFB, - 0x9A, 0x90, 0xDC, 0xF6, 0x6F, 0xA9, 0xD4, 0xCA, - 0xCB, 0x91, 0xC4, 0xFE, 0xEE, 0x9C, 0x01, 0x50, - 0x2E, 0xAC, 0xCC, 0x5F, 0x89, 0xD0, 0x91, 0xA3, - 0xD9, 0xF9, 0x4B, 0x8D, 0xDE, 0x6C, 0x60, 0x21, - 0x19, 0xB1, 0xD3, 0x4D, 0x75, 0x56, 0x6F, 0xB8, - 0x25, 0xA4, 0x92, 0x4F, 0x12, 0xF5, 0x8F, 0xC1, - 0x17, 0x4B, 0xB3, 0x34, 0x21, 0x22, 0xAC, 0x52, - 0xD2, 0x64, 0xC9, 0x9A, 0x7D, 0xFC, 0xC0, 0x0A, - 0x89, 0x34, 0xFF, 0x08, 0xD3, 0x04, 0xDC, 0xFE, - 0x7C, 0xB3, 0xB8, 0xFD, 0x85, 0xDD, 0x79, 0x51, - 0xA7, 0x89, 0xE8, 0xF1, 0x23, 0xB1, 0xDF, 0xD7, - 0x1F, 0x7B, 0xB1, 0x5D, 0x42, 0xF9, 0x61, 0xF8, - 0xDC, 0x81, 0x04, 0xF1, 0xCC, 0xFA, 0xD7, 0xED, - 0xBF, 0x47, 0xAC, 0xBD, 0xE5, 0xFA, 0xAC, 0xB3, - 0x1C, 0xD9, 0xA1, 0xB3, 0x60, 0xEE, 0x9C, 0x8A, - 0x36, 0x57, 0xB4, 0x2F, 0xA1, 0xA2, 0xF3, 0xE2, - 0x09, 0x9A, 0x6E, 0x43, 0x9B, 0xE5, 0x93, 0xB8, - 0x3D, 0x9E, 0x9F, 0xC1, 0xC6, 0x0D, 0x02, 0xEB, - 0x4D, 0x38, 0xE9, 0xB4, 0x9F, 0xEA, 0x33, 0x8C, - 0x07, 0xD8, 0xB4, 0x71, 0xAD, 0xE5, 0x43, 0xB2, - 0xCC, 0x55, 0x93, 0x6A, 0xDB, 0x1E, 0x80, 0xDB, - 0xC2, 0xEA, 0x42, 0x8E, 0xFC, 0x86, 0x44, 0xC9, - 0x8A, 0xC4, 0xF2, 0x46, 0xA7, 0x39, 0x50, 0x0D, - 0x1A, 0xAA, 0x07, 0x04, 0xBE, 0xD4, 0xCE, 0x62, - 0x4D, 0x0F, 0x91, 0x7D, 0x29, 0x88, 0x9C, 0x4C, - 0xAF, 0xF7, 0xD8, 0x40, 0x93, 0x88, 0xC7, 0x20, - 0xD2, 0x17, 0x2A, 0xC4, 0x92, 0x72, 0xD0, 0xC0, - 0x4E, 0x56, 0x47, 0xB1, 0x27, 0x02, 0xE6, 0x61, - 0x82, 0x5E, 0xC8, 0x2E, 0x90, 0xD2, 0x31, 0x22, - 0xE2, 0xA9, 0x4A, 0x91, 0x45, 0x69, 0xB1, 0xA5, - 0x0F, 0x66, 0x2C, 0x30, 0xAD, 0x7F, 0x1B, 0x0E, - 0x22, 0x17, 0x60, 0x2E, 0x3D, 0x7F, 0x7F, 0x8C, - 0x33, 0x51, 0xA0, 0x25, 0xDE, 0xFD, 0x75, 0xBC, - 0xEF, 0xE6, 0xE7, 0x20, 0x04, 0x5A, 0xEC, 0x50, - 0x21, 0x48, 0x56, 0x98, 0xE2, 0x33, 0x6D, 0x22, - 0x5C, 0xC3, 0xFB, 0xFC, 0x6F, 0xB3, 0xA7, 0x8E, - 0x6F, 0x67, 0x70, 0x9D, 0xDA, 0x02, 0x01, 0x59, - 0x7B, 0x3D, 0x2B, 0x38, 0xCC, 0x0F, 0x44, 0x3D, - 0xFB, 0x9A, 0xB3, 0x23, 0x15, 0x50, 0x6E, 0xBF, - 0x8B, 0xA1, 0x94, 0x33, 0xE5, 0x7B, 0x88, 0x4E, - 0xCB, 0x6D, 0x9F, 0xBF, 0xBC, 0x7A, 0xA8, 0x1E, - 0x68, 0x25, 0xED, 0x8E, 0x53, 0x21, 0x72, 0xC5, - 0x70, 0xB3, 0xE4, 0xA6, 0xA1, 0x5A, 0x2D, 0xC8, - 0x43, 0x9D, 0x60, 0x77, 0x78, 0xE0, 0xC4, 0xAF, - 0xC8, 0x29, 0xBA, 0xD0, 0x4D, 0x39, 0x83, 0x51, - 0xA7, 0x10, 0x7F, 0x0C, 0x34, 0x0E, 0x6C, 0x75, - 0x26, 0xD7, 0xD6, 0xC7, 0x32, 0x53, 0xAF, 0x4E, - 0xBE, 0xF2, 0xC2, 0x0F, 0x99, 0x23, 0xB9, 0xE1, - 0xC8, 0xB4, 0xBC, 0x5A, 0xC6, 0xCB, 0xEB, 0x4D, - 0x28, 0x56, 0x72, 0xFE, 0x1B, 0x2C, 0x5D, 0xE3, - 0xBC, 0xC7, 0xA3, 0xC0, 0x7D, 0x27, 0xF0, 0xD0, - 0x4F, 0x3F, 0x1F, 0xF7, 0x87, 0x15, 0xF2, 0xEA, - 0xD4, 0x03, 0x6D, 0x2F, 0xD4, 0x8E, 0x50, 0x4B, - 0x05, 0xBF, 0xF7, 0x8C, 0x67, 0x5A, 0xDC, 0x4D, - 0xCD, 0xCF, 0x9D, 0x02, 0xB6, 0xE7, 0xAE, 0x49, - 0xD1, 0x7C, 0x00, 0xE7, 0x3B, 0xEA, 0xFB, 0x0D, - 0x2A, 0x7B, 0x41, 0x33, 0x66, 0xD0, 0x29, 0x9F, - 0xB3, 0x8A, 0x71, 0xB0, 0xE2, 0x76, 0xA9, 0xDB, - 0xFD, 0x64, 0x04, 0x69, 0xDF, 0x89, 0x1F, 0x56, - 0x86, 0x92, 0xD9, 0xD9, 0xB9, 0xF3, 0x4F, 0xAC, - 0xAE, 0x61, 0x48, 0x20, 0xCE, 0x3C, 0x2B, 0x44, - 0xAB, 0x42, 0xFA, 0xAB, 0x2E, 0x94, 0x82, 0xC8, - 0xD9, 0x97, 0xCF, 0x27, 0xDF, 0xAC, 0xAC, 0xE7, - 0xCA, 0xB2, 0x84, 0xAB, 0xF2, 0x5D, 0xDF, 0x56, - 0x0C, 0x8C, 0x07, 0x3C, 0x3D, 0xA8, 0xDD, 0xBE, - 0xFF, 0x4E, 0x28, 0x0D, 0xB2, 0x2D, 0xE6, 0x9D, - 0x44, 0x21, 0xCB, 0xE7, 0x33, 0x63, 0x22, 0x8F, - 0x4C, 0xFF, 0xB6, 0x1D, 0x9A, 0x71, 0x3F, 0xB1, - 0x29, 0xAE, 0x3A, 0x35, 0xEE, 0x9C, 0x97, 0x68, - 0xA7, 0x52, 0x66, 0x01, 0xD8, 0x9A, 0x5D, 0xF4, - 0xB3, 0x2F, 0x5C, 0xD4, 0x0E, 0xF9, 0xCF, 0x07, - 0xF6, 0x8C, 0xBA, 0xA6, 0x8D, 0x6B, 0xC6, 0x01, - 0xC2, 0x69, 0xAE, 0x60, 0x08, 0x1A, 0x0E, 0x3F, - 0xAE, 0x60, 0x29, 0xF3, 0x48, 0x0D, 0xE0, 0xD0, - 0xAE, 0x52, 0x44, 0xE9, 0x7F, 0x1F, 0x92, 0x5F, - 0x71, 0xAD, 0xEC, 0x6B, 0x47, 0x66, 0x92, 0x22, - 0x27, 0xAE, 0x6E, 0x25, 0xCD, 0xF3, 0x5F, 0x55, - 0x59, 0xBD, 0x73, 0xCE, 0x2B, 0x7E, 0x99, 0x44, - 0x56, 0x70, 0xA3, 0xE7, 0x7A, 0x59, 0x75, 0xD8, - 0x48, 0x0C, 0x39, 0x2B, 0xD7, 0x53, 0xC6, 0xAD, - 0x4A, 0x6F, 0xB4, 0x14, 0x96, 0xDF, 0xF2, 0x4A, - 0x0C, 0xA2, 0xD5, 0x29, 0x98, 0x7C, 0x42, 0x87, - 0xD9, 0x1F, 0x97, 0x61, 0xD9, 0xBF, 0x99, 0x4F, - 0x2C, 0x4C, 0x75, 0xAC, 0xB8, 0x06, 0x75, 0xD6, - 0x87, 0x76, 0x7E, 0xE3, 0x23, 0x4B, 0xEA, 0x1A, - 0x1A, 0xF4, 0xB7, 0x09, 0xAF, 0x53, 0xEB, 0xA6, - 0x39, 0x10, 0xFE, 0xD4, 0xEB, 0x1B, 0xAE, 0x38, - 0x31, 0x33, 0xBA, 0x68, 0xEE, 0xC7, 0x65, 0x76, - 0xFB, 0x49, 0x77, 0xD4, 0x19, 0xC4, 0xE6, 0xA7, - 0x05, 0xFE, 0x2A, 0xDA, 0x39, 0x99, 0x1A, 0x92, - 0xD2, 0xF0, 0x61, 0x97, 0xF6, 0x06, 0x6C, 0x88, - 0x7B, 0x6F, 0x60, 0xE6, 0x70, 0x08, 0xF0, 0xB4, - 0x6B, 0x39, 0x6F, 0x05, 0x41, 0x81, 0xF9, 0xBE, - 0x7A, 0x51, 0xC4, 0x75, 0xB0, 0x6A, 0x89, 0xA0, - 0xA6, 0x9A, 0x5B, 0xEE, 0x7D, 0x78, 0x17, 0x5F, - 0x9F, 0x3B, 0x7D, 0xDD, 0x8A, 0x9E, 0xAA, 0x1A, - 0xDA, 0x49, 0x08, 0xE9, 0xFD, 0x91, 0xA6, 0xFA, - 0xCE, 0xCF, 0x67, 0xDF, 0x0F, 0xC9, 0xD6, 0x38, - 0xD9, 0xD5, 0xD1, 0xC0, 0x76, 0x59, 0x42, 0x53, - 0xBF, 0x48, 0xE9, 0x11, 0x74, 0xC7, 0x11, 0xD8, - 0xE7, 0x8E, 0xD3, 0xC8, 0x25, 0xA1, 0x26, 0x50, - 0xBB, 0xB4, 0x35, 0xAF, 0xAF, 0x06, 0x23, 0x69, - 0x3E, 0x30, 0xFD, 0x7B, 0x34, 0x83, 0x07, 0xD0, - 0xF0, 0x0F, 0x6C, 0x9A, 0x13, 0x5D, 0xC2, 0x7B, - 0xDF, 0x6F, 0xDD, 0x8E, 0xF4, 0x30, 0x82, 0x05, - 0x41, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x05, 0x32, - 0x04, 0x82, 0x05, 0x2E, 0x30, 0x82, 0x05, 0x2A, - 0x30, 0x82, 0x05, 0x26, 0x06, 0x0B, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, - 0x02, 0xA0, 0x82, 0x04, 0xEE, 0x30, 0x82, 0x04, - 0xEA, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, - 0x0E, 0x04, 0x08, 0x74, 0xC0, 0x84, 0x8F, 0xC7, - 0x74, 0x5E, 0x21, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x04, 0xC8, 0x1E, 0xF4, 0xE9, 0x07, 0x27, - 0x9E, 0x5A, 0xC9, 0x39, 0x1D, 0x37, 0x2C, 0x06, - 0x4B, 0x57, 0xEA, 0xC5, 0x42, 0x9A, 0x60, 0xD5, - 0x42, 0xB2, 0x34, 0x2D, 0xD3, 0x88, 0x7C, 0x78, - 0x87, 0xB6, 0xE9, 0x42, 0x44, 0x1F, 0x67, 0x32, - 0x92, 0x54, 0x22, 0xDA, 0xB2, 0x43, 0xE7, 0x40, - 0xBE, 0x1F, 0xAF, 0x3A, 0xCD, 0x2A, 0x9F, 0xD7, - 0x44, 0x5B, 0x37, 0x69, 0x85, 0xDF, 0xEB, 0x2A, - 0xB9, 0xE2, 0x92, 0x3B, 0xEA, 0xD5, 0x42, 0x53, - 0x95, 0x4A, 0xB0, 0x1B, 0xA5, 0xEF, 0xA6, 0x0D, - 0x29, 0xF4, 0x33, 0xFE, 0xD7, 0x49, 0x04, 0x1E, - 0x8C, 0xAD, 0x63, 0x1E, 0x79, 0x63, 0x74, 0x0C, - 0xE5, 0x5E, 0xA2, 0x2C, 0xBE, 0xB8, 0x90, 0xCE, - 0x06, 0x25, 0xBF, 0xD1, 0x5A, 0x50, 0xCF, 0x3B, - 0x52, 0xE2, 0xA7, 0xFF, 0x19, 0x02, 0xCF, 0xD0, - 0x9B, 0xD9, 0xF7, 0x28, 0x07, 0x38, 0x1F, 0xF2, - 0xAF, 0x44, 0x91, 0x3F, 0x0F, 0xB6, 0x6E, 0x8C, - 0xC0, 0x32, 0x92, 0xC0, 0xCD, 0x25, 0x98, 0x67, - 0xF1, 0x47, 0x52, 0x50, 0xF0, 0xA3, 0x7B, 0xE6, - 0x74, 0xDC, 0x72, 0x28, 0xC8, 0xAB, 0xB3, 0x31, - 0x7D, 0xA3, 0xF7, 0xC7, 0xD1, 0xE6, 0x99, 0xB4, - 0xB6, 0x5A, 0x3A, 0x4D, 0x83, 0x4F, 0xB8, 0xB5, - 0x86, 0xF8, 0x37, 0x7F, 0xA0, 0x16, 0x2F, 0x3C, - 0x62, 0x7A, 0xD4, 0x3A, 0xEB, 0xC2, 0xE8, 0x03, - 0x49, 0x17, 0x9E, 0xFB, 0xD7, 0xAF, 0x91, 0x32, - 0xFD, 0xEA, 0x4F, 0x64, 0xC6, 0x6E, 0x02, 0xEA, - 0xC4, 0xC8, 0x1F, 0x16, 0xC5, 0x4C, 0xFB, 0xC5, - 0x42, 0xF5, 0x85, 0x05, 0x92, 0x59, 0x4B, 0x31, - 0xE5, 0xE9, 0x69, 0xE7, 0x02, 0x98, 0x33, 0xBA, - 0x4C, 0x17, 0x09, 0xEF, 0x89, 0x20, 0xFA, 0x83, - 0x9F, 0xAE, 0x0E, 0x1B, 0x7D, 0x98, 0xB9, 0xF2, - 0x3C, 0x0F, 0xB7, 0x1C, 0x72, 0xDF, 0x17, 0x84, - 0x7F, 0x0A, 0xFD, 0x12, 0x3C, 0x6F, 0x68, 0x5D, - 0x45, 0xEB, 0xB8, 0xD6, 0x24, 0x65, 0x42, 0x75, - 0x5C, 0xC2, 0xF3, 0x3A, 0x6A, 0x4E, 0x51, 0x34, - 0x1B, 0xB6, 0x81, 0xB2, 0x8A, 0xEF, 0x28, 0xA4, - 0xC5, 0x88, 0x9A, 0x97, 0xE0, 0xEF, 0x31, 0x12, - 0x01, 0x7E, 0x1B, 0x43, 0x0F, 0x27, 0x80, 0x87, - 0x98, 0xC5, 0xD5, 0x83, 0xCB, 0x4B, 0xB7, 0x01, - 0x79, 0x60, 0xA1, 0x1A, 0x03, 0x05, 0xC6, 0x36, - 0x04, 0x31, 0x3C, 0x06, 0xDB, 0x08, 0xA8, 0xDA, - 0x8E, 0x32, 0x19, 0x91, 0xF1, 0x0D, 0x61, 0x6F, - 0xE4, 0xB2, 0x79, 0x8A, 0xDE, 0xF4, 0xF7, 0xFB, - 0x2C, 0x23, 0x5B, 0xD9, 0x64, 0x2F, 0xB7, 0xB3, - 0x8B, 0xCA, 0xB8, 0x8C, 0x1D, 0x3B, 0x49, 0x05, - 0x38, 0xA1, 0xE5, 0x8C, 0x1A, 0xDC, 0xA5, 0x61, - 0xFE, 0xF4, 0x2B, 0xDC, 0x77, 0x28, 0xF6, 0x19, - 0xE7, 0xB7, 0x8F, 0x4D, 0x27, 0x2D, 0xED, 0x8A, - 0x3F, 0x3D, 0xDC, 0x9F, 0xD1, 0x30, 0xFF, 0xD6, - 0xC3, 0xBE, 0x41, 0x25, 0xE3, 0xA5, 0x9B, 0x73, - 0xDF, 0x6A, 0xD9, 0xF9, 0x70, 0x84, 0x02, 0x4C, - 0x35, 0xD4, 0x3E, 0x05, 0x76, 0x3A, 0xDC, 0x6D, - 0x5A, 0x81, 0xB3, 0x94, 0xF7, 0x22, 0xF7, 0xDC, - 0xC1, 0x43, 0x31, 0x57, 0x5B, 0x42, 0x9A, 0x0B, - 0xF4, 0x95, 0x30, 0xA9, 0xBB, 0xD8, 0x06, 0xFB, - 0x1D, 0x6F, 0x9B, 0xC3, 0xBB, 0xF3, 0xBF, 0xFB, - 0xB4, 0x9F, 0x35, 0x64, 0x0A, 0x69, 0xB7, 0xD1, - 0x3E, 0xCA, 0x78, 0x07, 0x04, 0x03, 0x79, 0xD4, - 0xF3, 0xA8, 0xEC, 0x18, 0xDB, 0x03, 0x5E, 0x47, - 0xD7, 0xD0, 0x56, 0x2C, 0x74, 0x94, 0x86, 0x04, - 0x46, 0xB8, 0xD4, 0x35, 0x0A, 0x7B, 0xE6, 0x78, - 0xC4, 0x43, 0x3C, 0x56, 0xCC, 0x37, 0x8B, 0xFD, - 0xE8, 0xF4, 0x57, 0xEA, 0xAE, 0xCF, 0x36, 0x97, - 0x12, 0xAC, 0x39, 0xCF, 0x7C, 0xEF, 0x22, 0x67, - 0x01, 0xEC, 0xD8, 0x09, 0x49, 0x4E, 0xE3, 0x74, - 0xDD, 0x39, 0xE1, 0x39, 0xD7, 0x0C, 0x5F, 0x1B, - 0xCE, 0x69, 0xBC, 0x72, 0x44, 0x87, 0x64, 0x1C, - 0x08, 0x05, 0x93, 0x69, 0x6D, 0x7F, 0x90, 0x0A, - 0x2C, 0xCB, 0x8A, 0xBB, 0x7F, 0xE3, 0xE0, 0x80, - 0x31, 0xD0, 0x0A, 0x3A, 0x95, 0xFF, 0xF7, 0xB4, - 0x36, 0x38, 0x93, 0xE0, 0x0C, 0x11, 0x37, 0x12, - 0x06, 0xF6, 0xAD, 0xE9, 0xB1, 0x7A, 0x00, 0xF5, - 0xD2, 0x32, 0x6B, 0xD0, 0x27, 0xA5, 0x1B, 0x3D, - 0xE8, 0xDB, 0xCC, 0xA9, 0x1F, 0x1F, 0xB1, 0x99, - 0x3D, 0x7C, 0xB7, 0xCA, 0xDA, 0x27, 0x2C, 0x64, - 0x1C, 0x49, 0xB6, 0x87, 0x44, 0x06, 0x94, 0x9D, - 0xBC, 0x6B, 0x20, 0xA2, 0x68, 0x15, 0x1F, 0xE2, - 0xF2, 0xAD, 0x6D, 0x23, 0x2E, 0x2B, 0x74, 0xE2, - 0x5D, 0xE4, 0xB0, 0xC7, 0x84, 0xCB, 0x64, 0xBF, - 0xE0, 0xA8, 0x18, 0x83, 0xB4, 0xC9, 0xD9, 0x73, - 0xA8, 0xE6, 0xA9, 0x36, 0xD5, 0x63, 0x1E, 0x2C, - 0x2A, 0x55, 0x09, 0x77, 0x5E, 0xB3, 0x4B, 0xEA, - 0xB5, 0xD0, 0x14, 0x5F, 0xEB, 0x50, 0x7B, 0xAA, - 0xEF, 0x94, 0xBA, 0x2B, 0xD7, 0x8A, 0x07, 0xF1, - 0xF9, 0x5E, 0x12, 0x12, 0x21, 0x52, 0xE5, 0x0A, - 0x3E, 0xC0, 0xBC, 0x5D, 0x4C, 0xE2, 0x12, 0x7C, - 0x39, 0xF9, 0x16, 0x9D, 0xBD, 0x96, 0x83, 0x3B, - 0x7F, 0x3D, 0x6A, 0xEC, 0xF1, 0x25, 0xD2, 0xB0, - 0xB0, 0xEB, 0x20, 0x06, 0x07, 0xD6, 0xD9, 0x4C, - 0x07, 0x9A, 0x82, 0xC1, 0xFC, 0xF7, 0x66, 0x15, - 0xBD, 0x62, 0x65, 0xD8, 0x6C, 0xF6, 0x33, 0x7B, - 0x5A, 0x28, 0xEC, 0x90, 0xA1, 0x26, 0x9F, 0xC3, - 0x28, 0x4A, 0x64, 0x50, 0x5F, 0xCA, 0xE2, 0x6D, - 0xB8, 0x0F, 0xE2, 0x94, 0xB5, 0x8E, 0x1F, 0x8A, - 0x8F, 0x6B, 0xA6, 0x86, 0x1F, 0xEE, 0xDC, 0x24, - 0xB4, 0xB8, 0x25, 0xEC, 0x28, 0x2D, 0xF9, 0xCB, - 0x7D, 0x38, 0xFF, 0xC7, 0x74, 0x2E, 0xD3, 0x10, - 0xEC, 0x03, 0x31, 0xEE, 0x83, 0xE7, 0xA4, 0xF7, - 0xBA, 0x28, 0x21, 0xE0, 0x7F, 0xB4, 0xB7, 0xE1, - 0x7A, 0xF9, 0x2B, 0xB0, 0x2C, 0x3B, 0x80, 0x5F, - 0xE0, 0x5D, 0xB2, 0x7E, 0x59, 0xFF, 0x59, 0x07, - 0x58, 0x42, 0x57, 0xEE, 0x44, 0xF1, 0xB1, 0xAD, - 0xBA, 0xDE, 0xCB, 0x1D, 0x8A, 0x36, 0x67, 0xE8, - 0x45, 0xFF, 0x07, 0x8D, 0xEE, 0xA4, 0x51, 0x9C, - 0x4C, 0x83, 0x5D, 0x2E, 0x2F, 0xE1, 0x5B, 0x75, - 0xE8, 0x29, 0xCD, 0x0B, 0x07, 0x62, 0xE0, 0xC3, - 0x0D, 0x1D, 0xEA, 0xCF, 0xF0, 0x8A, 0x65, 0x27, - 0x70, 0x42, 0x9F, 0x26, 0x00, 0x15, 0x70, 0xC5, - 0x4A, 0xF6, 0x25, 0xD0, 0x40, 0x72, 0xE9, 0xC1, - 0x73, 0xFD, 0x48, 0x94, 0xA3, 0x8D, 0x66, 0x63, - 0x96, 0x4F, 0xF7, 0xEE, 0xFB, 0x4C, 0xC7, 0xB8, - 0x6B, 0xE9, 0x90, 0xE1, 0x2A, 0x66, 0x80, 0x99, - 0x3B, 0xB0, 0x1A, 0x6C, 0xF9, 0x0E, 0x72, 0xDA, - 0x8E, 0x4F, 0x46, 0xC2, 0x6A, 0x4B, 0x7A, 0x16, - 0xE5, 0x26, 0x0B, 0x5C, 0xD4, 0x47, 0x34, 0xE5, - 0x37, 0xBE, 0x68, 0x6C, 0xDA, 0xD3, 0x9B, 0x6F, - 0xAE, 0x51, 0x9C, 0x99, 0x0A, 0x5B, 0xF8, 0x37, - 0xBC, 0xDE, 0xFC, 0x93, 0xC5, 0xE7, 0x0F, 0xEF, - 0x0B, 0xA6, 0x07, 0xC2, 0xA6, 0xE6, 0xDA, 0x2D, - 0x1B, 0x49, 0xC9, 0xDE, 0x6B, 0x27, 0xDC, 0x00, - 0xEF, 0x23, 0x87, 0x0E, 0xEB, 0xD1, 0x48, 0x7D, - 0xB4, 0xF2, 0x58, 0xC6, 0x3C, 0xE2, 0x89, 0xBA, - 0xB0, 0x05, 0xAC, 0x94, 0x41, 0x9A, 0xA8, 0xFF, - 0x3E, 0xBC, 0x3A, 0x52, 0x9C, 0xF9, 0x7F, 0x07, - 0x8B, 0xB0, 0x2C, 0x71, 0x83, 0x7B, 0xCF, 0x2E, - 0x7F, 0x7C, 0x96, 0x65, 0xD9, 0x08, 0x17, 0xEC, - 0xFA, 0xDE, 0x4E, 0x40, 0x12, 0x26, 0x70, 0x71, - 0x65, 0xA5, 0xDC, 0x98, 0x47, 0xA3, 0xFC, 0xE0, - 0x9A, 0x16, 0xED, 0x45, 0x56, 0x72, 0x50, 0x05, - 0x28, 0x2C, 0x99, 0xEC, 0x20, 0x2E, 0x40, 0xC0, - 0x26, 0x69, 0xCD, 0x49, 0x45, 0x17, 0xA4, 0xA3, - 0x42, 0x0D, 0x14, 0x65, 0x87, 0x33, 0x8C, 0x92, - 0xC5, 0xC4, 0x61, 0xFD, 0xE8, 0x68, 0x56, 0x20, - 0x57, 0xF5, 0x8E, 0x5F, 0xCF, 0x7E, 0x97, 0xF6, - 0x49, 0x97, 0x0A, 0xFE, 0xD3, 0x60, 0x1A, 0x5B, - 0x0C, 0x75, 0xDD, 0x8E, 0x31, 0x78, 0x29, 0xA6, - 0xB1, 0x4D, 0xAA, 0xDF, 0x8A, 0xD1, 0xE6, 0x91, - 0xE3, 0x32, 0x3F, 0xEC, 0x8A, 0x1F, 0x0E, 0x35, - 0x07, 0x6E, 0x4B, 0x83, 0x3B, 0xE5, 0x67, 0x34, - 0x1F, 0x0C, 0x81, 0xD8, 0xD5, 0x25, 0x68, 0xE5, - 0x28, 0x1B, 0x5C, 0x81, 0x3E, 0xE3, 0x5C, 0xB4, - 0xB6, 0xBD, 0x62, 0x6A, 0x70, 0x33, 0xC2, 0xC5, - 0x75, 0x27, 0xF4, 0x30, 0xE1, 0x1D, 0xC1, 0x4C, - 0xC5, 0x02, 0x12, 0x46, 0xAC, 0xEC, 0xF9, 0xE8, - 0xE7, 0x58, 0x24, 0x11, 0xB1, 0xF3, 0xB7, 0x8C, - 0x3C, 0xA4, 0x0A, 0x94, 0xA6, 0x7C, 0x68, 0x54, - 0x5B, 0xB9, 0x4D, 0x57, 0x9C, 0xE7, 0x28, 0x09, - 0x6B, 0x89, 0x26, 0x5D, 0xE7, 0x50, 0xA9, 0x95, - 0x90, 0x91, 0x8E, 0x00, 0x59, 0xF8, 0x3A, 0x70, - 0xAF, 0x48, 0x2E, 0xE8, 0xC4, 0x34, 0x8C, 0xF4, - 0x5F, 0x7F, 0xCB, 0x07, 0xAA, 0xF0, 0xD9, 0xFB, - 0x5C, 0x32, 0x90, 0x22, 0x1A, 0xD2, 0x1A, 0xCF, - 0x92, 0x06, 0x02, 0xCF, 0x10, 0x18, 0x7B, 0x93, - 0xCC, 0x07, 0x4A, 0x31, 0x25, 0x30, 0x23, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xD1, 0xDE, - 0x23, 0x16, 0x9F, 0x6E, 0xF4, 0x42, 0x21, 0x23, - 0xE1, 0x11, 0xAA, 0xC8, 0x7C, 0x60, 0x4A, 0x78, - 0x9D, 0x24, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, - 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, - 0x00, 0x04, 0x14, 0xD6, 0x4A, 0xBB, 0x75, 0xB1, - 0xF9, 0x9E, 0xD3, 0x58, 0x6D, 0xD1, 0x74, 0x9F, - 0x00, 0x8A, 0xF2, 0xC8, 0xAA, 0x52, 0x4D, 0x04, - 0x08, 0x77, 0x46, 0xE7, 0xBA, 0x25, 0x4B, 0xDA, - 0x41, 0x02, 0x02, 0x08, 0x00] -}; - -const WPA_EAP_CLIENT_LIST = [ - { - ssid: 'WPA-EAP-TLS', - keyManagement: 'WPA-EAP', - eap: 'TLS', - identity: EAP_USERNAME, - serverCertificate: CLIENT_PKCS12_CERT.nickname, - userCertificate: CLIENT_PKCS12_CERT.nickname - } -]; - -/** - * Convert the given MozWifiNetwork object array to testAssociate chain. - * - * @param aNetworks - * An array of MozWifiNetwork which we want to convert. - * - * @return A promise chain which "then"s testAssociate accordingly. - */ -function convertToTestAssociateChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - network = new window.MozWifiNetwork(aNetwork); - chain = chain.then(() => gTestSuite.testAssociate(network)); - }); - - return chain; -} - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(CLIENT_PKCS12_CERT.content)]), - CLIENT_PKCS12_CERT.password, - CLIENT_PKCS12_CERT.nickname, - CLIENT_PKCS12_CERT.usage, - function() { - return gTestSuite.ensureWifiEnabled(true) - // Load required server files. - .then(() => gTestSuite.writeFile(SERVER_EAP_USER_CONF.path, SERVER_EAP_USER_CONF.content)) - .then(() => gTestSuite.writeFile(CA_CERT.path, CA_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_CERT.path, SERVER_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_KEY.path, SERVER_KEY.content)) - // Start AP. - .then(() => gTestSuite.startHostapds(WPA_EAP_AP_LIST)) - // Scan test. - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, WPA_EAP_AP_LIST)) - // Associate test. - .then(() => convertToTestAssociateChain(WPA_EAP_CLIENT_LIST)) - // Tear down. - .then(gTestSuite.killAllHostapd) -}); diff --git a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TTLS.js b/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TTLS.js deleted file mode 100644 index 06e052909..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate_WPA_EAP_TTLS.js +++ /dev/null @@ -1,623 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -const EAP_USERNAME = 'username'; -const EAP_PASSWORD = 'password'; - -const SERVER_EAP_USER_CONF = { - path: HOSTAPD_CONFIG_PATH + 'hostapd.eap_user', - content: '* PEAP,TTLS,TLS\n' + - '"' + EAP_USERNAME + '" MSCHAPV2,TTLS-MSCHAPV2 "' + EAP_PASSWORD + '" [2]\n' -}; -const CA_CERT = { - path: HOSTAPD_CONFIG_PATH + 'ca.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIIDsTCCApmgAwIBAgIJAKxTf+8X8qngMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV\n' + - 'BAYTAlRXMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTER\n' + - 'MA8GA1UEAwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdt\n' + - 'YWlsLmNvbTAgFw0xNDEyMjQxMTI4NTBaGA8yMjg4MTAwNzExMjg1MFowbjELMAkG\n' + - 'A1UEBhMCVFcxEzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAoMCGNodWNrbGVl\n' + - 'MREwDwYDVQQDDAhjaHVja2xlZTEkMCIGCSqGSIb3DQEJARYVY2h1Y2tsaTA3MDZA\n' + - 'Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3c2yFxY\n' + - 'o6gGg0I83jy00ME+MAfzCd+4ShL45ZLqysQP93jRBfPzU9ZuZ29ysVwgWIdqkZao\n' + - 'XTuV/NAW2GMGd8W1jQJ3J81fjb9wvhlny3rrACwvUn1N1S1BnM+BAAiDLGxEmvAQ\n' + - 'onp2aaa6HsHsYS8ONX+d2Qh4LEA4vupeSGAqJychCZv/l+aq/ErFZhFYB3CPUQEt\n' + - 'cClO24ucsIYP95lA0zhscnmAj06qplFD4Bv6IVrdDqujy1zNwCQwsJq/8OQdaTN/\n' + - 'h3y9pWvNKMBMM2niOUAjtuNpqsSK/lTS1WAT3PdtVECX9fYBi0Bg+HM92xs/6gt6\n' + - 'kh9jPV8keXHvSwIDAQABo1AwTjAdBgNVHQ4EFgQU7hBqhuG04xeCzrQ3ngx18ZJ3\n' + - 'lUswHwYDVR0jBBgwFoAU7hBqhuG04xeCzrQ3ngx18ZJ3lUswDAYDVR0TBAUwAwEB\n' + - '/zANBgkqhkiG9w0BAQsFAAOCAQEAFYX2iy680GAnBTttk0gyX6gk+8pYr3D22k/G\n' + - '6rvcjefzS7ELQPRKr6mfmwXq3mMf/4jiS2zI5zmXsestPYzHYxf2viQ6t7vr9XiJ\n' + - '3WfFjNw4ERlRisAvg0aqqTNNQq5v2VME4sdFZagy217f73C7azwCHl0bqOLH05rl\n' + - '8RubOxiHEj7ZybJqnRciK/bht4D+rZkwf4bBBmoloqH7xT0+rFQclpYXDGGjNUQB\n' + - 'LcHLF10xcr7g3ZVVu82fe6+d85gIGOIMR9+TKhdw6gO3CNcnDAj6gxksghgtcxmh\n' + - 'OzOggCn7nlIwImtsg2sZkpWB4lEi9hdv4lkNuyFjOL3bnuc+NA==\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_CERT = { - path: HOSTAPD_CONFIG_PATH + 'server.pem', - content: '-----BEGIN CERTIFICATE-----\n' + - 'MIID1DCCArygAwIBAgIBADANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJUVzET\n' + - 'MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIY2h1Y2tsZWUxETAPBgNVBAMM\n' + - 'CGNodWNrbGVlMSQwIgYJKoZIhvcNAQkBFhVjaHVja2xpMDcwNkBnbWFpbC5jb20w\n' + - 'IBcNMTQxMjI0MTEyOTQ5WhgPMjI4ODEwMDcxMTI5NDlaMG4xCzAJBgNVBAYTAlRX\n' + - 'MRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTERMA8GA1UE\n' + - 'AwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdtYWlsLmNv\n' + - 'bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdhQmKilTJbWZRxTiSV\n' + - 'rqIU+LYW1RKghx5o+0JpNRJVLuz5kBMaNskbbfUSNuHbEq0QA9BDKAZWIc4LSotk\n' + - 'lCo8TbcO9CJvJPQGGjGdHcohWX5vy6BE/OVE46CUteMFyZF6F8R2fNUww08iR/u1\n' + - 'YZebL5pWO1j43sPpAzEy6Tij2ACPt6EZcFaZG3SF2mVJWkCQnBqrojP65WUvZQqp\n' + - 'seUhW2YAS8Nu0Yrohgxz6VYk+cNDuDZVGs6qWRStZzJfYrfc76DtkHof5B14M+xp\n' + - 'XJaBLxN+whvnYkDTfinaCxnW1O7eXUltr87fLc5zmeBkgwaiaQuIdcfZm7vDUiz8\n' + - 'vnUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH\n' + - 'ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKK4f9/YavTHOfEiAB83Deac\n' + - '6gT5MB8GA1UdIwQYMBaAFO4QaobhtOMXgs60N54MdfGSd5VLMA0GCSqGSIb3DQEB\n' + - 'CwUAA4IBAQBWnO9o9KSJIqjoz5Nwll63ULOdcvgGdOeJIw1fcKQ817Rsp+TVcjcH\n' + - 'IrIADsT/QZGXRO/l6p1750e2iFtJEo1hsRaxtA1wWn2I9HO3+av2spQhr3jpYGPf\n' + - 'zpsMTp4RNYV7Q8+q1kZIz9PY4V1T0p6lveK8+fUj2hSLnxSj0QiGSJJtnEC3w4Rv\n' + - 'C9T6oUwIeToULmi+8FXQFdEqwKRU98DPq3eLzN28ZxUgoPE1C8+42D2UW8uyp/Gm\n' + - 'tGOa/k7nzkCdVqZI7lX7f0AjEvQgjtAMQ/k7Mhxx7TzW2HO+1YPMoKji6Z4WkNwt\n' + - 'JEj9ZUBSNt8B26UksJMBDkcvSegF3a7o\n' + - '-----END CERTIFICATE-----\n' -}; - -const SERVER_KEY = { - path: HOSTAPD_CONFIG_PATH + 'server.key', - content: '-----BEGIN RSA PRIVATE KEY-----\n' + - 'MIIEpAIBAAKCAQEAx2FCYqKVMltZlHFOJJWuohT4thbVEqCHHmj7Qmk1ElUu7PmQ\n' + - 'Exo2yRtt9RI24dsSrRAD0EMoBlYhzgtKi2SUKjxNtw70Im8k9AYaMZ0dyiFZfm/L\n' + - 'oET85UTjoJS14wXJkXoXxHZ81TDDTyJH+7Vhl5svmlY7WPjew+kDMTLpOKPYAI+3\n' + - 'oRlwVpkbdIXaZUlaQJCcGquiM/rlZS9lCqmx5SFbZgBLw27RiuiGDHPpViT5w0O4\n' + - 'NlUazqpZFK1nMl9it9zvoO2Qeh/kHXgz7GlcloEvE37CG+diQNN+KdoLGdbU7t5d\n' + - 'SW2vzt8tznOZ4GSDBqJpC4h1x9mbu8NSLPy+dQIDAQABAoIBAASG4Mr8hgaurEoC\n' + - 'iJOsElr7vunjetMBcg/uskW/vcS8ymP3Bp5oafYG+WgnEbfvEW18f5mq7K24JuxW\n' + - 'tUqU7ghHdjxByqk9fMlNmiqmNpbwSufkAeuRpWxPNBvhRH/zEbCL5R5A0nTEtqqF\n' + - 'TL0aUSzwCRSoAJD0lZo9ICVt0n3GsDyM9rqQg/uZmh1qsRdwPsRuYORND9g48rKq\n' + - '6WN9leskSxhhsYE2D9ocOFd9bNt8Zxejh9ppVSnG/KsIdt18iBzcabatgAQ046fb\n' + - 'Z3vprcZJLg93Sg2gSuVqlSTs3M2W8VQnm22/EBMb1y0M48MSRCgnbPLG/CcCLLfF\n' + - 'LwxCOgECgYEA/eYt67xyJ6JeAdxdwOZuT1WWGbFpLiG9+2OgiHumyRQ5969XMTWo\n' + - 'fIhMKchDdjoy9RR236\/\/EFCs7UEyB7+a7ODRzNiK2zCD8Smjp+21fUPSthEeQesk\n' + - 'eiMYICIu5Ay35x9sxIX+XOUVvRhPOGcD29GVeRnKh1inTHOz2dje8LkCgYEAyQeY\n' + - 'STi9jjCEcHkM1E/UeDiLfHHepLXi8wS41JNRHl5Jacp7XB5djAjKu/jf367/VpFy\n' + - 'GDDMetE7n8eWkrnAvovxOwZ000YDMtL1sUYSjL+XtBS5s6VY1p4qaSAY9nUUGrJh\n' + - 'JvtvsuI7SKTtL+60vjBOH7zDnvOdBgAp0utLhZ0CgYEAuLzzqrPKB8afShFSchn4\n' + - 'J2dpuLYahsNsXW7HDqeR2nsKFosRETAusLXnXPtnAq4kB6jlOarwFqnsuRCX24Vx\n' + - 'r2uBm9/vYL7zMdUPTA+s30ErHuhjsKjsOKYyVqcooSwT32pBFNk+E89nutfmRG7I\n' + - 'IvhjHuNCNqqtx/Xj5d1jkZkCgYBQicppC2Jl5OoqZVTOem0U/RJk+PnJ41TZJ7sk\n' + - '7yBAmmWvDH\/\/l+rCf4M5a6vFYcbKV9rt9h711X2dtciNX/3oWQh8LUoAmrwNUJc+\n' + - 'PmSQHvIYI3WCk2vUD+nN1B4sHxu+1lg11eYaNKiroeeknG2tBI1ICcgVlmQCU25u\n' + - 'IfZPwQKBgQCdO6QHhPLtcHUDNFA6FQ1jKL1iEd7G0JLVRz4Xkpkn1Vrr5MD6JFDa\n' + - '5ccabADyl0lpFqDIVJQIzLku2hOD2i9aBNCY0pL391HeOS7CkZX+TdOY1tquoBq5\n' + - 'MnmixZjDCVd2VcrVyTA6ntOBoharKFW0rH1PqU+qu7dZF7CBPbAdEw==\n' + - '-----END RSA PRIVATE KEY-----\n' -}; - -const WPA_EAP_AP_LIST = [ - { - ssid: 'WPA-EAP-TTLS', - ieee8021x: 1, - eapol_version: 1, - eap_server: 1, - eapol_key_index_workaround: 0, - eap_user_file: SERVER_EAP_USER_CONF.path, - ca_cert: CA_CERT.path, - server_cert: SERVER_CERT.path, - private_key: SERVER_KEY.path, - wpa: 3, - wpa_key_mgmt: 'WPA-EAP' - } -]; - -const CLIENT_PKCS12_CERT = { - nickname: 'client', - password: 'password', - usage: ['UserCert', 'ServerCert'], - content: [0x30, 0x82, 0x0E, 0x01, 0x02, 0x01, 0x03, 0x30, - 0x82, 0x0D, 0xC7, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, - 0x0D, 0xB8, 0x04, 0x82, 0x0D, 0xB4, 0x30, 0x82, - 0x0D, 0xB0, 0x30, 0x82, 0x08, 0x67, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, - 0x06, 0xA0, 0x82, 0x08, 0x58, 0x30, 0x82, 0x08, - 0x54, 0x02, 0x01, 0x00, 0x30, 0x82, 0x08, 0x4D, - 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, - 0x06, 0x30, 0x0E, 0x04, 0x08, 0x67, 0x7A, 0xF3, - 0x61, 0xBE, 0xE0, 0x51, 0xC1, 0x02, 0x02, 0x08, - 0x00, 0x80, 0x82, 0x08, 0x20, 0xFC, 0x6A, 0x79, - 0xA1, 0x6C, 0xAF, 0xBE, 0xEE, 0x62, 0x45, 0x33, - 0xB8, 0x48, 0xE1, 0x68, 0xA1, 0x15, 0x11, 0x4B, - 0x95, 0xCB, 0x77, 0xC0, 0x5D, 0xA2, 0xCB, 0xDB, - 0xD1, 0x83, 0x74, 0x60, 0xD7, 0xEC, 0x42, 0xA6, - 0x3A, 0x23, 0xF7, 0x85, 0xEB, 0xC1, 0xFE, 0x6A, - 0x57, 0x8E, 0xC1, 0x44, 0xF3, 0x1F, 0xFE, 0xB8, - 0x2D, 0x8C, 0x4D, 0xC9, 0x5B, 0xAE, 0x21, 0x2E, - 0x4C, 0x1A, 0xEB, 0x84, 0x09, 0xF3, 0x40, 0x92, - 0x39, 0x7F, 0x56, 0x02, 0x46, 0x61, 0x16, 0xDE, - 0x5C, 0x48, 0xB6, 0x0C, 0x1D, 0xD3, 0x5F, 0x10, - 0x9A, 0x39, 0xB8, 0x66, 0x31, 0xFC, 0x39, 0x71, - 0x87, 0x23, 0x46, 0x9D, 0xE8, 0x3C, 0x2B, 0xA1, - 0x39, 0x8A, 0xD3, 0xFF, 0xD9, 0x43, 0xB6, 0x61, - 0xC6, 0x67, 0x70, 0x40, 0xBD, 0xFE, 0xD3, 0xC1, - 0x68, 0xF5, 0xF7, 0xC8, 0x89, 0xD8, 0x17, 0xC5, - 0xE8, 0x3D, 0x29, 0xD5, 0x91, 0xDF, 0x1F, 0x56, - 0x74, 0x5A, 0xC4, 0xA8, 0x14, 0xBA, 0xD4, 0xFA, - 0x13, 0x49, 0x2A, 0x9F, 0x63, 0xF1, 0xB2, 0x45, - 0xF1, 0xF0, 0x2A, 0xDD, 0x75, 0x66, 0x8A, 0xF7, - 0xAB, 0x73, 0x86, 0x26, 0x9D, 0x1F, 0x07, 0xAD, - 0xD3, 0xFE, 0xE0, 0xA3, 0xED, 0xA0, 0x96, 0x3E, - 0x1E, 0x89, 0x86, 0x02, 0x4C, 0x28, 0xFD, 0x57, - 0xA1, 0x67, 0x55, 0xF0, 0x82, 0x3B, 0x7F, 0xCC, - 0x2A, 0x32, 0x01, 0x93, 0x1D, 0x8B, 0x66, 0x8A, - 0x20, 0x52, 0x84, 0xDD, 0x2C, 0xFD, 0xEE, 0x72, - 0xF3, 0x8C, 0x58, 0xB9, 0x99, 0xE5, 0xC1, 0x22, - 0x63, 0x59, 0x00, 0xE2, 0x76, 0xC5, 0x3A, 0x17, - 0x7F, 0x93, 0xE9, 0x67, 0x61, 0xAA, 0x10, 0xC3, - 0xD9, 0xC8, 0x24, 0x46, 0x5B, 0xBE, 0x8C, 0x1F, - 0x2D, 0x66, 0x48, 0xD2, 0x02, 0x11, 0xFB, 0x74, - 0x14, 0x76, 0x76, 0x5A, 0x98, 0x54, 0x35, 0xA7, - 0x85, 0x66, 0x20, 0x26, 0x8B, 0x13, 0x6F, 0x68, - 0xE3, 0xC9, 0x58, 0x7D, 0x1C, 0x3E, 0x01, 0x8D, - 0xF8, 0xD6, 0x7F, 0xCF, 0xA2, 0x07, 0xB7, 0x95, - 0xFD, 0xF0, 0x02, 0x34, 0x32, 0x30, 0xE8, 0xD4, - 0x57, 0x5E, 0x53, 0xFB, 0x54, 0xE2, 0x03, 0x32, - 0xCC, 0x52, 0x2E, 0xD2, 0x35, 0xD9, 0x58, 0x85, - 0x2D, 0xEC, 0x2D, 0x71, 0xD1, 0x8A, 0x29, 0xD0, - 0xB0, 0x24, 0xBD, 0x24, 0xDC, 0x1A, 0x28, 0x3F, - 0xA0, 0x12, 0x81, 0x15, 0x24, 0xC9, 0xB5, 0x4A, - 0x23, 0xB6, 0xA3, 0x45, 0x50, 0x2D, 0x73, 0x99, - 0x6B, 0x1C, 0xFB, 0xA4, 0x53, 0xD7, 0x5C, 0xF4, - 0x6C, 0xB0, 0xE5, 0x74, 0xB3, 0x76, 0xF8, 0xB1, - 0x0D, 0x59, 0x70, 0x9F, 0xCA, 0xDE, 0xF2, 0xAA, - 0x4C, 0x7D, 0x11, 0x54, 0xC4, 0x19, 0x0F, 0x36, - 0x4A, 0x62, 0xFF, 0x8B, 0x10, 0xCB, 0x93, 0x50, - 0xDA, 0x79, 0x5E, 0x4E, 0x09, 0x1F, 0x22, 0xC8, - 0x19, 0x85, 0xE9, 0xEE, 0xB7, 0x71, 0x65, 0xB9, - 0x10, 0xD2, 0x0A, 0x73, 0x5B, 0xA6, 0xDA, 0x37, - 0x46, 0x02, 0x00, 0x98, 0x9E, 0x20, 0x6C, 0x7D, - 0xC7, 0x69, 0xBB, 0xC2, 0x00, 0x40, 0x9C, 0x57, - 0x00, 0xC2, 0x36, 0x76, 0xE8, 0x2A, 0x8D, 0xAD, - 0x62, 0x57, 0xC8, 0xD0, 0x9D, 0x66, 0x27, 0x5A, - 0xD8, 0x0D, 0x35, 0x60, 0x28, 0x38, 0x62, 0x94, - 0x78, 0x36, 0x25, 0x58, 0xFD, 0xF8, 0x66, 0x1F, - 0x68, 0x04, 0x0F, 0xD8, 0x00, 0xDF, 0xA0, 0x6C, - 0x25, 0x42, 0x9A, 0x4C, 0xEB, 0x80, 0x13, 0x51, - 0x7D, 0x2D, 0xA8, 0x89, 0xD6, 0x1B, 0x67, 0x72, - 0x01, 0xF3, 0x2D, 0x16, 0x77, 0xFE, 0x22, 0xBC, - 0x8A, 0x45, 0x09, 0x1F, 0x9C, 0x2F, 0x2A, 0xA9, - 0x61, 0x5B, 0x4A, 0xE6, 0x64, 0x2C, 0x62, 0x1A, - 0x3A, 0x96, 0xE6, 0x0A, 0xAE, 0x05, 0x1A, 0xC8, - 0xCB, 0xD6, 0x8F, 0x3A, 0x4B, 0xE0, 0x7F, 0x82, - 0xB4, 0x98, 0xF1, 0x9D, 0xD7, 0x14, 0x76, 0x5E, - 0x77, 0x85, 0x87, 0xEC, 0x13, 0xDA, 0xFD, 0xAF, - 0xCB, 0xA3, 0x1C, 0x99, 0xC1, 0xFE, 0x17, 0x0C, - 0x40, 0x4D, 0x3C, 0x8F, 0x70, 0x86, 0x63, 0x64, - 0xB7, 0x75, 0xA8, 0x71, 0x36, 0xDC, 0x54, 0x10, - 0x57, 0x0C, 0xA8, 0xF2, 0xA1, 0xBB, 0xED, 0x03, - 0x41, 0x57, 0x34, 0x2C, 0x8F, 0x7C, 0xA0, 0x09, - 0xF3, 0x9E, 0x41, 0xB7, 0xA8, 0xD4, 0x66, 0x0D, - 0x0D, 0xC0, 0x6A, 0xFC, 0x6A, 0xA2, 0xAC, 0xE2, - 0x60, 0x00, 0xE3, 0xF7, 0x75, 0x43, 0x23, 0xEB, - 0xC8, 0x61, 0xFA, 0xB3, 0xB8, 0x28, 0xCE, 0xCA, - 0xF4, 0x47, 0x7F, 0x30, 0x6D, 0x61, 0x89, 0x47, - 0xA1, 0x4A, 0xFE, 0xD1, 0x21, 0x0B, 0x6D, 0xF4, - 0x3F, 0x00, 0x86, 0x30, 0x8E, 0x33, 0x21, 0x6F, - 0xDA, 0x15, 0xFD, 0x5F, 0xEC, 0x8E, 0xF1, 0x12, - 0x3F, 0xC9, 0x83, 0x0C, 0xCA, 0x22, 0x01, 0xF1, - 0x70, 0x5F, 0x1F, 0x66, 0xB5, 0xF8, 0x3E, 0x7A, - 0x6F, 0xDE, 0xDB, 0xA7, 0x8D, 0x18, 0x9E, 0xBE, - 0xDB, 0xAD, 0x3D, 0x66, 0x30, 0xC1, 0x6C, 0x0C, - 0x87, 0xB4, 0x65, 0x75, 0xE0, 0x9D, 0xEA, 0x16, - 0x0D, 0x07, 0x37, 0x33, 0xC5, 0xEC, 0x97, 0x93, - 0x37, 0xEB, 0x8E, 0x65, 0x9C, 0x40, 0x63, 0x6C, - 0x43, 0x60, 0xB0, 0x40, 0x4D, 0x85, 0xEF, 0xC2, - 0x47, 0x5F, 0xE7, 0x6B, 0xCB, 0x40, 0xE8, 0xEA, - 0xD8, 0xAB, 0xB1, 0x9A, 0x72, 0xDC, 0x4C, 0x14, - 0xFA, 0x43, 0x61, 0x5F, 0xA6, 0x5C, 0x3A, 0x05, - 0x17, 0x2E, 0x74, 0xF3, 0x5E, 0x45, 0xD9, 0x47, - 0xAA, 0x59, 0xB6, 0x8F, 0x42, 0x66, 0x42, 0x29, - 0x90, 0x95, 0x48, 0x46, 0x91, 0x88, 0x3C, 0x8C, - 0xDE, 0xCC, 0xED, 0xB3, 0xAA, 0x62, 0xEA, 0xBC, - 0xB4, 0x0C, 0x48, 0x4C, 0x53, 0x23, 0x5E, 0x24, - 0x85, 0xBF, 0x92, 0xDA, 0x14, 0xDB, 0x1A, 0x3D, - 0xEF, 0x30, 0xD9, 0x49, 0x64, 0x4D, 0xE5, 0x01, - 0xFC, 0xA4, 0x4B, 0xD1, 0x9F, 0xDE, 0x96, 0x7F, - 0x50, 0xBC, 0x4D, 0x38, 0x44, 0xE9, 0x23, 0x5F, - 0x37, 0x57, 0x1A, 0xA6, 0x52, 0x5A, 0x0F, 0x4F, - 0x87, 0x33, 0x4A, 0x7B, 0x66, 0xEE, 0x3D, 0x66, - 0x0A, 0x63, 0x39, 0x1F, 0x23, 0x38, 0x35, 0x73, - 0x60, 0x5E, 0x47, 0x20, 0x4F, 0xC0, 0xC8, 0x3C, - 0x09, 0xF9, 0x29, 0x4F, 0x5E, 0x55, 0x69, 0xC4, - 0x6B, 0xE8, 0xF8, 0x91, 0xC0, 0x22, 0x65, 0x15, - 0x1E, 0xFB, 0xB9, 0x61, 0xCE, 0x45, 0xBE, 0x2B, - 0xEE, 0xB9, 0x04, 0x2B, 0xFD, 0xAE, 0x61, 0x1C, - 0x3D, 0x3D, 0x7C, 0xBF, 0xC1, 0xF7, 0x3C, 0x4E, - 0x9E, 0x0E, 0x54, 0xC8, 0xAD, 0xA9, 0xDF, 0x43, - 0x49, 0xB9, 0x41, 0x05, 0xE5, 0xF1, 0x49, 0xAA, - 0x77, 0x6C, 0x34, 0x5B, 0x93, 0x24, 0x24, 0x23, - 0x74, 0x68, 0x11, 0xCE, 0x15, 0x80, 0xA1, 0xA4, - 0x1F, 0x8D, 0x81, 0xCD, 0xB2, 0x98, 0xCA, 0x14, - 0x0B, 0x0C, 0x61, 0x50, 0x69, 0x72, 0xAE, 0xFA, - 0x8B, 0xC0, 0x3F, 0x0D, 0xE7, 0xF2, 0x0F, 0xEB, - 0xC1, 0x11, 0xB9, 0x10, 0x03, 0x6A, 0xF5, 0x97, - 0x3C, 0x53, 0x2F, 0x67, 0x86, 0x09, 0x6A, 0xE3, - 0x28, 0xC0, 0x78, 0xC8, 0xB4, 0x39, 0x8E, 0xD1, - 0xCE, 0x25, 0xE8, 0x66, 0xF7, 0x09, 0x40, 0x7D, - 0x81, 0xFB, 0xAF, 0xFA, 0x59, 0xC4, 0x9B, 0x2B, - 0x83, 0x45, 0x5B, 0xA8, 0x66, 0x9E, 0x38, 0xC8, - 0xFD, 0xAC, 0xF2, 0x2D, 0x21, 0xDE, 0x50, 0x4C, - 0x03, 0xCB, 0x88, 0x42, 0xDD, 0x84, 0x09, 0x99, - 0x8E, 0x8B, 0x40, 0x97, 0x1B, 0x14, 0x85, 0x37, - 0x11, 0x01, 0xE0, 0x74, 0x6B, 0x33, 0x52, 0x8C, - 0x68, 0x3A, 0x89, 0xB2, 0xAF, 0x35, 0xE6, 0x65, - 0xC3, 0x58, 0x70, 0xD2, 0xE7, 0x1F, 0x1F, 0xF6, - 0xE5, 0x0A, 0xB1, 0xFE, 0xD0, 0xC9, 0x51, 0x50, - 0xE7, 0xFD, 0x58, 0xF5, 0xC4, 0x58, 0x65, 0x94, - 0xD1, 0x57, 0x55, 0x5E, 0xD2, 0x27, 0x98, 0xAF, - 0xE7, 0x55, 0x0B, 0x87, 0x50, 0x9B, 0xEF, 0xE8, - 0x2B, 0xFC, 0xE7, 0x3B, 0x4E, 0xD7, 0xB7, 0x4D, - 0xF4, 0xBC, 0xF4, 0x88, 0x63, 0xE4, 0x8A, 0x20, - 0x4B, 0x22, 0xB0, 0xA0, 0x53, 0x7F, 0xA8, 0xC9, - 0x0C, 0xF8, 0xD7, 0xBD, 0x46, 0x39, 0xA7, 0x7D, - 0xDD, 0x10, 0x91, 0x50, 0x54, 0x06, 0x47, 0xF0, - 0x3C, 0xAA, 0x43, 0x40, 0xF8, 0x54, 0xDD, 0x8A, - 0xEA, 0x8A, 0x0B, 0xA5, 0x7F, 0xCD, 0x5E, 0xAA, - 0x02, 0x2E, 0x1F, 0xC6, 0x50, 0x15, 0xF8, 0x0A, - 0x0C, 0x1B, 0x3C, 0x55, 0x3A, 0xC3, 0x6F, 0x88, - 0xD7, 0xBF, 0xB1, 0x02, 0xCC, 0xE0, 0x08, 0x29, - 0x97, 0xD2, 0xAA, 0x23, 0xC4, 0x6D, 0xE3, 0xE3, - 0x76, 0x39, 0x92, 0xC3, 0x2E, 0x7A, 0xE2, 0x98, - 0xD1, 0xFC, 0xAE, 0xCC, 0x95, 0xD8, 0xB4, 0xDC, - 0x92, 0xEA, 0x6A, 0x5F, 0xF2, 0x92, 0x17, 0x0B, - 0x8D, 0xC3, 0xFA, 0x9C, 0x62, 0xCE, 0x44, 0x8D, - 0xC3, 0x1E, 0xC3, 0xB2, 0xD5, 0x00, 0xCD, 0xB4, - 0x9E, 0x2D, 0x7B, 0xF2, 0x98, 0xA3, 0x00, 0x8B, - 0x81, 0x30, 0x77, 0x5B, 0x02, 0x99, 0xB1, 0xCD, - 0xC3, 0x1D, 0x74, 0x74, 0xEF, 0x41, 0xCB, 0x69, - 0x63, 0x8E, 0xA6, 0xD3, 0x2D, 0x3E, 0x1F, 0x1D, - 0x12, 0x9E, 0xD9, 0x18, 0x67, 0x06, 0xAF, 0x37, - 0x29, 0xAD, 0x65, 0xD8, 0xEB, 0x71, 0xC4, 0x7D, - 0x94, 0x3D, 0xEA, 0xCC, 0xDF, 0x72, 0x41, 0x51, - 0x3C, 0xA1, 0x66, 0x98, 0x32, 0x32, 0x40, 0x54, - 0xB0, 0x2F, 0xEB, 0xCE, 0xDF, 0x4A, 0x64, 0xFB, - 0x9A, 0x90, 0xDC, 0xF6, 0x6F, 0xA9, 0xD4, 0xCA, - 0xCB, 0x91, 0xC4, 0xFE, 0xEE, 0x9C, 0x01, 0x50, - 0x2E, 0xAC, 0xCC, 0x5F, 0x89, 0xD0, 0x91, 0xA3, - 0xD9, 0xF9, 0x4B, 0x8D, 0xDE, 0x6C, 0x60, 0x21, - 0x19, 0xB1, 0xD3, 0x4D, 0x75, 0x56, 0x6F, 0xB8, - 0x25, 0xA4, 0x92, 0x4F, 0x12, 0xF5, 0x8F, 0xC1, - 0x17, 0x4B, 0xB3, 0x34, 0x21, 0x22, 0xAC, 0x52, - 0xD2, 0x64, 0xC9, 0x9A, 0x7D, 0xFC, 0xC0, 0x0A, - 0x89, 0x34, 0xFF, 0x08, 0xD3, 0x04, 0xDC, 0xFE, - 0x7C, 0xB3, 0xB8, 0xFD, 0x85, 0xDD, 0x79, 0x51, - 0xA7, 0x89, 0xE8, 0xF1, 0x23, 0xB1, 0xDF, 0xD7, - 0x1F, 0x7B, 0xB1, 0x5D, 0x42, 0xF9, 0x61, 0xF8, - 0xDC, 0x81, 0x04, 0xF1, 0xCC, 0xFA, 0xD7, 0xED, - 0xBF, 0x47, 0xAC, 0xBD, 0xE5, 0xFA, 0xAC, 0xB3, - 0x1C, 0xD9, 0xA1, 0xB3, 0x60, 0xEE, 0x9C, 0x8A, - 0x36, 0x57, 0xB4, 0x2F, 0xA1, 0xA2, 0xF3, 0xE2, - 0x09, 0x9A, 0x6E, 0x43, 0x9B, 0xE5, 0x93, 0xB8, - 0x3D, 0x9E, 0x9F, 0xC1, 0xC6, 0x0D, 0x02, 0xEB, - 0x4D, 0x38, 0xE9, 0xB4, 0x9F, 0xEA, 0x33, 0x8C, - 0x07, 0xD8, 0xB4, 0x71, 0xAD, 0xE5, 0x43, 0xB2, - 0xCC, 0x55, 0x93, 0x6A, 0xDB, 0x1E, 0x80, 0xDB, - 0xC2, 0xEA, 0x42, 0x8E, 0xFC, 0x86, 0x44, 0xC9, - 0x8A, 0xC4, 0xF2, 0x46, 0xA7, 0x39, 0x50, 0x0D, - 0x1A, 0xAA, 0x07, 0x04, 0xBE, 0xD4, 0xCE, 0x62, - 0x4D, 0x0F, 0x91, 0x7D, 0x29, 0x88, 0x9C, 0x4C, - 0xAF, 0xF7, 0xD8, 0x40, 0x93, 0x88, 0xC7, 0x20, - 0xD2, 0x17, 0x2A, 0xC4, 0x92, 0x72, 0xD0, 0xC0, - 0x4E, 0x56, 0x47, 0xB1, 0x27, 0x02, 0xE6, 0x61, - 0x82, 0x5E, 0xC8, 0x2E, 0x90, 0xD2, 0x31, 0x22, - 0xE2, 0xA9, 0x4A, 0x91, 0x45, 0x69, 0xB1, 0xA5, - 0x0F, 0x66, 0x2C, 0x30, 0xAD, 0x7F, 0x1B, 0x0E, - 0x22, 0x17, 0x60, 0x2E, 0x3D, 0x7F, 0x7F, 0x8C, - 0x33, 0x51, 0xA0, 0x25, 0xDE, 0xFD, 0x75, 0xBC, - 0xEF, 0xE6, 0xE7, 0x20, 0x04, 0x5A, 0xEC, 0x50, - 0x21, 0x48, 0x56, 0x98, 0xE2, 0x33, 0x6D, 0x22, - 0x5C, 0xC3, 0xFB, 0xFC, 0x6F, 0xB3, 0xA7, 0x8E, - 0x6F, 0x67, 0x70, 0x9D, 0xDA, 0x02, 0x01, 0x59, - 0x7B, 0x3D, 0x2B, 0x38, 0xCC, 0x0F, 0x44, 0x3D, - 0xFB, 0x9A, 0xB3, 0x23, 0x15, 0x50, 0x6E, 0xBF, - 0x8B, 0xA1, 0x94, 0x33, 0xE5, 0x7B, 0x88, 0x4E, - 0xCB, 0x6D, 0x9F, 0xBF, 0xBC, 0x7A, 0xA8, 0x1E, - 0x68, 0x25, 0xED, 0x8E, 0x53, 0x21, 0x72, 0xC5, - 0x70, 0xB3, 0xE4, 0xA6, 0xA1, 0x5A, 0x2D, 0xC8, - 0x43, 0x9D, 0x60, 0x77, 0x78, 0xE0, 0xC4, 0xAF, - 0xC8, 0x29, 0xBA, 0xD0, 0x4D, 0x39, 0x83, 0x51, - 0xA7, 0x10, 0x7F, 0x0C, 0x34, 0x0E, 0x6C, 0x75, - 0x26, 0xD7, 0xD6, 0xC7, 0x32, 0x53, 0xAF, 0x4E, - 0xBE, 0xF2, 0xC2, 0x0F, 0x99, 0x23, 0xB9, 0xE1, - 0xC8, 0xB4, 0xBC, 0x5A, 0xC6, 0xCB, 0xEB, 0x4D, - 0x28, 0x56, 0x72, 0xFE, 0x1B, 0x2C, 0x5D, 0xE3, - 0xBC, 0xC7, 0xA3, 0xC0, 0x7D, 0x27, 0xF0, 0xD0, - 0x4F, 0x3F, 0x1F, 0xF7, 0x87, 0x15, 0xF2, 0xEA, - 0xD4, 0x03, 0x6D, 0x2F, 0xD4, 0x8E, 0x50, 0x4B, - 0x05, 0xBF, 0xF7, 0x8C, 0x67, 0x5A, 0xDC, 0x4D, - 0xCD, 0xCF, 0x9D, 0x02, 0xB6, 0xE7, 0xAE, 0x49, - 0xD1, 0x7C, 0x00, 0xE7, 0x3B, 0xEA, 0xFB, 0x0D, - 0x2A, 0x7B, 0x41, 0x33, 0x66, 0xD0, 0x29, 0x9F, - 0xB3, 0x8A, 0x71, 0xB0, 0xE2, 0x76, 0xA9, 0xDB, - 0xFD, 0x64, 0x04, 0x69, 0xDF, 0x89, 0x1F, 0x56, - 0x86, 0x92, 0xD9, 0xD9, 0xB9, 0xF3, 0x4F, 0xAC, - 0xAE, 0x61, 0x48, 0x20, 0xCE, 0x3C, 0x2B, 0x44, - 0xAB, 0x42, 0xFA, 0xAB, 0x2E, 0x94, 0x82, 0xC8, - 0xD9, 0x97, 0xCF, 0x27, 0xDF, 0xAC, 0xAC, 0xE7, - 0xCA, 0xB2, 0x84, 0xAB, 0xF2, 0x5D, 0xDF, 0x56, - 0x0C, 0x8C, 0x07, 0x3C, 0x3D, 0xA8, 0xDD, 0xBE, - 0xFF, 0x4E, 0x28, 0x0D, 0xB2, 0x2D, 0xE6, 0x9D, - 0x44, 0x21, 0xCB, 0xE7, 0x33, 0x63, 0x22, 0x8F, - 0x4C, 0xFF, 0xB6, 0x1D, 0x9A, 0x71, 0x3F, 0xB1, - 0x29, 0xAE, 0x3A, 0x35, 0xEE, 0x9C, 0x97, 0x68, - 0xA7, 0x52, 0x66, 0x01, 0xD8, 0x9A, 0x5D, 0xF4, - 0xB3, 0x2F, 0x5C, 0xD4, 0x0E, 0xF9, 0xCF, 0x07, - 0xF6, 0x8C, 0xBA, 0xA6, 0x8D, 0x6B, 0xC6, 0x01, - 0xC2, 0x69, 0xAE, 0x60, 0x08, 0x1A, 0x0E, 0x3F, - 0xAE, 0x60, 0x29, 0xF3, 0x48, 0x0D, 0xE0, 0xD0, - 0xAE, 0x52, 0x44, 0xE9, 0x7F, 0x1F, 0x92, 0x5F, - 0x71, 0xAD, 0xEC, 0x6B, 0x47, 0x66, 0x92, 0x22, - 0x27, 0xAE, 0x6E, 0x25, 0xCD, 0xF3, 0x5F, 0x55, - 0x59, 0xBD, 0x73, 0xCE, 0x2B, 0x7E, 0x99, 0x44, - 0x56, 0x70, 0xA3, 0xE7, 0x7A, 0x59, 0x75, 0xD8, - 0x48, 0x0C, 0x39, 0x2B, 0xD7, 0x53, 0xC6, 0xAD, - 0x4A, 0x6F, 0xB4, 0x14, 0x96, 0xDF, 0xF2, 0x4A, - 0x0C, 0xA2, 0xD5, 0x29, 0x98, 0x7C, 0x42, 0x87, - 0xD9, 0x1F, 0x97, 0x61, 0xD9, 0xBF, 0x99, 0x4F, - 0x2C, 0x4C, 0x75, 0xAC, 0xB8, 0x06, 0x75, 0xD6, - 0x87, 0x76, 0x7E, 0xE3, 0x23, 0x4B, 0xEA, 0x1A, - 0x1A, 0xF4, 0xB7, 0x09, 0xAF, 0x53, 0xEB, 0xA6, - 0x39, 0x10, 0xFE, 0xD4, 0xEB, 0x1B, 0xAE, 0x38, - 0x31, 0x33, 0xBA, 0x68, 0xEE, 0xC7, 0x65, 0x76, - 0xFB, 0x49, 0x77, 0xD4, 0x19, 0xC4, 0xE6, 0xA7, - 0x05, 0xFE, 0x2A, 0xDA, 0x39, 0x99, 0x1A, 0x92, - 0xD2, 0xF0, 0x61, 0x97, 0xF6, 0x06, 0x6C, 0x88, - 0x7B, 0x6F, 0x60, 0xE6, 0x70, 0x08, 0xF0, 0xB4, - 0x6B, 0x39, 0x6F, 0x05, 0x41, 0x81, 0xF9, 0xBE, - 0x7A, 0x51, 0xC4, 0x75, 0xB0, 0x6A, 0x89, 0xA0, - 0xA6, 0x9A, 0x5B, 0xEE, 0x7D, 0x78, 0x17, 0x5F, - 0x9F, 0x3B, 0x7D, 0xDD, 0x8A, 0x9E, 0xAA, 0x1A, - 0xDA, 0x49, 0x08, 0xE9, 0xFD, 0x91, 0xA6, 0xFA, - 0xCE, 0xCF, 0x67, 0xDF, 0x0F, 0xC9, 0xD6, 0x38, - 0xD9, 0xD5, 0xD1, 0xC0, 0x76, 0x59, 0x42, 0x53, - 0xBF, 0x48, 0xE9, 0x11, 0x74, 0xC7, 0x11, 0xD8, - 0xE7, 0x8E, 0xD3, 0xC8, 0x25, 0xA1, 0x26, 0x50, - 0xBB, 0xB4, 0x35, 0xAF, 0xAF, 0x06, 0x23, 0x69, - 0x3E, 0x30, 0xFD, 0x7B, 0x34, 0x83, 0x07, 0xD0, - 0xF0, 0x0F, 0x6C, 0x9A, 0x13, 0x5D, 0xC2, 0x7B, - 0xDF, 0x6F, 0xDD, 0x8E, 0xF4, 0x30, 0x82, 0x05, - 0x41, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x05, 0x32, - 0x04, 0x82, 0x05, 0x2E, 0x30, 0x82, 0x05, 0x2A, - 0x30, 0x82, 0x05, 0x26, 0x06, 0x0B, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, - 0x02, 0xA0, 0x82, 0x04, 0xEE, 0x30, 0x82, 0x04, - 0xEA, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, - 0x0E, 0x04, 0x08, 0x74, 0xC0, 0x84, 0x8F, 0xC7, - 0x74, 0x5E, 0x21, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x04, 0xC8, 0x1E, 0xF4, 0xE9, 0x07, 0x27, - 0x9E, 0x5A, 0xC9, 0x39, 0x1D, 0x37, 0x2C, 0x06, - 0x4B, 0x57, 0xEA, 0xC5, 0x42, 0x9A, 0x60, 0xD5, - 0x42, 0xB2, 0x34, 0x2D, 0xD3, 0x88, 0x7C, 0x78, - 0x87, 0xB6, 0xE9, 0x42, 0x44, 0x1F, 0x67, 0x32, - 0x92, 0x54, 0x22, 0xDA, 0xB2, 0x43, 0xE7, 0x40, - 0xBE, 0x1F, 0xAF, 0x3A, 0xCD, 0x2A, 0x9F, 0xD7, - 0x44, 0x5B, 0x37, 0x69, 0x85, 0xDF, 0xEB, 0x2A, - 0xB9, 0xE2, 0x92, 0x3B, 0xEA, 0xD5, 0x42, 0x53, - 0x95, 0x4A, 0xB0, 0x1B, 0xA5, 0xEF, 0xA6, 0x0D, - 0x29, 0xF4, 0x33, 0xFE, 0xD7, 0x49, 0x04, 0x1E, - 0x8C, 0xAD, 0x63, 0x1E, 0x79, 0x63, 0x74, 0x0C, - 0xE5, 0x5E, 0xA2, 0x2C, 0xBE, 0xB8, 0x90, 0xCE, - 0x06, 0x25, 0xBF, 0xD1, 0x5A, 0x50, 0xCF, 0x3B, - 0x52, 0xE2, 0xA7, 0xFF, 0x19, 0x02, 0xCF, 0xD0, - 0x9B, 0xD9, 0xF7, 0x28, 0x07, 0x38, 0x1F, 0xF2, - 0xAF, 0x44, 0x91, 0x3F, 0x0F, 0xB6, 0x6E, 0x8C, - 0xC0, 0x32, 0x92, 0xC0, 0xCD, 0x25, 0x98, 0x67, - 0xF1, 0x47, 0x52, 0x50, 0xF0, 0xA3, 0x7B, 0xE6, - 0x74, 0xDC, 0x72, 0x28, 0xC8, 0xAB, 0xB3, 0x31, - 0x7D, 0xA3, 0xF7, 0xC7, 0xD1, 0xE6, 0x99, 0xB4, - 0xB6, 0x5A, 0x3A, 0x4D, 0x83, 0x4F, 0xB8, 0xB5, - 0x86, 0xF8, 0x37, 0x7F, 0xA0, 0x16, 0x2F, 0x3C, - 0x62, 0x7A, 0xD4, 0x3A, 0xEB, 0xC2, 0xE8, 0x03, - 0x49, 0x17, 0x9E, 0xFB, 0xD7, 0xAF, 0x91, 0x32, - 0xFD, 0xEA, 0x4F, 0x64, 0xC6, 0x6E, 0x02, 0xEA, - 0xC4, 0xC8, 0x1F, 0x16, 0xC5, 0x4C, 0xFB, 0xC5, - 0x42, 0xF5, 0x85, 0x05, 0x92, 0x59, 0x4B, 0x31, - 0xE5, 0xE9, 0x69, 0xE7, 0x02, 0x98, 0x33, 0xBA, - 0x4C, 0x17, 0x09, 0xEF, 0x89, 0x20, 0xFA, 0x83, - 0x9F, 0xAE, 0x0E, 0x1B, 0x7D, 0x98, 0xB9, 0xF2, - 0x3C, 0x0F, 0xB7, 0x1C, 0x72, 0xDF, 0x17, 0x84, - 0x7F, 0x0A, 0xFD, 0x12, 0x3C, 0x6F, 0x68, 0x5D, - 0x45, 0xEB, 0xB8, 0xD6, 0x24, 0x65, 0x42, 0x75, - 0x5C, 0xC2, 0xF3, 0x3A, 0x6A, 0x4E, 0x51, 0x34, - 0x1B, 0xB6, 0x81, 0xB2, 0x8A, 0xEF, 0x28, 0xA4, - 0xC5, 0x88, 0x9A, 0x97, 0xE0, 0xEF, 0x31, 0x12, - 0x01, 0x7E, 0x1B, 0x43, 0x0F, 0x27, 0x80, 0x87, - 0x98, 0xC5, 0xD5, 0x83, 0xCB, 0x4B, 0xB7, 0x01, - 0x79, 0x60, 0xA1, 0x1A, 0x03, 0x05, 0xC6, 0x36, - 0x04, 0x31, 0x3C, 0x06, 0xDB, 0x08, 0xA8, 0xDA, - 0x8E, 0x32, 0x19, 0x91, 0xF1, 0x0D, 0x61, 0x6F, - 0xE4, 0xB2, 0x79, 0x8A, 0xDE, 0xF4, 0xF7, 0xFB, - 0x2C, 0x23, 0x5B, 0xD9, 0x64, 0x2F, 0xB7, 0xB3, - 0x8B, 0xCA, 0xB8, 0x8C, 0x1D, 0x3B, 0x49, 0x05, - 0x38, 0xA1, 0xE5, 0x8C, 0x1A, 0xDC, 0xA5, 0x61, - 0xFE, 0xF4, 0x2B, 0xDC, 0x77, 0x28, 0xF6, 0x19, - 0xE7, 0xB7, 0x8F, 0x4D, 0x27, 0x2D, 0xED, 0x8A, - 0x3F, 0x3D, 0xDC, 0x9F, 0xD1, 0x30, 0xFF, 0xD6, - 0xC3, 0xBE, 0x41, 0x25, 0xE3, 0xA5, 0x9B, 0x73, - 0xDF, 0x6A, 0xD9, 0xF9, 0x70, 0x84, 0x02, 0x4C, - 0x35, 0xD4, 0x3E, 0x05, 0x76, 0x3A, 0xDC, 0x6D, - 0x5A, 0x81, 0xB3, 0x94, 0xF7, 0x22, 0xF7, 0xDC, - 0xC1, 0x43, 0x31, 0x57, 0x5B, 0x42, 0x9A, 0x0B, - 0xF4, 0x95, 0x30, 0xA9, 0xBB, 0xD8, 0x06, 0xFB, - 0x1D, 0x6F, 0x9B, 0xC3, 0xBB, 0xF3, 0xBF, 0xFB, - 0xB4, 0x9F, 0x35, 0x64, 0x0A, 0x69, 0xB7, 0xD1, - 0x3E, 0xCA, 0x78, 0x07, 0x04, 0x03, 0x79, 0xD4, - 0xF3, 0xA8, 0xEC, 0x18, 0xDB, 0x03, 0x5E, 0x47, - 0xD7, 0xD0, 0x56, 0x2C, 0x74, 0x94, 0x86, 0x04, - 0x46, 0xB8, 0xD4, 0x35, 0x0A, 0x7B, 0xE6, 0x78, - 0xC4, 0x43, 0x3C, 0x56, 0xCC, 0x37, 0x8B, 0xFD, - 0xE8, 0xF4, 0x57, 0xEA, 0xAE, 0xCF, 0x36, 0x97, - 0x12, 0xAC, 0x39, 0xCF, 0x7C, 0xEF, 0x22, 0x67, - 0x01, 0xEC, 0xD8, 0x09, 0x49, 0x4E, 0xE3, 0x74, - 0xDD, 0x39, 0xE1, 0x39, 0xD7, 0x0C, 0x5F, 0x1B, - 0xCE, 0x69, 0xBC, 0x72, 0x44, 0x87, 0x64, 0x1C, - 0x08, 0x05, 0x93, 0x69, 0x6D, 0x7F, 0x90, 0x0A, - 0x2C, 0xCB, 0x8A, 0xBB, 0x7F, 0xE3, 0xE0, 0x80, - 0x31, 0xD0, 0x0A, 0x3A, 0x95, 0xFF, 0xF7, 0xB4, - 0x36, 0x38, 0x93, 0xE0, 0x0C, 0x11, 0x37, 0x12, - 0x06, 0xF6, 0xAD, 0xE9, 0xB1, 0x7A, 0x00, 0xF5, - 0xD2, 0x32, 0x6B, 0xD0, 0x27, 0xA5, 0x1B, 0x3D, - 0xE8, 0xDB, 0xCC, 0xA9, 0x1F, 0x1F, 0xB1, 0x99, - 0x3D, 0x7C, 0xB7, 0xCA, 0xDA, 0x27, 0x2C, 0x64, - 0x1C, 0x49, 0xB6, 0x87, 0x44, 0x06, 0x94, 0x9D, - 0xBC, 0x6B, 0x20, 0xA2, 0x68, 0x15, 0x1F, 0xE2, - 0xF2, 0xAD, 0x6D, 0x23, 0x2E, 0x2B, 0x74, 0xE2, - 0x5D, 0xE4, 0xB0, 0xC7, 0x84, 0xCB, 0x64, 0xBF, - 0xE0, 0xA8, 0x18, 0x83, 0xB4, 0xC9, 0xD9, 0x73, - 0xA8, 0xE6, 0xA9, 0x36, 0xD5, 0x63, 0x1E, 0x2C, - 0x2A, 0x55, 0x09, 0x77, 0x5E, 0xB3, 0x4B, 0xEA, - 0xB5, 0xD0, 0x14, 0x5F, 0xEB, 0x50, 0x7B, 0xAA, - 0xEF, 0x94, 0xBA, 0x2B, 0xD7, 0x8A, 0x07, 0xF1, - 0xF9, 0x5E, 0x12, 0x12, 0x21, 0x52, 0xE5, 0x0A, - 0x3E, 0xC0, 0xBC, 0x5D, 0x4C, 0xE2, 0x12, 0x7C, - 0x39, 0xF9, 0x16, 0x9D, 0xBD, 0x96, 0x83, 0x3B, - 0x7F, 0x3D, 0x6A, 0xEC, 0xF1, 0x25, 0xD2, 0xB0, - 0xB0, 0xEB, 0x20, 0x06, 0x07, 0xD6, 0xD9, 0x4C, - 0x07, 0x9A, 0x82, 0xC1, 0xFC, 0xF7, 0x66, 0x15, - 0xBD, 0x62, 0x65, 0xD8, 0x6C, 0xF6, 0x33, 0x7B, - 0x5A, 0x28, 0xEC, 0x90, 0xA1, 0x26, 0x9F, 0xC3, - 0x28, 0x4A, 0x64, 0x50, 0x5F, 0xCA, 0xE2, 0x6D, - 0xB8, 0x0F, 0xE2, 0x94, 0xB5, 0x8E, 0x1F, 0x8A, - 0x8F, 0x6B, 0xA6, 0x86, 0x1F, 0xEE, 0xDC, 0x24, - 0xB4, 0xB8, 0x25, 0xEC, 0x28, 0x2D, 0xF9, 0xCB, - 0x7D, 0x38, 0xFF, 0xC7, 0x74, 0x2E, 0xD3, 0x10, - 0xEC, 0x03, 0x31, 0xEE, 0x83, 0xE7, 0xA4, 0xF7, - 0xBA, 0x28, 0x21, 0xE0, 0x7F, 0xB4, 0xB7, 0xE1, - 0x7A, 0xF9, 0x2B, 0xB0, 0x2C, 0x3B, 0x80, 0x5F, - 0xE0, 0x5D, 0xB2, 0x7E, 0x59, 0xFF, 0x59, 0x07, - 0x58, 0x42, 0x57, 0xEE, 0x44, 0xF1, 0xB1, 0xAD, - 0xBA, 0xDE, 0xCB, 0x1D, 0x8A, 0x36, 0x67, 0xE8, - 0x45, 0xFF, 0x07, 0x8D, 0xEE, 0xA4, 0x51, 0x9C, - 0x4C, 0x83, 0x5D, 0x2E, 0x2F, 0xE1, 0x5B, 0x75, - 0xE8, 0x29, 0xCD, 0x0B, 0x07, 0x62, 0xE0, 0xC3, - 0x0D, 0x1D, 0xEA, 0xCF, 0xF0, 0x8A, 0x65, 0x27, - 0x70, 0x42, 0x9F, 0x26, 0x00, 0x15, 0x70, 0xC5, - 0x4A, 0xF6, 0x25, 0xD0, 0x40, 0x72, 0xE9, 0xC1, - 0x73, 0xFD, 0x48, 0x94, 0xA3, 0x8D, 0x66, 0x63, - 0x96, 0x4F, 0xF7, 0xEE, 0xFB, 0x4C, 0xC7, 0xB8, - 0x6B, 0xE9, 0x90, 0xE1, 0x2A, 0x66, 0x80, 0x99, - 0x3B, 0xB0, 0x1A, 0x6C, 0xF9, 0x0E, 0x72, 0xDA, - 0x8E, 0x4F, 0x46, 0xC2, 0x6A, 0x4B, 0x7A, 0x16, - 0xE5, 0x26, 0x0B, 0x5C, 0xD4, 0x47, 0x34, 0xE5, - 0x37, 0xBE, 0x68, 0x6C, 0xDA, 0xD3, 0x9B, 0x6F, - 0xAE, 0x51, 0x9C, 0x99, 0x0A, 0x5B, 0xF8, 0x37, - 0xBC, 0xDE, 0xFC, 0x93, 0xC5, 0xE7, 0x0F, 0xEF, - 0x0B, 0xA6, 0x07, 0xC2, 0xA6, 0xE6, 0xDA, 0x2D, - 0x1B, 0x49, 0xC9, 0xDE, 0x6B, 0x27, 0xDC, 0x00, - 0xEF, 0x23, 0x87, 0x0E, 0xEB, 0xD1, 0x48, 0x7D, - 0xB4, 0xF2, 0x58, 0xC6, 0x3C, 0xE2, 0x89, 0xBA, - 0xB0, 0x05, 0xAC, 0x94, 0x41, 0x9A, 0xA8, 0xFF, - 0x3E, 0xBC, 0x3A, 0x52, 0x9C, 0xF9, 0x7F, 0x07, - 0x8B, 0xB0, 0x2C, 0x71, 0x83, 0x7B, 0xCF, 0x2E, - 0x7F, 0x7C, 0x96, 0x65, 0xD9, 0x08, 0x17, 0xEC, - 0xFA, 0xDE, 0x4E, 0x40, 0x12, 0x26, 0x70, 0x71, - 0x65, 0xA5, 0xDC, 0x98, 0x47, 0xA3, 0xFC, 0xE0, - 0x9A, 0x16, 0xED, 0x45, 0x56, 0x72, 0x50, 0x05, - 0x28, 0x2C, 0x99, 0xEC, 0x20, 0x2E, 0x40, 0xC0, - 0x26, 0x69, 0xCD, 0x49, 0x45, 0x17, 0xA4, 0xA3, - 0x42, 0x0D, 0x14, 0x65, 0x87, 0x33, 0x8C, 0x92, - 0xC5, 0xC4, 0x61, 0xFD, 0xE8, 0x68, 0x56, 0x20, - 0x57, 0xF5, 0x8E, 0x5F, 0xCF, 0x7E, 0x97, 0xF6, - 0x49, 0x97, 0x0A, 0xFE, 0xD3, 0x60, 0x1A, 0x5B, - 0x0C, 0x75, 0xDD, 0x8E, 0x31, 0x78, 0x29, 0xA6, - 0xB1, 0x4D, 0xAA, 0xDF, 0x8A, 0xD1, 0xE6, 0x91, - 0xE3, 0x32, 0x3F, 0xEC, 0x8A, 0x1F, 0x0E, 0x35, - 0x07, 0x6E, 0x4B, 0x83, 0x3B, 0xE5, 0x67, 0x34, - 0x1F, 0x0C, 0x81, 0xD8, 0xD5, 0x25, 0x68, 0xE5, - 0x28, 0x1B, 0x5C, 0x81, 0x3E, 0xE3, 0x5C, 0xB4, - 0xB6, 0xBD, 0x62, 0x6A, 0x70, 0x33, 0xC2, 0xC5, - 0x75, 0x27, 0xF4, 0x30, 0xE1, 0x1D, 0xC1, 0x4C, - 0xC5, 0x02, 0x12, 0x46, 0xAC, 0xEC, 0xF9, 0xE8, - 0xE7, 0x58, 0x24, 0x11, 0xB1, 0xF3, 0xB7, 0x8C, - 0x3C, 0xA4, 0x0A, 0x94, 0xA6, 0x7C, 0x68, 0x54, - 0x5B, 0xB9, 0x4D, 0x57, 0x9C, 0xE7, 0x28, 0x09, - 0x6B, 0x89, 0x26, 0x5D, 0xE7, 0x50, 0xA9, 0x95, - 0x90, 0x91, 0x8E, 0x00, 0x59, 0xF8, 0x3A, 0x70, - 0xAF, 0x48, 0x2E, 0xE8, 0xC4, 0x34, 0x8C, 0xF4, - 0x5F, 0x7F, 0xCB, 0x07, 0xAA, 0xF0, 0xD9, 0xFB, - 0x5C, 0x32, 0x90, 0x22, 0x1A, 0xD2, 0x1A, 0xCF, - 0x92, 0x06, 0x02, 0xCF, 0x10, 0x18, 0x7B, 0x93, - 0xCC, 0x07, 0x4A, 0x31, 0x25, 0x30, 0x23, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xD1, 0xDE, - 0x23, 0x16, 0x9F, 0x6E, 0xF4, 0x42, 0x21, 0x23, - 0xE1, 0x11, 0xAA, 0xC8, 0x7C, 0x60, 0x4A, 0x78, - 0x9D, 0x24, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, - 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, - 0x00, 0x04, 0x14, 0xD6, 0x4A, 0xBB, 0x75, 0xB1, - 0xF9, 0x9E, 0xD3, 0x58, 0x6D, 0xD1, 0x74, 0x9F, - 0x00, 0x8A, 0xF2, 0xC8, 0xAA, 0x52, 0x4D, 0x04, - 0x08, 0x77, 0x46, 0xE7, 0xBA, 0x25, 0x4B, 0xDA, - 0x41, 0x02, 0x02, 0x08, 0x00] -}; - -const WPA_EAP_CLIENT_LIST = [ - { - ssid: 'WPA-EAP-TTLS', - keyManagement: 'WPA-EAP', - eap: 'TTLS', - identity: EAP_USERNAME, - password: EAP_PASSWORD, - serverCertificate: CLIENT_PKCS12_CERT.nickname, - phase2: 'MSCHAPV2' - } -]; - -/** - * Convert the given MozWifiNetwork object array to testAssociate chain. - * - * @param aNetworks - * An array of MozWifiNetwork which we want to convert. - * - * @return A promise chain which "then"s testAssociate accordingly. - */ -function convertToTestAssociateChain(aNetworks) { - let chain = Promise.resolve(); - - aNetworks.forEach(function (aNetwork) { - network = new window.MozWifiNetwork(aNetwork); - chain = chain.then(() => gTestSuite.testAssociate(network)); - }); - - return chain; -} - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(CLIENT_PKCS12_CERT.content)]), - CLIENT_PKCS12_CERT.password, - CLIENT_PKCS12_CERT.nickname, - CLIENT_PKCS12_CERT.usage, - function() { - return gTestSuite.ensureWifiEnabled(true) - // Load required server files. - .then(() => gTestSuite.writeFile(SERVER_EAP_USER_CONF.path, SERVER_EAP_USER_CONF.content)) - .then(() => gTestSuite.writeFile(CA_CERT.path, CA_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_CERT.path, SERVER_CERT.content)) - .then(() => gTestSuite.writeFile(SERVER_KEY.path, SERVER_KEY.content)) - // Start AP. - .then(() => gTestSuite.startHostapds(WPA_EAP_AP_LIST)) - // Scan test. - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, WPA_EAP_AP_LIST)) - // Associate test. - .then(() => convertToTestAssociateChain(WPA_EAP_CLIENT_LIST)) - // Tear down. - .then(gTestSuite.killAllHostapd) -}); diff --git a/dom/wifi/test/marionette/test_wifi_associate_wo_connect.js b/dom/wifi/test/marionette/test_wifi_associate_wo_connect.js deleted file mode 100644 index 3fba0b2c6..000000000 --- a/dom/wifi/test/marionette/test_wifi_associate_wo_connect.js +++ /dev/null @@ -1,55 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -/** - * Associate with the given networks but don't connect to it. - * - * Issue a association-only request, which will not have us connect - * to the network. Instead, the network config will be added as the - * known networks. After calling the "associate" API, we will wait - * a while to make sure the "connected" event is not received. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aNetwork - * MozWifiNetwork object. - * - * @return A deferred promise. - */ -function associateButDontConnect(aNetwork) { - log('Associating with ' + aNetwork.ssid); - aNetwork.dontConnect = true; - - let promises = []; - promises.push(gTestSuite.waitForTimeout(10 * 1000) - .then(() => { throw 'timeout'; })); - - promises.push(gTestSuite.testAssociate(aNetwork)); - - return Promise.all(promises) - .then(() => { throw 'unexpected state'; }, - function(aReason) { - is(typeof aReason, 'string', 'typeof aReason'); - is(aReason, 'timeout', aReason); - }); -} - -gTestSuite.doTest(function() { - let firstNetwork; - return gTestSuite.ensureWifiEnabled(true) - .then(gTestSuite.requestWifiScan) - .then(function(aNetworks) { - firstNetwork = aNetworks[0]; - return associateButDontConnect(firstNetwork); - }) - .then(gTestSuite.getKnownNetworks) - .then(function(aKnownNetworks) { - is(1, aKnownNetworks.length, 'There should be only one known network!'); - is(aKnownNetworks[0].ssid, firstNetwork.ssid, - 'The only one known network should be ' + firstNetwork.ssid) - }); -}); diff --git a/dom/wifi/test/marionette/test_wifi_auto_connect.js b/dom/wifi/test/marionette/test_wifi_auto_connect.js deleted file mode 100644 index 7add9f03d..000000000 --- a/dom/wifi/test/marionette/test_wifi_auto_connect.js +++ /dev/null @@ -1,44 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const TESTING_HOSTAPD = [{ ssid: 'ap0' }]; - -gTestSuite.doTestWithoutStockAp(function() { - let firstNetwork; - return gTestSuite.ensureWifiEnabled(true) - // Start custom hostapd for testing. - .then(() => gTestSuite.startHostapds(TESTING_HOSTAPD)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', TESTING_HOSTAPD.length)) - - // Request the first scan. - .then(gTestSuite.requestWifiScan) - .then(function(networks) { - firstNetwork = networks[0]; - return gTestSuite.testAssociate(firstNetwork); - }) - - // Note that due to Bug 1168285, we need to re-start testing hostapd - // after wifi has been re-enabled. - - // Disable wifi and kill running hostapd. - .then(() => gTestSuite.requestWifiEnabled(false)) - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)) - - // Re-enable wifi. - .then(() => gTestSuite.requestWifiEnabled(true)) - - // Restart hostapd. - .then(() => gTestSuite.startHostapds(TESTING_HOSTAPD)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', TESTING_HOSTAPD.length)) - - // Wait for connection automatically. - .then(() => gTestSuite.waitForConnected(firstNetwork)) - - // Kill running hostapd. - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)) -}); diff --git a/dom/wifi/test/marionette/test_wifi_enable.js b/dom/wifi/test/marionette/test_wifi_enable.js deleted file mode 100644 index 6a1bec7a2..000000000 --- a/dom/wifi/test/marionette/test_wifi_enable.js +++ /dev/null @@ -1,11 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.doTest(function() { - return Promise.resolve() - .then(() => gTestSuite.ensureWifiEnabled(false)) - .then(() => gTestSuite.requestWifiEnabled(true)); -});
\ No newline at end of file diff --git a/dom/wifi/test/marionette/test_wifi_enable_api.js b/dom/wifi/test/marionette/test_wifi_enable_api.js deleted file mode 100644 index 3728330a2..000000000 --- a/dom/wifi/test/marionette/test_wifi_enable_api.js +++ /dev/null @@ -1,13 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.doTest(function() { - return Promise.resolve() - .then(() => gTestSuite.ensureWifiEnabled(false, true)) - .then(() => gTestSuite.requestWifiEnabled(true, true)) - .then(() => gTestSuite.requestWifiEnabled(false, true)) - .then(() => gTestSuite.ensureWifiEnabled(true, true)); -}); diff --git a/dom/wifi/test/marionette/test_wifi_manage_pkcs12_certificate.js b/dom/wifi/test/marionette/test_wifi_manage_pkcs12_certificate.js deleted file mode 100644 index f85ef00c9..000000000 --- a/dom/wifi/test/marionette/test_wifi_manage_pkcs12_certificate.js +++ /dev/null @@ -1,338 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -// Binary form of test certificate. -var testCertInfo = { - nickname: 'Test Certificate', - password: '12345678', - usage: ['UserCert', 'ServerCert'], - blob: [0x30, 0x82, 0x09, 0xF1, 0x02, 0x01, 0x03, 0x30, - 0x82, 0x09, 0xB7, 0x06, 0x09, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, - 0x09, 0xA8, 0x04, 0x82, 0x09, 0xA4, 0x30, 0x82, - 0x09, 0xA0, 0x30, 0x82, 0x06, 0x9F, 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, - 0x06, 0xA0, 0x82, 0x06, 0x90, 0x30, 0x82, 0x06, - 0x8C, 0x02, 0x01, 0x00, 0x30, 0x82, 0x06, 0x85, - 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, - 0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, - 0x06, 0x30, 0x0E, 0x04, 0x08, 0x13, 0xB5, 0x2F, - 0x5A, 0xB9, 0x49, 0xE6, 0x0B, 0x02, 0x02, 0x08, - 0x00, 0x80, 0x82, 0x06, 0x58, 0x35, 0x77, 0x6B, - 0xBF, 0x5C, 0x06, 0x09, 0xD8, 0xF0, 0x36, 0x06, - 0x69, 0x8D, 0xA2, 0x86, 0xCF, 0x6B, 0x73, 0x86, - 0x14, 0xFA, 0x51, 0x9A, 0x87, 0x73, 0x29, 0x71, - 0xC5, 0xB1, 0x4F, 0xFB, 0xEC, 0x64, 0x84, 0x20, - 0xFC, 0x06, 0x4A, 0x93, 0x74, 0x01, 0xFB, 0xEB, - 0x1F, 0xDC, 0xF8, 0xF7, 0xBB, 0xDC, 0x42, 0xA1, - 0x4A, 0x71, 0xDE, 0x08, 0x33, 0x7A, 0xCA, 0xD3, - 0xD8, 0x40, 0x24, 0x47, 0xAE, 0x41, 0x42, 0x8E, - 0xC8, 0x4E, 0xBE, 0x8B, 0xB3, 0xE5, 0x77, 0xAC, - 0xBD, 0x98, 0x0C, 0x0E, 0x53, 0xBE, 0x38, 0xB7, - 0xEA, 0xD2, 0x29, 0x35, 0xD2, 0xC4, 0xF4, 0xC7, - 0xD8, 0xB1, 0x73, 0x2A, 0x13, 0x11, 0x65, 0xF7, - 0x0C, 0x8B, 0xC0, 0x43, 0xFB, 0x31, 0x6C, 0xD2, - 0xE4, 0x43, 0x85, 0x51, 0x16, 0xBF, 0x35, 0xB5, - 0x05, 0x6B, 0x86, 0x11, 0xEA, 0x78, 0x64, 0x9F, - 0x42, 0x29, 0xB9, 0x79, 0xAF, 0xB0, 0x7C, 0xBF, - 0xC0, 0x89, 0xAD, 0xC7, 0x37, 0xD2, 0x30, 0x8C, - 0xDC, 0xF6, 0x77, 0x5E, 0x1F, 0x26, 0x28, 0x8F, - 0xAC, 0x19, 0x6C, 0xA0, 0x15, 0xC7, 0x12, 0xA3, - 0x0A, 0xD5, 0xC6, 0x15, 0x60, 0x58, 0x16, 0xB8, - 0x30, 0x12, 0x3C, 0x78, 0x3C, 0x93, 0x23, 0xA1, - 0x56, 0x75, 0x0B, 0x77, 0xAA, 0x0B, 0x0B, 0x2B, - 0x91, 0xB6, 0x41, 0xAB, 0xF5, 0x09, 0x4C, 0x1E, - 0x36, 0xC0, 0x88, 0xC3, 0x08, 0xF2, 0x65, 0xCB, - 0x58, 0x8F, 0x94, 0xB4, 0xB4, 0x05, 0xCC, 0x44, - 0x49, 0x73, 0x1B, 0x25, 0x6F, 0x5D, 0x83, 0xBD, - 0xF0, 0x70, 0xD0, 0xE8, 0x0D, 0x18, 0x2E, 0x44, - 0xD7, 0x89, 0x64, 0x6A, 0xED, 0x23, 0x30, 0xDF, - 0xAD, 0x84, 0x3B, 0x74, 0x2C, 0x0D, 0x2B, 0x51, - 0x84, 0xA2, 0xA4, 0x9E, 0x42, 0xC3, 0x81, 0x69, - 0xFA, 0x56, 0x76, 0x9F, 0xD9, 0x02, 0x64, 0x04, - 0xFE, 0xF0, 0xD9, 0x01, 0xBC, 0xE2, 0xC9, 0xDD, - 0x88, 0xAC, 0xFA, 0x24, 0x7E, 0xB1, 0xF8, 0x39, - 0x27, 0xA2, 0xEB, 0xE4, 0x53, 0xC1, 0xF3, 0xFE, - 0x2D, 0x9A, 0x49, 0x73, 0xFF, 0x7C, 0x8E, 0x39, - 0xF7, 0x15, 0x27, 0xB3, 0x47, 0x48, 0x92, 0x8C, - 0x57, 0x60, 0x9C, 0x97, 0xBA, 0x80, 0xD2, 0x25, - 0x80, 0x94, 0xCE, 0x2C, 0x0C, 0x00, 0x44, 0x8C, - 0x8C, 0x37, 0x82, 0x5D, 0x5F, 0x62, 0x8B, 0x05, - 0x6F, 0xB0, 0x07, 0x34, 0xF9, 0xC3, 0xA1, 0x34, - 0x3D, 0xE4, 0x90, 0xB0, 0x03, 0x59, 0x97, 0x6E, - 0xFB, 0xF2, 0x92, 0xE5, 0xB5, 0x30, 0x7C, 0x0D, - 0x3B, 0x8F, 0x90, 0x8E, 0x04, 0x47, 0x01, 0x0E, - 0x88, 0x50, 0x4A, 0x88, 0xA0, 0xFF, 0xB7, 0x9E, - 0x2B, 0x2C, 0x98, 0xD0, 0x3E, 0x16, 0x35, 0x5B, - 0xD5, 0xEA, 0x54, 0x86, 0xE0, 0xFB, 0x9F, 0x2F, - 0x62, 0x89, 0x36, 0x36, 0x9D, 0x6E, 0x62, 0xCB, - 0xC8, 0x6C, 0x62, 0x34, 0x8F, 0x66, 0x07, 0x62, - 0xA7, 0x00, 0x90, 0x31, 0xFA, 0x5D, 0xDD, 0x12, - 0x33, 0x69, 0xD0, 0x74, 0x0E, 0x0B, 0x42, 0x9A, - 0xF3, 0x40, 0x7E, 0x3E, 0x48, 0x1D, 0xF2, 0x5C, - 0x71, 0x0B, 0x78, 0x7E, 0xD5, 0x15, 0xA4, 0x16, - 0x1E, 0xBD, 0x71, 0x18, 0x87, 0x3A, 0xC9, 0xE3, - 0x45, 0xEE, 0x70, 0xA2, 0x4C, 0x50, 0xF5, 0x16, - 0x5C, 0xF8, 0x76, 0xE6, 0x9F, 0x8D, 0x86, 0x41, - 0x7E, 0xF8, 0x60, 0x3D, 0x75, 0x6D, 0x55, 0x96, - 0x9E, 0x43, 0x48, 0x82, 0xF7, 0xB6, 0xAC, 0x98, - 0x6F, 0x10, 0xAA, 0x20, 0x64, 0xD0, 0x7C, 0x25, - 0x24, 0xF7, 0xD8, 0xA4, 0xCC, 0x2D, 0xBF, 0x85, - 0x62, 0x6C, 0x4F, 0xFF, 0x9D, 0x71, 0x04, 0x98, - 0x61, 0xB0, 0xBC, 0x31, 0xC1, 0xE9, 0xB8, 0x29, - 0xA5, 0xEB, 0xD1, 0x1D, 0x65, 0x8E, 0xAE, 0x38, - 0x55, 0x65, 0x22, 0xC7, 0xFD, 0x7E, 0xF2, 0x6A, - 0xB6, 0xB1, 0x51, 0x37, 0x4B, 0x05, 0x8F, 0xA7, - 0x2D, 0x3F, 0x5C, 0x04, 0x2B, 0xBA, 0x2C, 0x37, - 0xCA, 0xDE, 0xD5, 0x3E, 0xA0, 0xA5, 0x86, 0x59, - 0xA7, 0xD7, 0x38, 0x07, 0xFB, 0x79, 0xF6, 0x2D, - 0xE1, 0xAA, 0x7C, 0xD1, 0x91, 0xBE, 0x39, 0xDF, - 0x53, 0x3C, 0xD1, 0x44, 0x2C, 0xF9, 0x12, 0x7D, - 0xB1, 0xCD, 0xF3, 0x35, 0x1F, 0x85, 0xA6, 0x64, - 0x2F, 0xFD, 0x28, 0xF2, 0x85, 0xA8, 0xA7, 0x1F, - 0x7F, 0xD9, 0x79, 0x30, 0x9B, 0xFC, 0x69, 0x3A, - 0x9B, 0x1F, 0x55, 0x70, 0xC9, 0x60, 0x82, 0x3D, - 0xE9, 0x5A, 0x37, 0x5F, 0x8C, 0xBD, 0x19, 0x5D, - 0xCC, 0x1C, 0xBE, 0x26, 0x4A, 0xEA, 0x8B, 0x39, - 0xCE, 0x0D, 0xBD, 0x63, 0x05, 0x98, 0x75, 0xAB, - 0x08, 0x79, 0x90, 0xC7, 0x20, 0xFF, 0xE4, 0x0D, - 0xB1, 0xA0, 0x92, 0x2B, 0x0C, 0x4B, 0x0C, 0xDC, - 0xB9, 0x72, 0x2A, 0xA4, 0xCC, 0xA6, 0x32, 0xA3, - 0x57, 0x82, 0xB4, 0xB9, 0x0F, 0x81, 0xC5, 0xD9, - 0x7C, 0xB8, 0x0F, 0x7D, 0xEA, 0x5D, 0xD3, 0xC4, - 0x2F, 0x31, 0x79, 0x11, 0xAD, 0x36, 0x56, 0x1F, - 0xFA, 0xE3, 0xCE, 0xD2, 0x29, 0x23, 0xE8, 0x2C, - 0xDF, 0x7D, 0x94, 0x28, 0x28, 0x9A, 0x0E, 0x64, - 0xFC, 0x07, 0x11, 0x96, 0x06, 0x1A, 0x39, 0xCD, - 0x04, 0x37, 0x37, 0xDB, 0xFE, 0x68, 0x37, 0xF5, - 0x59, 0x54, 0xBC, 0xEF, 0xDB, 0x0C, 0x80, 0xCD, - 0xD3, 0x46, 0xA8, 0xA2, 0xBE, 0xE0, 0x63, 0x80, - 0xA1, 0x5F, 0x5D, 0xF1, 0xFB, 0x96, 0x8C, 0x06, - 0x38, 0xB6, 0xCB, 0x70, 0xB0, 0xFB, 0xD3, 0x26, - 0xB3, 0x8B, 0xC6, 0x85, 0x34, 0xB7, 0xAB, 0x5F, - 0x7E, 0xC6, 0xAA, 0x79, 0x5B, 0x48, 0x11, 0x65, - 0x9E, 0x2A, 0xCD, 0x6A, 0xF0, 0xB2, 0x93, 0xF5, - 0x2B, 0x88, 0x45, 0xB7, 0xC9, 0xBE, 0x1A, 0x72, - 0x60, 0x62, 0xA4, 0xA5, 0x3B, 0xC2, 0x1C, 0xC6, - 0x21, 0x09, 0xA9, 0x40, 0xF6, 0x58, 0x2B, 0xE5, - 0x70, 0xDC, 0xFC, 0x47, 0x3B, 0x08, 0xEE, 0xA9, - 0x94, 0x26, 0x43, 0xFE, 0xA7, 0x75, 0xD6, 0x4E, - 0x52, 0xF6, 0x46, 0xD1, 0x80, 0xEB, 0x3B, 0x8E, - 0xBE, 0x54, 0x4F, 0xBD, 0x42, 0x0E, 0x41, 0xF9, - 0x36, 0x7D, 0xB6, 0x7F, 0x99, 0x20, 0xC9, 0x63, - 0xE7, 0x93, 0x02, 0x62, 0x59, 0x94, 0xCB, 0xC6, - 0x62, 0xA9, 0x26, 0xE1, 0x1E, 0x03, 0x5A, 0x41, - 0x2F, 0x43, 0x28, 0x75, 0xB7, 0x0C, 0x02, 0x9C, - 0x1E, 0xE0, 0x40, 0xB3, 0xE2, 0x9A, 0xED, 0xC6, - 0x20, 0x49, 0xEC, 0xDD, 0xC5, 0x64, 0x95, 0x83, - 0x51, 0xAE, 0x46, 0x9D, 0x70, 0x17, 0xC6, 0x47, - 0xD3, 0x82, 0xCC, 0x6A, 0x5D, 0x93, 0xB2, 0x85, - 0x5B, 0x25, 0x05, 0xE7, 0x26, 0x2E, 0xD3, 0xDA, - 0x1C, 0xD9, 0x06, 0xB6, 0x16, 0x69, 0x8C, 0x7F, - 0xC8, 0xCF, 0x95, 0x18, 0xB5, 0x98, 0xC0, 0x42, - 0x61, 0xDE, 0x77, 0x41, 0x3A, 0xF6, 0xE1, 0xB0, - 0xE8, 0x64, 0x4A, 0xC2, 0x58, 0xBE, 0x27, 0xC6, - 0x9B, 0x0D, 0x47, 0x1A, 0x09, 0x56, 0x7D, 0x2B, - 0x19, 0x01, 0x88, 0xC7, 0xFB, 0x1E, 0xCF, 0x5E, - 0xF6, 0xB0, 0x82, 0x87, 0xC0, 0xBE, 0xD6, 0xA5, - 0xC3, 0xAC, 0x3A, 0x97, 0x88, 0x25, 0x81, 0xAA, - 0x3A, 0xCE, 0x66, 0x88, 0x0F, 0xC3, 0x02, 0x50, - 0x1C, 0xC3, 0x2B, 0xBC, 0x53, 0x52, 0xFE, 0xD2, - 0x3F, 0x50, 0xC8, 0xB2, 0x19, 0x0A, 0x14, 0xB1, - 0x73, 0x18, 0xB4, 0xDF, 0xBD, 0xED, 0x43, 0xC5, - 0x91, 0xF4, 0x91, 0xBA, 0x7E, 0xB0, 0x7E, 0xA9, - 0x43, 0x67, 0x06, 0xCF, 0x51, 0xC1, 0xBF, 0x63, - 0x7E, 0x91, 0x76, 0xFF, 0x4F, 0x48, 0x91, 0xCF, - 0xDF, 0x01, 0x4D, 0x7E, 0x81, 0x22, 0xFB, 0x79, - 0xFC, 0x1D, 0xE3, 0xA7, 0x45, 0x16, 0xFB, 0xF2, - 0x83, 0xC7, 0xAE, 0xC6, 0xC5, 0x81, 0xDB, 0xA2, - 0x9F, 0x2F, 0xEA, 0xE6, 0x8E, 0x12, 0x8D, 0x43, - 0x14, 0x26, 0x25, 0x0E, 0xB4, 0x18, 0xE8, 0x41, - 0x84, 0xA3, 0x04, 0xDF, 0x97, 0xFF, 0xAA, 0x45, - 0xEC, 0x18, 0xAA, 0xB1, 0xFC, 0xDC, 0xB9, 0xAB, - 0xEE, 0xD1, 0xC4, 0x9E, 0x42, 0x3F, 0x5B, 0x8F, - 0x9F, 0x22, 0xAF, 0xCC, 0x6F, 0xA0, 0x41, 0x41, - 0xCB, 0xD3, 0xAC, 0x96, 0x20, 0xF1, 0x63, 0x56, - 0x65, 0xCE, 0x83, 0xC6, 0x62, 0x04, 0x85, 0x16, - 0x7F, 0x4E, 0xFB, 0xA0, 0x68, 0x11, 0x85, 0x5B, - 0x51, 0xB6, 0x9F, 0xA2, 0xF5, 0xA1, 0xCF, 0x01, - 0x9A, 0x80, 0x68, 0xC3, 0xE9, 0x7F, 0x9E, 0x2E, - 0x83, 0x84, 0xDC, 0x3C, 0x35, 0xCF, 0x24, 0xBF, - 0xF5, 0x00, 0x91, 0x45, 0x14, 0x65, 0xE0, 0xC5, - 0x75, 0xDA, 0xEF, 0x14, 0xBD, 0xDB, 0x28, 0x8D, - 0x30, 0x96, 0xC9, 0xFE, 0xA8, 0x49, 0x76, 0xC9, - 0xED, 0x90, 0x4C, 0x2E, 0xF1, 0x14, 0x2C, 0xF7, - 0x13, 0x7C, 0xF1, 0xCC, 0x67, 0xA5, 0x11, 0x55, - 0xBD, 0x66, 0x13, 0x8A, 0x76, 0xF9, 0xAC, 0xC9, - 0x51, 0x8A, 0xBB, 0x5D, 0x29, 0xEF, 0xF6, 0x37, - 0xA0, 0x3E, 0x99, 0x77, 0x6B, 0xE5, 0xCD, 0x06, - 0xAC, 0x57, 0x07, 0x37, 0x44, 0x3D, 0x5D, 0xD7, - 0xB6, 0x5C, 0xCB, 0x77, 0xD0, 0x4C, 0x28, 0x9D, - 0x12, 0x69, 0x5A, 0x68, 0xD1, 0x15, 0x30, 0xC4, - 0x30, 0xD2, 0x20, 0xDF, 0xD5, 0x73, 0x9F, 0x83, - 0xE9, 0x4C, 0x55, 0xF5, 0xAF, 0xAA, 0x37, 0xF8, - 0x28, 0xB6, 0x3F, 0x99, 0x4B, 0x15, 0x1E, 0x40, - 0xAB, 0x4F, 0x58, 0x3D, 0x3B, 0x81, 0x7D, 0x62, - 0x28, 0x6E, 0x73, 0x58, 0x50, 0x36, 0x49, 0x01, - 0xF7, 0x04, 0x3A, 0x23, 0x28, 0xDA, 0x15, 0xC5, - 0xE3, 0xF6, 0x6F, 0xE1, 0x79, 0x07, 0xFB, 0xAA, - 0xFF, 0x44, 0x48, 0x53, 0x9E, 0x7F, 0x8D, 0x89, - 0x88, 0x1A, 0x9A, 0xF9, 0x47, 0x58, 0x20, 0xBB, - 0x79, 0x4A, 0x2A, 0x14, 0x03, 0x9B, 0x65, 0x4C, - 0x67, 0x02, 0x02, 0xFE, 0xEB, 0xCD, 0xCB, 0x84, - 0xF5, 0xCE, 0x32, 0x59, 0xBC, 0xEA, 0xEC, 0xB1, - 0x3C, 0x22, 0xCF, 0x9D, 0xB0, 0x34, 0x6D, 0xE6, - 0x5A, 0x37, 0xC0, 0x22, 0xAA, 0xF3, 0xB5, 0x71, - 0x90, 0x21, 0xE0, 0xB6, 0x19, 0xE9, 0xB3, 0x10, - 0xCE, 0x5B, 0xF9, 0xD4, 0x25, 0x30, 0x7D, 0xF6, - 0x7D, 0xB6, 0x16, 0xFC, 0x20, 0x3C, 0x2F, 0x96, - 0xD5, 0x79, 0x90, 0x88, 0x24, 0x5D, 0x46, 0x64, - 0x99, 0xC1, 0xF8, 0x7F, 0x96, 0xA7, 0xB5, 0xA9, - 0x47, 0xA3, 0x14, 0xED, 0x93, 0xED, 0x30, 0x56, - 0x58, 0xA5, 0xD4, 0x54, 0x2A, 0xF3, 0x89, 0x27, - 0x7C, 0x55, 0x41, 0x11, 0x27, 0x9D, 0xF6, 0x4D, - 0xA6, 0xB1, 0x00, 0xE0, 0xB0, 0xF6, 0x1E, 0xAB, - 0x20, 0x1F, 0xAE, 0x8A, 0x82, 0xA7, 0x49, 0xFC, - 0xBB, 0x66, 0xAC, 0x97, 0x95, 0x49, 0x29, 0xCB, - 0x6F, 0xF4, 0xC1, 0xB7, 0x6B, 0xF9, 0x8C, 0x25, - 0xC6, 0xF0, 0xB5, 0x81, 0xB0, 0xA2, 0x4D, 0xCC, - 0x2E, 0xD0, 0x13, 0x5F, 0x96, 0x3F, 0xCD, 0xD0, - 0x52, 0xD1, 0xFE, 0xF9, 0xC2, 0x7E, 0x9D, 0xAB, - 0xCB, 0x95, 0x0F, 0x27, 0x01, 0x9E, 0x23, 0x6B, - 0x19, 0xFF, 0x52, 0x55, 0x71, 0x0A, 0xD4, 0xBB, - 0x43, 0x65, 0x29, 0x66, 0xBE, 0x2D, 0x6C, 0xE3, - 0x2A, 0x7C, 0xB4, 0x02, 0x32, 0x59, 0x94, 0x80, - 0x14, 0xE7, 0x62, 0xE4, 0xCE, 0xB0, 0xCA, 0xCA, - 0x37, 0xD7, 0x0C, 0x68, 0x29, 0xE2, 0x92, 0xE1, - 0xEB, 0x91, 0xE5, 0xA1, 0x0C, 0xFC, 0x55, 0xCB, - 0x56, 0xB3, 0x96, 0xFB, 0x64, 0xD9, 0x53, 0x8E, - 0x82, 0x2B, 0xDF, 0x7F, 0xCB, 0x2A, 0xF6, 0x3C, - 0xA7, 0x89, 0x52, 0x13, 0x2C, 0x6A, 0x93, 0xA2, - 0x74, 0xF5, 0x91, 0x00, 0x17, 0xAA, 0x74, 0x45, - 0x63, 0x5A, 0xE5, 0xC3, 0x16, 0xFC, 0x0E, 0xF7, - 0xF3, 0xA4, 0x55, 0x8A, 0xA2, 0x60, 0x24, 0x57, - 0x25, 0x2C, 0x94, 0xE0, 0xF5, 0x32, 0x54, 0x4A, - 0x2D, 0x63, 0x5F, 0xD8, 0x35, 0x96, 0xBD, 0xFE, - 0x90, 0x33, 0x17, 0xF6, 0xB5, 0x81, 0x02, 0xFA, - 0x5C, 0x94, 0x3A, 0xBE, 0x22, 0xB9, 0xFC, 0x3E, - 0x09, 0xE4, 0x76, 0xD7, 0x03, 0x38, 0x38, 0xC2, - 0xC2, 0x0D, 0x66, 0x3C, 0xD0, 0x91, 0x5C, 0xF4, - 0x0E, 0xC2, 0xDE, 0x46, 0x90, 0x2E, 0xF5, 0x22, - 0xA9, 0x3D, 0x15, 0x20, 0x5F, 0x17, 0x10, 0x5A, - 0x54, 0x63, 0x93, 0x7B, 0xC3, 0x00, 0x3D, 0x42, - 0x73, 0xF1, 0xAD, 0xC1, 0xDE, 0x76, 0x18, 0x9C, - 0x68, 0x17, 0xBF, 0x3B, 0xE0, 0x30, 0x82, 0x02, - 0xF9, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x02, 0xEA, - 0x04, 0x82, 0x02, 0xE6, 0x30, 0x82, 0x02, 0xE2, - 0x30, 0x82, 0x02, 0xDE, 0x06, 0x0B, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, - 0x02, 0xA0, 0x82, 0x02, 0xA6, 0x30, 0x82, 0x02, - 0xA2, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, - 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, - 0x0E, 0x04, 0x08, 0x34, 0x37, 0x27, 0x5F, 0xE8, - 0xD6, 0x00, 0x0D, 0x02, 0x02, 0x08, 0x00, 0x04, - 0x82, 0x02, 0x80, 0xC0, 0xE6, 0xB1, 0x63, 0x73, - 0xFC, 0xBF, 0x50, 0xFB, 0x54, 0xCF, 0x67, 0x16, - 0xF8, 0x28, 0x48, 0x13, 0x7F, 0xF2, 0xBD, 0x66, - 0x70, 0xC7, 0xF6, 0x01, 0xD0, 0x58, 0xF4, 0xA4, - 0xD9, 0x45, 0xE2, 0x63, 0x92, 0x7F, 0x78, 0x2B, - 0xB6, 0xDB, 0x16, 0x44, 0x1D, 0x11, 0xCB, 0xC3, - 0x20, 0xA9, 0x8A, 0x96, 0x13, 0xB8, 0x6E, 0xF3, - 0xDA, 0x46, 0x05, 0x2C, 0xF9, 0x67, 0xBB, 0x05, - 0x88, 0xC0, 0xC8, 0x60, 0x09, 0xA3, 0x82, 0x27, - 0x33, 0xEB, 0xEE, 0x43, 0x98, 0xE9, 0xE2, 0x24, - 0xA8, 0x06, 0xD5, 0xFF, 0xF5, 0xC0, 0x79, 0x4B, - 0x06, 0x40, 0xE6, 0x28, 0xC6, 0x6E, 0x4E, 0x03, - 0xCC, 0x9B, 0xB6, 0xBD, 0xB6, 0x81, 0x88, 0x5C, - 0x34, 0x6B, 0x8B, 0x15, 0x23, 0x75, 0x21, 0xAC, - 0x79, 0xFD, 0xDB, 0x80, 0x1D, 0x20, 0x84, 0xF1, - 0x47, 0xAF, 0x7B, 0x40, 0x6C, 0xD2, 0x64, 0x52, - 0x11, 0x1B, 0x01, 0x1E, 0xB5, 0xA9, 0x4B, 0xC4, - 0x51, 0x54, 0x40, 0xE2, 0xC8, 0xEB, 0x20, 0x48, - 0x2D, 0x40, 0xF8, 0xC6, 0x58, 0x5A, 0xE3, 0x34, - 0xD8, 0x79, 0x04, 0xD7, 0xD6, 0x07, 0xF2, 0x12, - 0x66, 0xC8, 0x31, 0x37, 0x71, 0x60, 0xF4, 0x75, - 0xDC, 0x60, 0x54, 0x19, 0x6A, 0x75, 0x56, 0xC5, - 0xA9, 0x67, 0x4A, 0x03, 0x7A, 0xFD, 0x12, 0x59, - 0x2B, 0x74, 0xE6, 0xA5, 0xE2, 0xF8, 0xBB, 0x1E, - 0x76, 0x96, 0xD4, 0xD4, 0x3F, 0x8B, 0xAD, 0x90, - 0xAF, 0x04, 0x41, 0xDB, 0xD8, 0xCC, 0x2D, 0x37, - 0x06, 0x20, 0x9B, 0xE7, 0x98, 0x87, 0x12, 0xAC, - 0x70, 0xC9, 0xF4, 0x1C, 0x28, 0xFB, 0x2C, 0x9E, - 0x18, 0xE1, 0x6D, 0x79, 0x34, 0xBC, 0xAC, 0xCB, - 0x75, 0x92, 0x7E, 0x8E, 0x7C, 0xA9, 0x0B, 0x86, - 0x4A, 0x88, 0xFB, 0xE8, 0xBE, 0x6A, 0x32, 0xEF, - 0x58, 0xCC, 0x4C, 0x89, 0x50, 0xEF, 0xDF, 0xE0, - 0xDD, 0x35, 0x07, 0x8C, 0x01, 0x8B, 0x57, 0x38, - 0xB5, 0x64, 0xBB, 0x0A, 0xC2, 0xD8, 0xAB, 0xC5, - 0x45, 0xA6, 0x83, 0xBF, 0xA6, 0xA2, 0xCC, 0x06, - 0x64, 0xBE, 0x84, 0x04, 0x55, 0x8E, 0xF4, 0x4C, - 0xB5, 0xBC, 0xE5, 0x97, 0x2B, 0x3C, 0x42, 0x44, - 0x91, 0x9B, 0xB2, 0x65, 0x70, 0x02, 0xC5, 0xB7, - 0x71, 0xB3, 0xF0, 0xAA, 0x46, 0x4F, 0x42, 0x40, - 0x53, 0x65, 0x89, 0xA5, 0x6C, 0xBC, 0xB5, 0x6C, - 0x0C, 0x3B, 0x50, 0x46, 0x67, 0xFA, 0x14, 0x68, - 0x01, 0xE7, 0xA6, 0xD4, 0xB5, 0xD0, 0x82, 0x44, - 0x92, 0x2C, 0xE3, 0x43, 0x5D, 0x34, 0x7C, 0x04, - 0xA3, 0x4D, 0x2F, 0x5A, 0x75, 0xE7, 0x0B, 0x64, - 0xD0, 0xAE, 0x7F, 0xCB, 0xDD, 0x7D, 0x05, 0x88, - 0x4C, 0x34, 0xBB, 0xF4, 0x00, 0xCE, 0x1C, 0x13, - 0x4E, 0xA3, 0xE3, 0x60, 0x4B, 0x50, 0x4E, 0xE1, - 0x26, 0x22, 0x51, 0xD4, 0x32, 0x60, 0xC6, 0x3E, - 0x7D, 0x4A, 0x3E, 0x56, 0x78, 0xBD, 0x5F, 0x23, - 0x7F, 0x0A, 0xA0, 0xC1, 0x1A, 0x60, 0xA2, 0x7C, - 0x9E, 0x17, 0x6F, 0xD8, 0x73, 0x0F, 0x1A, 0x1F, - 0x47, 0x58, 0x44, 0x20, 0x80, 0xC6, 0x5D, 0x6E, - 0xEC, 0xFF, 0xCA, 0x65, 0xA1, 0xFB, 0xEE, 0xF2, - 0x56, 0x1A, 0x16, 0x9E, 0x4D, 0xCA, 0x67, 0x81, - 0x23, 0xDE, 0xBE, 0x5E, 0x31, 0x56, 0xF0, 0x34, - 0xBA, 0x12, 0xFC, 0x07, 0x03, 0x96, 0xD2, 0x8E, - 0xCE, 0xA6, 0xF6, 0x74, 0x07, 0x4F, 0x63, 0x40, - 0x14, 0x0A, 0xD6, 0x45, 0xB4, 0xF1, 0x72, 0x87, - 0x34, 0x89, 0x5C, 0x06, 0x1B, 0x8C, 0x0E, 0xA2, - 0x84, 0x50, 0x12, 0xAD, 0x26, 0x5B, 0x4F, 0x6B, - 0x23, 0x9D, 0x3C, 0xBB, 0x8A, 0xDA, 0x08, 0x4B, - 0x93, 0x47, 0x02, 0x96, 0x76, 0xD4, 0x87, 0xE9, - 0x4B, 0x69, 0x82, 0xD6, 0xCC, 0x69, 0x02, 0xC0, - 0xA4, 0x75, 0x7A, 0x90, 0xFD, 0xF6, 0xD6, 0x9D, - 0xE2, 0x4C, 0xB6, 0xFA, 0x61, 0xA5, 0x7C, 0x18, - 0xEA, 0x84, 0xA1, 0x74, 0x85, 0x2E, 0xCA, 0xF9, - 0x17, 0x29, 0xFF, 0x67, 0x70, 0xC9, 0x6F, 0xF1, - 0x41, 0xEF, 0xA1, 0x59, 0x54, 0xA0, 0x99, 0x14, - 0x48, 0x74, 0x5D, 0x14, 0x3E, 0x04, 0xCE, 0xF7, - 0x16, 0x9F, 0x8A, 0x41, 0xF4, 0xAE, 0xB3, 0x10, - 0xCE, 0x19, 0xC2, 0x83, 0x7B, 0xD0, 0x26, 0x1E, - 0x75, 0x8A, 0x0A, 0x40, 0x4A, 0xB8, 0xE0, 0x5C, - 0x13, 0x8B, 0xCC, 0x6F, 0xF3, 0x00, 0xB3, 0x64, - 0x1B, 0x3C, 0x3D, 0x08, 0x3B, 0x9F, 0xD0, 0x9B, - 0xE5, 0x72, 0x45, 0x96, 0x95, 0x4D, 0x66, 0xC7, - 0x79, 0x5D, 0x3A, 0x1A, 0x94, 0x64, 0x94, 0x07, - 0x1A, 0xE8, 0x7C, 0xD1, 0x1C, 0xB1, 0x7E, 0x32, - 0x28, 0x1A, 0x90, 0x22, 0xD9, 0x86, 0x9B, 0x9C, - 0x9B, 0x0C, 0x04, 0x31, 0x85, 0x10, 0x42, 0x50, - 0x40, 0x11, 0x72, 0xAB, 0x94, 0x0C, 0xAF, 0xC3, - 0x22, 0x1A, 0xC1, 0x31, 0x25, 0x30, 0x23, 0x06, - 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, - 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xFD, 0x78, - 0xA7, 0x70, 0x1F, 0x8A, 0xE9, 0x07, 0xB9, 0xCA, - 0x3C, 0xD1, 0xE8, 0xDC, 0x68, 0xFF, 0x02, 0x61, - 0x29, 0x97, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, - 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, - 0x00, 0x04, 0x14, 0x22, 0x7E, 0x99, 0x10, 0xB3, - 0x99, 0x79, 0xE7, 0x14, 0x7F, 0x91, 0x59, 0x24, - 0x4F, 0x2F, 0xCF, 0xE8, 0x53, 0x1D, 0x0F, 0x04, - 0x08, 0x30, 0x1E, 0x5C, 0xE4, 0x3C, 0x66, 0xDF, - 0xB0, 0x02, 0x02, 0x08, 0x00] -}; - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(testCertInfo.blob)]), - testCertInfo.password, - testCertInfo.nickname, - testCertInfo.usage -); diff --git a/dom/wifi/test/marionette/test_wifi_manage_server_certificate.js b/dom/wifi/test/marionette/test_wifi_manage_server_certificate.js deleted file mode 100644 index dfaf524b2..000000000 --- a/dom/wifi/test/marionette/test_wifi_manage_server_certificate.js +++ /dev/null @@ -1,106 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -// Binary form of test certificate. -var testCertInfo = { - nickname: 'Test Certificate', - password: '', - usage: ['ServerCert'], - blob: [0x30, 0x82, 0x02, 0xae, 0x30, 0x82, 0x02, 0x17, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, - 0x92, 0x49, 0xe2, 0x62, 0x71, 0xf6, 0xc7, 0x92, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, - 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x54, 0x57, 0x31, 0x0f, - 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, - 0x06, 0x54, 0x61, 0x69, 0x70, 0x65, 0x69, 0x31, - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x0c, 0x07, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, - 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x0c, 0x02, 0x51, 0x41, 0x31, 0x0e, - 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, - 0x05, 0x47, 0x65, 0x72, 0x72, 0x79, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x67, - 0x63, 0x68, 0x61, 0x6e, 0x67, 0x40, 0x6d, 0x6f, - 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2e, 0x63, 0x6f, - 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, - 0x35, 0x32, 0x33, 0x30, 0x39, 0x34, 0x32, 0x33, - 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x35, - 0x32, 0x32, 0x30, 0x39, 0x34, 0x32, 0x33, 0x37, - 0x5a, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x54, 0x57, - 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x0c, 0x06, 0x54, 0x61, 0x69, 0x70, 0x65, - 0x69, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x6f, 0x7a, 0x69, - 0x6c, 0x6c, 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x02, 0x51, 0x41, - 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x05, 0x47, 0x65, 0x72, 0x72, 0x79, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, - 0x12, 0x67, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x40, - 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, - 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, - 0xd3, 0xdb, 0x54, 0xcc, 0xca, 0x0b, 0xee, 0xf9, - 0x8a, 0x37, 0x0d, 0x06, 0x8b, 0x20, 0x00, 0x4a, - 0x55, 0x84, 0x90, 0x1a, 0xb7, 0x9c, 0x91, 0xb2, - 0x38, 0x6b, 0x8b, 0x32, 0x7a, 0x89, 0x9e, 0x79, - 0x71, 0x88, 0x43, 0x21, 0x94, 0x18, 0xa8, 0xfc, - 0xe3, 0x7a, 0x8a, 0xb3, 0xa1, 0xf7, 0x23, 0xe7, - 0x1a, 0xe3, 0xe7, 0x0d, 0xf1, 0x66, 0x21, 0x58, - 0x21, 0x85, 0x5b, 0x35, 0xec, 0x68, 0xd2, 0xfd, - 0x44, 0x76, 0x93, 0x05, 0xbb, 0x89, 0x7d, 0x92, - 0xf9, 0xce, 0x75, 0xa3, 0xeb, 0x39, 0xc1, 0x7d, - 0x7e, 0x50, 0xf9, 0xb8, 0x60, 0x61, 0xf7, 0x2f, - 0x54, 0x39, 0xfe, 0x8a, 0x20, 0xb2, 0x0d, 0x48, - 0x7f, 0x18, 0x0d, 0x02, 0xcc, 0x7b, 0x8e, 0x31, - 0xe9, 0xbe, 0xfc, 0x96, 0x2e, 0x63, 0x6f, 0xfa, - 0x4c, 0xc4, 0xcf, 0x8a, 0xe4, 0x13, 0x67, 0xf1, - 0xec, 0x3e, 0xd8, 0x23, 0xa1, 0xbf, 0x67, 0x71, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, - 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0x13, 0xe1, 0xac, 0xa4, - 0x75, 0x3d, 0x2c, 0x5f, 0xe5, 0x41, 0x42, 0x90, - 0x5a, 0x48, 0x5c, 0x46, 0xbc, 0x24, 0x8e, 0xa1, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x18, 0x30, 0x16, 0x80, 0x14, 0x13, 0xe1, 0xac, - 0xa4, 0x75, 0x3d, 0x2c, 0x5f, 0xe5, 0x41, 0x42, - 0x90, 0x5a, 0x48, 0x5c, 0x46, 0xbc, 0x24, 0x8e, - 0xa1, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0xaa, 0x6b, 0x62, 0x53, 0x74, 0x2a, - 0x20, 0x76, 0xab, 0xd2, 0x60, 0x06, 0xfd, 0x88, - 0xf5, 0x1c, 0x85, 0xe6, 0x57, 0xf1, 0xf0, 0x18, - 0x97, 0x7c, 0x70, 0xb8, 0xb4, 0x7c, 0xcc, 0x58, - 0x8d, 0xf4, 0x7c, 0xb6, 0x34, 0xcc, 0x15, 0x79, - 0xaf, 0x75, 0xa9, 0x0b, 0xd1, 0xea, 0xf8, 0x85, - 0x7c, 0xe8, 0x19, 0xe9, 0x13, 0x90, 0x84, 0x5f, - 0x21, 0x94, 0x0a, 0x4d, 0x15, 0xef, 0xd1, 0x16, - 0xd4, 0xba, 0x2c, 0x59, 0x1b, 0x83, 0x23, 0xf5, - 0xa5, 0xcd, 0xbd, 0xda, 0x32, 0x73, 0x46, 0x49, - 0x98, 0xf3, 0xfb, 0x50, 0x6e, 0x30, 0xd7, 0x3e, - 0x31, 0xd6, 0xe8, 0x65, 0x2f, 0x5a, 0xf1, 0x0f, - 0x7b, 0x0a, 0x21, 0x61, 0x8e, 0x45, 0x29, 0x4f, - 0x7a, 0x04, 0xda, 0x29, 0xfc, 0x6f, 0xc5, 0x5e, - 0xee, 0xe1, 0x0f, 0xd5, 0x4b, 0xb7, 0xc9, 0x6a, - 0x8e, 0x7c, 0x19, 0xef, 0x6e, 0x64, 0x98, 0xfe, - 0xe3, 0x35] -}; - -gTestSuite.doTestWithCertificate( - new Blob([new Uint8Array(testCertInfo.blob)]), - testCertInfo.password, - testCertInfo.nickname, - testCertInfo.usage -); diff --git a/dom/wifi/test/marionette/test_wifi_manage_user_certificate.js b/dom/wifi/test/marionette/test_wifi_manage_user_certificate.js deleted file mode 100644 index 950ceae4e..000000000 --- a/dom/wifi/test/marionette/test_wifi_manage_user_certificate.js +++ /dev/null @@ -1,34 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -// Binary form of test certificate. -var testCertInfo = { - nickname: 'Test Certificate', - password: '', - usage: ['UserCert'], - blob: '-----BEGIN CERTIFICATE-----\n' + - 'MIICTjCCAbegAwIBAgICNV4wDQYJKoZIhvcNAQEEBQAwgYUxCzAJBgNVBAYTAklU\n' + - 'MRYwFAYDVQQKEw1aZXJvc2hlbGwubmV0MRAwDgYDVQQLEwdFeGFtcGxlMR0wGwYD\n' + - 'VQQDExRaZXJvU2hlbGwgRXhhbXBsZSBDQTEtMCsGCSqGSIb3DQEJARYeRnVsdmlv\n' + - 'LlJpY2NpYXJkaUB6ZXJvc2hlbGwubmV0MB4XDTEzMDMxMTAzMzg1MloXDTE0MDMx\n' + - 'MTAzMzg1MlowIzEOMAwGA1UECxMFVXNlcnMxETAPBgNVBAMTCGNodWNrbGVlMIGf\n' + - 'MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvVzFhQAVqAIHW5DlAhp4FEGEei7k7\n' + - 'uVUeqkH7JAsww6zmDLg9yZlcZAc95N0lkz022gLXehH2M0R1FOR++nkqofzWfc7w\n' + - 'n79ith+dU2GQMeKq7vPGDYXpgIkEKbYfzKj3fY3129MlTxJQt1UD/ejz38V8HKgw\n' + - 'qKSuwo0NVeY66QIDAQABoy4wLDALBgNVHQ8EBAMCBLAwHQYDVR0lBBYwFAYIKwYB\n' + - 'BQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBBAUAA4GBAJWgfX5vYSD7MGZk1rTF\n' + - 'DSziWYGqpR+Moo3qQ+9qLG8m+XVM9hckWpY31A5sWAeCZCe1SSNLFbbgsaOyPZE2\n' + - 'NqMyvs61Vszpc2mmWAYT6j2OU2tw8p5pcUZd6eIp7Gc3fLymiX/WoSmilZKmrGUZ\n' + - 'Q15R+TCpclUsaNrUGjybgaw7\n' + - '-----END CERTIFICATE-----' -}; - -gTestSuite.doTestWithCertificate( - new Blob([testCertInfo.blob]), - testCertInfo.password, - testCertInfo.nickname, - testCertInfo.usage -); diff --git a/dom/wifi/test/marionette/test_wifi_scan.js b/dom/wifi/test/marionette/test_wifi_scan.js deleted file mode 100644 index 4bb7d1a3d..000000000 --- a/dom/wifi/test/marionette/test_wifi_scan.js +++ /dev/null @@ -1,43 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const SCAN_RETRY_CNT = 5; - -/** - * Test scan with no AP present. - * - * The precondition is: - * 1) Wifi is enabled. - * 2) All the hostapds are turned off. - * - * @return deferred promise. - */ -function testScanNoAp() { - return gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, []); -} - -/** - * Test scan with APs present. - * - * The precondition is: - * 1) Wifi is enabled. - * 2) All the hostapds are turned off. - * - * @return deferred promise. - */ -function testScanWithAps() { - return gTestSuite.startHostapds(HOSTAPD_CONFIG_LIST) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', HOSTAPD_CONFIG_LIST.length)) - .then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, HOSTAPD_CONFIG_LIST)) - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)); -} - -gTestSuite.doTestWithoutStockAp(function() { - return gTestSuite.ensureWifiEnabled(true) - .then(testScanNoAp) - .then(testScanWithAps); -}); diff --git a/dom/wifi/test/marionette/test_wifi_static_ip.js b/dom/wifi/test/marionette/test_wifi_static_ip.js deleted file mode 100644 index 90436b6fe..000000000 --- a/dom/wifi/test/marionette/test_wifi_static_ip.js +++ /dev/null @@ -1,65 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const STATIC_IP_CONFIG = { - enabled: true, - ipaddr: "192.168.111.222", - proxy: "", - maskLength: 24, - gateway: "192.168.111.1", - dns1: "8.8.8.8", - dns2: "8.8.4.4", -}; - -const TESTING_HOSTAPD = [{ ssid: 'ap0' }]; - -function testAssociateWithStaticIp(aNetwork, aStaticIpConfig) { - return gTestSuite.setStaticIpMode(aNetwork, aStaticIpConfig) - .then(() => gTestSuite.testAssociate(aNetwork)) - // Check ip address and prefix. - .then(() => gTestSuite.exeAndParseNetcfg()) - .then((aResult) => { - is(aResult["wlan0"].ip, aStaticIpConfig.ipaddr, "Check ip address"); - is(aResult["wlan0"].prefix, aStaticIpConfig.maskLength, "Check prefix"); - }) - // Check routing. - .then(() => gTestSuite.exeAndParseIpRoute()) - .then((aResult) => { - is(aResult["wlan0"].src, aStaticIpConfig.ipaddr, "Check ip address"); - is(aResult["wlan0"].default, true, "Check default route"); - is(aResult["wlan0"].gateway, aStaticIpConfig.gateway, "Check gateway"); - }); -} - -function findDesireNetwork(aNetworks) { - let i = gTestSuite.getFirstIndexBySsid(TESTING_HOSTAPD[0].ssid, aNetworks); - - if (-1 !== i) { - return aNetworks[i]; - } - - return aNetworks[0]; -} - -// Start test. -gTestSuite.doTestWithoutStockAp(function() { - return gTestSuite.ensureWifiEnabled(true) - - // Start custom hostapd for testing. - .then(() => gTestSuite.startHostapds(TESTING_HOSTAPD)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', - TESTING_HOSTAPD.length)) - - // Perform a wifi scan, and then run the static ip test - .then(() => gTestSuite.requestWifiScan()) - .then((aNetworks) => findDesireNetwork(aNetworks)) - .then((aNetwork) => testAssociateWithStaticIp(aNetwork, - STATIC_IP_CONFIG)) - - // Kill running hostapd. - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)); -}); diff --git a/dom/wifi/test/marionette/test_wifi_tethering_wifi_active.js b/dom/wifi/test/marionette/test_wifi_tethering_wifi_active.js deleted file mode 100644 index af0df01a0..000000000 --- a/dom/wifi/test/marionette/test_wifi_tethering_wifi_active.js +++ /dev/null @@ -1,74 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -const TESTING_HOSTAPD = [{ ssid: 'ap0' }]; - -function connectToFirstNetwork() { - let firstNetwork; - return gTestSuite.requestWifiScan() - .then(function (networks) { - firstNetwork = networks[0]; - return gTestSuite.testAssociate(firstNetwork); - }) - .then(() => firstNetwork); -} - -gTestSuite.doTestTethering(function() { - let firstNetwork; - - return gTestSuite.ensureWifiEnabled(true) - // Start custom hostapd for testing. - .then(() => gTestSuite.startHostapds(TESTING_HOSTAPD)) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', TESTING_HOSTAPD.length)) - - // Connect to the testing AP and wait for data becoming disconnected. - .then(function () { - return Promise.all([ - // 1) Set up the event listener first: - // RIL data should become disconnected after connecting to wifi. - gTestSuite.waitForRilDataConnected(false), - - // 2) Connect to the first scanned network. - connectToFirstNetwork() - .then(aFirstNetwork => firstNetwork = aFirstNetwork) - ]); - }) - .then(function() { - return Promise.all([ - // 1) Set up the event listeners first: - // Wifi should be turned off and RIL data should be connected. - gTestSuite.waitForWifiManagerEventOnce('disabled'), - gTestSuite.waitForRilDataConnected(true), - - // 2) Start wifi tethering. - gTestSuite.requestTetheringEnabled(true) - ]); - }) - .then(function() { - return Promise.all([ - // 1) Set up the event listeners first: - // Wifi should be enabled, RIL data should become disconnected and - // we should connect to an wifi AP. - gTestSuite.waitForWifiManagerEventOnce('enabled'), - - // Due to Bug 1168285, after re-enablin wifi, the remembered network - // will not be connected automatically. Leave "auto connect test" - // covered by test_wifi_auto_connect.js. - //gTestSuite.waitForRilDataConnected(false), - //gTestSuite.waitForConnected(firstNetwork), - - // 2) Stop wifi tethering. - gTestSuite.requestTetheringEnabled(false) - ]); - }) - // Remove wlan0 from default route by disabling wifi. Otherwise, - // it will cause the subsequent test cases loading page error. - .then(() => gTestSuite.requestWifiEnabled(false)) - - // Kill running hostapd. - .then(gTestSuite.killAllHostapd) - .then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0)); -});
\ No newline at end of file diff --git a/dom/wifi/test/marionette/test_wifi_tethering_wifi_disabled.js b/dom/wifi/test/marionette/test_wifi_tethering_wifi_disabled.js deleted file mode 100644 index 860a91cf6..000000000 --- a/dom/wifi/test/marionette/test_wifi_tethering_wifi_disabled.js +++ /dev/null @@ -1,11 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.doTestTethering(function() { - return gTestSuite.ensureWifiEnabled(false) - .then(() => gTestSuite.requestTetheringEnabled(true)) - .then(() => gTestSuite.requestTetheringEnabled(false)) -}); diff --git a/dom/wifi/test/marionette/test_wifi_tethering_wifi_inactive.js b/dom/wifi/test/marionette/test_wifi_tethering_wifi_inactive.js deleted file mode 100644 index 2de6ab667..000000000 --- a/dom/wifi/test/marionette/test_wifi_tethering_wifi_inactive.js +++ /dev/null @@ -1,21 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -gTestSuite.doTestTethering(function() { - return gTestSuite.ensureWifiEnabled(true) - .then(function() { - return Promise.all([ - gTestSuite.waitForWifiManagerEventOnce('disabled'), - gTestSuite.requestTetheringEnabled(true) - ]); - }) - .then(function() { - return Promise.all([ - gTestSuite.waitForWifiManagerEventOnce('enabled'), - gTestSuite.requestTetheringEnabled(false) - ]); - }); -}); |