VulpesOS/gaia/shared/js/wifi_helper.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

258 lines
7.2 KiB
JavaScript
Executable file

/* exported WifiHelper */
'use strict';
var WifiHelper = {
getWifiManager: function() {
return this.wifiManager();
},
wifiManager: function() {
return navigator.mozWifiManager;
},
setPassword: function(network, password, identity, eap, phase2, certificate) {
var encType = this.getKeyManagement(network);
switch (encType) {
case 'WPA-PSK':
network.psk = password;
break;
case 'WPA-EAP':
network.eap = eap;
switch (eap) {
case 'SIM':
break;
case 'PEAP':
case 'TLS':
case 'TTLS':
if (password && password.length) {
network.password = password;
}
if (identity && identity.length) {
network.identity = identity;
}
if (phase2 != 'No') {
network.phase2 = phase2;
}
if (certificate != 'none') {
network.serverCertificate = certificate;
}
break;
default:
break;
}
break;
case 'WEP':
network.wep = password;
break;
default:
return;
}
network.keyManagement = encType;
},
setSecurity: function(network, encryptions) {
network.security = encryptions;
},
getSecurity: function(network) {
return network.security;
},
getCapabilities: function(network) {
return network.capabilities === undefined || network.capabilities === null ?
[] : network.capabilities;
},
getKeyManagement: function(network) {
var key = this.getSecurity(network)[0];
if (/WEP$/.test(key)) {
return 'WEP';
}
if (/PSK$/.test(key)) {
return 'WPA-PSK';
}
if (/EAP$/.test(key)) {
return 'WPA-EAP';
}
return '';
},
isConnected: function(network) {
return 'connected' === this.getNetworkStatus(network);
},
getNetworkStatus: function(network) {
/**
* XXX the API should expose a 'connected' property on 'network',
* and 'wifiManager.connection.network' should be comparable to 'network'.
* Until this is properly implemented, we just compare SSIDs to tell wether
* the network is already connected or not.
*/
var currentConnection = this.getWifiManager().connection;
var currentNetwork = currentConnection.network;
if (!currentNetwork || !network) {
return false;
}
var key = network.ssid + '+' + this.getSecurity(network).join('+');
var curkey = currentNetwork.ssid + '+' +
this.getSecurity(currentNetwork).join('+');
return (key === curkey ? currentConnection.status : 'disconnected');
},
isValidInput: function(key, password, identity, eap) {
function isValidWepKey(password) {
switch (password.length) {
case 5:
case 13:
case 16:
case 29:
return true;
case 10:
case 26:
case 32:
case 58:
return !/[^a-fA-F0-9]/.test(password);
default:
return false;
}
}
switch (key) {
case 'WPA-PSK':
if (!password || password.length < 8) {
return false;
}
break;
case 'WPA-EAP':
switch (eap) {
case 'SIM':
break;
case 'PEAP':
case 'TLS':
case 'TTLS':
/* falls through */
default:
if (!password || password.length < 1 ||
!identity || identity.length < 1) {
return false;
}
break;
}
break;
case 'WEP':
if (!password || !isValidWepKey(password)) {
return false;
}
break;
}
return true;
},
isSSIDValid: function(ssid) {
return !!ssid && ssid.length > 0;
},
isWpsAvailable: function(network) {
var capabilities = this.getCapabilities(network);
for (var i = 0; i < capabilities.length; i++) {
if (/WPS/.test(capabilities[i])) {
return true;
}
}
return false;
},
isOpen: function(network) {
return this.getKeyManagement(network) === '';
},
isEap: function(network) {
return this.getKeyManagement(network).indexOf('EAP') !== -1;
},
// Both 'available' and 'known' are "object of networks".
// Each key of them is a composite key of a network,
// and each value is the original network object received from DOMRequest
// It'll be easier to compare in the form of "object of networks"
_unionOfNetworks: function(available, known) {
var allNetworks = available || {};
var result = [];
Object.keys(known).forEach(function(key) {
if (!allNetworks[key]) {
allNetworks[key] = known[key];
}
});
// However, people who use getAvailableAndKnownNetworks expect
// getAvailableAndKnownNetworks.result to be an array of network
Object.keys(allNetworks).forEach(function(key) {
result.push(allNetworks[key]);
});
return result;
},
_networksArrayToObject: function(allNetworks) {
var self = this;
var networksObject = {};
[].forEach.call(allNetworks, function(network) {
// use ssid + security as a composited key
var key = network.ssid + '+' +
self.getSecurity(network).join('+');
// ensure the wifi AP with the strongest signal is picked from wifi APs
// with the same SSID
if (!networksObject[key] ||
network.relSignalStrength > networksObject[key].relSignalStrength) {
networksObject[key] = network;
}
});
return networksObject;
},
_onReqProxySuccess: function(reqProxy, availableNetworks, knownNetworks) {
reqProxy.result =
this._unionOfNetworks(availableNetworks, knownNetworks);
reqProxy.onsuccess();
},
getAvailableAndKnownNetworks: function() {
var self = this;
var reqProxy = {
onsuccess: function() {},
onerror: function() {}
};
var knownNetworks = {};
var availableNetworks = {};
var knownNetworksReq = null;
var availableNetworksReq = this.getWifiManager().getNetworks();
// request available networks first then known networks,
// since it is acceptible that error on requesting known networks
availableNetworksReq.onsuccess = function anrOnSuccess() {
availableNetworks =
self._networksArrayToObject(availableNetworksReq.result);
knownNetworksReq = self.getWifiManager().getKnownNetworks();
knownNetworksReq.onsuccess = function knrOnSuccess() {
knownNetworks = self._networksArrayToObject(knownNetworksReq.result);
self._onReqProxySuccess(
reqProxy, availableNetworks, knownNetworks);
};
knownNetworksReq.onerror = function knrOnError() {
// it is acceptible that no known networks found or error
// on requesting known networks
self._onReqProxySuccess(
reqProxy, availableNetworks, knownNetworks);
};
};
availableNetworksReq.onerror = function anrOnError() {
reqProxy.error = availableNetworksReq.error;
reqProxy.onerror();
};
return reqProxy;
},
// Returns signal strength in terms of signal bars
getSignalLevel: function(network) {
return Math.min(Math.floor(network.relSignalStrength / 20), 4);
}
};