This commit is contained in:
Ryan VanderMeulen 2013-07-08 10:22:37 -04:00
Родитель a3df6b2f13 b504cafa6e
Коммит 6f550edf45
16 изменённых файлов: 310 добавлений и 106 удалений

Просмотреть файл

@ -1,4 +1,4 @@
{ {
"revision": "a80b392a3551e220c252228c5354cd85496cb625", "revision": "09cdef3222986569ee93081d7ef0e7f9cc0894f9",
"repo_path": "/integration/gaia-central" "repo_path": "/integration/gaia-central"
} }

Просмотреть файл

@ -9,7 +9,7 @@ interface nsIDOMEventListener;
interface nsIDOMDOMRequest; interface nsIDOMDOMRequest;
interface nsIDOMContact; interface nsIDOMContact;
[scriptable, builtinclass, uuid(b4e16bb0-a258-11e2-9e96-0800200c9a66)] [scriptable, builtinclass, uuid(d21b7070-c2bc-11e2-8b8b-0800200c9a66)]
interface nsIDOMMozIccManager : nsIDOMEventTarget interface nsIDOMMozIccManager : nsIDOMEventTarget
{ {
/** /**
@ -275,6 +275,22 @@ interface nsIDOMMozIccManager : nsIDOMEventTarget
*/ */
[implicit_jscontext] attribute jsval onstksessionend; [implicit_jscontext] attribute jsval onstksessionend;
// UICC Card State.
/**
* Indicates the state of the device's ICC card.
*
* Possible values: null, 'unknown', 'absent', 'pinRequired', 'pukRequired',
* 'networkLocked', 'corporateLocked', 'serviceProviderLocked', 'ready'.
*/
readonly attribute DOMString cardState;
/**
* The 'cardstatechange' event is notified when the 'cardState' attribute
* changes value.
*/
[implicit_jscontext] attribute jsval oncardstatechange;
// UICC Card Lock interfaces. // UICC Card Lock interfaces.
/** /**

Просмотреть файл

@ -8,19 +8,20 @@ interface nsIDOMWindow;
interface nsIDOMDOMRequest; interface nsIDOMDOMRequest;
interface nsIDOMContact; interface nsIDOMContact;
[scriptable, uuid(dca08580-a25a-11e2-9e96-0800200c9a66)] [scriptable, uuid(5902d9b0-c2be-11e2-8b8b-0800200c9a66)]
interface nsIIccListener : nsISupports interface nsIIccListener : nsISupports
{ {
void notifyStkCommand(in DOMString aMessage); void notifyStkCommand(in DOMString aMessage);
void notifyStkSessionEnd(); void notifyStkSessionEnd();
void notifyIccCardLockError(in DOMString lockType, void notifyIccCardLockError(in DOMString lockType,
in unsigned long retryCount); in unsigned long retryCount);
void notifyCardStateChanged();
}; };
/** /**
* XPCOM component (in the content process) that provides the ICC information. * XPCOM component (in the content process) that provides the ICC information.
*/ */
[scriptable, uuid(e60ec460-a25a-11e2-9e96-0800200c9a66)] [scriptable, uuid(77487bf0-c2be-11e2-8b8b-0800200c9a66)]
interface nsIIccProvider : nsISupports interface nsIIccProvider : nsISupports
{ {
/** /**
@ -31,6 +32,11 @@ interface nsIIccProvider : nsISupports
void registerIccMsg(in nsIIccListener listener); void registerIccMsg(in nsIIccListener listener);
void unregisterIccMsg(in nsIIccListener listener); void unregisterIccMsg(in nsIIccListener listener);
/**
* Card State
*/
readonly attribute DOMString cardState;
/** /**
* STK interfaces. * STK interfaces.
*/ */

Просмотреть файл

@ -129,6 +129,17 @@ IccManager::SendStkEventDownload(const JS::Value& aEvent)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
IccManager::GetCardState(nsAString& cardState)
{
cardState.SetIsVoid(true);
if (!mProvider) {
return NS_ERROR_FAILURE;
}
return mProvider->GetCardState(cardState);
}
NS_IMETHODIMP NS_IMETHODIMP
IccManager::GetCardLock(const nsAString& aLockType, nsIDOMDOMRequest** aDomRequest) IccManager::GetCardLock(const nsAString& aLockType, nsIDOMDOMRequest** aDomRequest)
{ {
@ -215,6 +226,7 @@ IccManager::UpdateContact(const nsAString& aContactType,
NS_IMPL_EVENT_HANDLER(IccManager, stkcommand) NS_IMPL_EVENT_HANDLER(IccManager, stkcommand)
NS_IMPL_EVENT_HANDLER(IccManager, stksessionend) NS_IMPL_EVENT_HANDLER(IccManager, stksessionend)
NS_IMPL_EVENT_HANDLER(IccManager, icccardlockerror) NS_IMPL_EVENT_HANDLER(IccManager, icccardlockerror)
NS_IMPL_EVENT_HANDLER(IccManager, cardstatechange)
// nsIIccListener // nsIIccListener
@ -247,3 +259,9 @@ IccManager::NotifyIccCardLockError(const nsAString& aLockType, uint32_t aRetryCo
return DispatchTrustedEvent(ce); return DispatchTrustedEvent(ce);
} }
NS_IMETHODIMP
IccManager::NotifyCardStateChanged()
{
return DispatchTrustedEvent(NS_LITERAL_STRING("cardstatechange"));
}

Просмотреть файл

@ -6,6 +6,7 @@ qemu = true
[test_stk_proactive_command.js] [test_stk_proactive_command.js]
[test_icc_contact.js] [test_icc_contact.js]
[test_icc_card_lock.js] [test_icc_card_lock.js]
[test_icc_card_state.js]
[test_stk_refresh.js] [test_stk_refresh.js]
[test_stk_poll_off.js] [test_stk_poll_off.js]
[test_stk_setup_event_list.js] [test_stk_setup_event_list.js]

Просмотреть файл

@ -0,0 +1,61 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
SpecialPowers.addPermission("mobileconnection", true, document);
SpecialPowers.addPermission("settings-write", true, document);
let icc = navigator.mozIccManager;
ok(icc instanceof MozIccManager, "icc is instanceof " + icc.constructor);
is(icc.cardState, "ready");
function setAirplaneModeEnabled(enabled) {
let settings = window.navigator.mozSettings;
let setLock = settings.createLock();
let obj = {
"ril.radio.disabled": enabled
};
let setReq = setLock.set(obj);
log("set airplane mode to " + enabled);
setReq.addEventListener("success", function onSetSuccess() {
log("set 'ril.radio.disabled' to " + enabled);
});
setReq.addEventListener("error", function onSetError() {
ok(false, "cannot set 'ril.radio.disabled' to " + enabled);
});
}
function waitCardStateChangedEvent(expectedCardState, callback) {
icc.addEventListener("cardstatechange", function oncardstatechange() {
log("card state changes to " + icc.cardState);
if (icc.cardState === expectedCardState) {
log("got expected card state: " + icc.cardState);
icc.removeEventListener("cardstatechange", oncardstatechange);
callback();
}
});
}
// Test cardstatechange event by switching airplane mode
function testCardStateChange(airplaneMode, expectedCardState, callback) {
setAirplaneModeEnabled(airplaneMode);
waitCardStateChangedEvent(expectedCardState, callback);
}
function cleanUp() {
SpecialPowers.removePermission("mobileconnection", document);
SpecialPowers.removePermission("settings-write", document);
finish();
}
// Enable Airplane mode, expect got cardstatechange to null
testCardStateChange(true, null,
// Disable Airplane mode, expect got cardstatechange to 'ready'
testCardStateChange.bind(this, false, "ready", cleanUp)
);

Просмотреть файл

@ -12,7 +12,7 @@ interface nsIDOMMozMobileNetworkInfo;
interface nsIDOMMozMobileCellInfo; interface nsIDOMMozMobileCellInfo;
interface nsIDOMMozMobileCFInfo; interface nsIDOMMozMobileCFInfo;
[scriptable, builtinclass, uuid(c7fdf0f0-a740-11e2-9e96-0800200c9a66)] [scriptable, builtinclass, uuid(dc010230-c2bc-11e2-8b8b-0800200c9a66)]
interface nsIDOMMozMobileConnection : nsIDOMEventTarget interface nsIDOMMozMobileConnection : nsIDOMEventTarget
{ {
const long ICC_SERVICE_CLASS_VOICE = (1 << 0); const long ICC_SERVICE_CLASS_VOICE = (1 << 0);
@ -47,14 +47,6 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
readonly attribute DOMString lastKnownNetwork; readonly attribute DOMString lastKnownNetwork;
readonly attribute DOMString lastKnownHomeNetwork; readonly attribute DOMString lastKnownHomeNetwork;
/**
* Indicates the state of the device's ICC card.
*
* Possible values: null, 'unknown', 'absent', 'pinRequired', 'pukRequired',
* 'networkLocked', 'corporateLocked', 'serviceProviderLocked', 'ready'.
*/
readonly attribute DOMString cardState;
/** /**
* Indicates the number of retries remaining when cardState equals 'pinRequired' * Indicates the number of retries remaining when cardState equals 'pinRequired'
* or 'pukRequired'. 0 denotes the retry count is unavailable. * or 'pukRequired'. 0 denotes the retry count is unavailable.
@ -240,12 +232,6 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
*/ */
nsIDOMDOMRequest getCallWaitingOption(); nsIDOMDOMRequest getCallWaitingOption();
/**
* The 'cardstatechange' event is notified when the 'cardState' attribute
* changes value.
*/
[implicit_jscontext] attribute jsval oncardstatechange;
/** /**
* The 'iccinfochange' event is notified whenever the icc info object * The 'iccinfochange' event is notified whenever the icc info object
* changes. * changes.

Просмотреть файл

@ -11,12 +11,11 @@ interface nsIDOMMozMobileCFInfo;
interface nsIDOMDOMRequest; interface nsIDOMDOMRequest;
interface nsIDOMWindow; interface nsIDOMWindow;
[scriptable, uuid(d09099b0-a25a-11e2-9e96-0800200c9a66)] [scriptable, uuid(529864f0-c2be-11e2-8b8b-0800200c9a66)]
interface nsIMobileConnectionListener : nsISupports interface nsIMobileConnectionListener : nsISupports
{ {
void notifyVoiceChanged(); void notifyVoiceChanged();
void notifyDataChanged(); void notifyDataChanged();
void notifyCardStateChanged();
void notifyIccInfoChanged(); void notifyIccInfoChanged();
void notifyUssdReceived(in DOMString message, void notifyUssdReceived(in DOMString message,
in boolean sessionEnded); in boolean sessionEnded);
@ -33,7 +32,7 @@ interface nsIMobileConnectionListener : nsISupports
* XPCOM component (in the content process) that provides the mobile * XPCOM component (in the content process) that provides the mobile
* network information. * network information.
*/ */
[scriptable, uuid(b9605230-a25a-11e2-9e96-0800200c9a66)] [scriptable, uuid(66e7ac90-c2be-11e2-8b8b-0800200c9a66)]
interface nsIMobileConnectionProvider : nsISupports interface nsIMobileConnectionProvider : nsISupports
{ {
/** /**
@ -44,7 +43,6 @@ interface nsIMobileConnectionProvider : nsISupports
void registerMobileConnectionMsg(in nsIMobileConnectionListener listener); void registerMobileConnectionMsg(in nsIMobileConnectionListener listener);
void unregisterMobileConnectionMsg(in nsIMobileConnectionListener listener); void unregisterMobileConnectionMsg(in nsIMobileConnectionListener listener);
readonly attribute DOMString cardState;
readonly attribute long retryCount; readonly attribute long retryCount;
readonly attribute nsIDOMMozMobileICCInfo iccInfo; readonly attribute nsIDOMMozMobileICCInfo iccInfo;
readonly attribute nsIDOMMozMobileConnectionInfo voiceConnectionInfo; readonly attribute nsIDOMMozMobileConnectionInfo voiceConnectionInfo;

Просмотреть файл

@ -67,7 +67,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(MobileConnection, nsDOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(MobileConnection, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(MobileConnection, nsDOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(MobileConnection, nsDOMEventTargetHelper)
NS_IMPL_EVENT_HANDLER(MobileConnection, cardstatechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, iccinfochange) NS_IMPL_EVENT_HANDLER(MobileConnection, iccinfochange)
NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange) NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, datachange) NS_IMPL_EVENT_HANDLER(MobileConnection, datachange)
@ -162,17 +161,6 @@ MobileConnection::CheckPermission(const char* type)
return permission == nsIPermissionManager::ALLOW_ACTION; return permission == nsIPermissionManager::ALLOW_ACTION;
} }
NS_IMETHODIMP
MobileConnection::GetCardState(nsAString& cardState)
{
cardState.SetIsVoid(true);
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetCardState(cardState);
}
NS_IMETHODIMP NS_IMETHODIMP
MobileConnection::GetRetryCount(int32_t* retryCount) MobileConnection::GetRetryCount(int32_t* retryCount)
{ {
@ -428,16 +416,6 @@ MobileConnection::NotifyDataChanged()
return DispatchTrustedEvent(NS_LITERAL_STRING("datachange")); return DispatchTrustedEvent(NS_LITERAL_STRING("datachange"));
} }
NS_IMETHODIMP
MobileConnection::NotifyCardStateChanged()
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
return DispatchTrustedEvent(NS_LITERAL_STRING("cardstatechange"));
}
NS_IMETHODIMP NS_IMETHODIMP
MobileConnection::NotifyIccInfoChanged() MobileConnection::NotifyIccInfoChanged()
{ {

Просмотреть файл

@ -85,6 +85,10 @@ const SETTINGS_USB_DHCPSERVER_ENDIP = "tethering.usb.dhcpserver.endip";
const SETTINGS_USB_DNS1 = "tethering.usb.dns1"; const SETTINGS_USB_DNS1 = "tethering.usb.dns1";
const SETTINGS_USB_DNS2 = "tethering.usb.dns2"; const SETTINGS_USB_DNS2 = "tethering.usb.dns2";
// Settings DB path for WIFI tethering.
const SETTINGS_WIFI_DHCPSERVER_STARTIP = "tethering.wifi.dhcpserver.startip";
const SETTINGS_WIFI_DHCPSERVER_ENDIP = "tethering.wifi.dhcpserver.endip";
// Default value for USB tethering. // Default value for USB tethering.
const DEFAULT_USB_IP = "192.168.0.1"; const DEFAULT_USB_IP = "192.168.0.1";
const DEFAULT_USB_PREFIX = "24"; const DEFAULT_USB_PREFIX = "24";
@ -94,6 +98,9 @@ const DEFAULT_USB_DHCPSERVER_ENDIP = "192.168.0.30";
const DEFAULT_DNS1 = "8.8.8.8"; const DEFAULT_DNS1 = "8.8.8.8";
const DEFAULT_DNS2 = "8.8.4.4"; const DEFAULT_DNS2 = "8.8.4.4";
const DEFAULT_WIFI_DHCPSERVER_STARTIP = "192.168.1.10";
const DEFAULT_WIFI_DHCPSERVER_ENDIP = "192.168.1.30";
const MANUAL_PROXY_CONFIGURATION = 1; const MANUAL_PROXY_CONFIGURATION = 1;
const DEBUG = false; const DEBUG = false;
@ -174,13 +181,19 @@ function NetworkManager() {
settingsLock.get(SETTINGS_USB_DNS2, this); settingsLock.get(SETTINGS_USB_DNS2, this);
settingsLock.get(SETTINGS_USB_ENABLED, this); settingsLock.get(SETTINGS_USB_ENABLED, this);
// Read wifi tethering data from settings DB.
settingsLock.get(SETTINGS_WIFI_DHCPSERVER_STARTIP, this);
settingsLock.get(SETTINGS_WIFI_DHCPSERVER_ENDIP, this);
this._usbTetheringSettingsToRead = [SETTINGS_USB_IP, this._usbTetheringSettingsToRead = [SETTINGS_USB_IP,
SETTINGS_USB_PREFIX, SETTINGS_USB_PREFIX,
SETTINGS_USB_DHCPSERVER_STARTIP, SETTINGS_USB_DHCPSERVER_STARTIP,
SETTINGS_USB_DHCPSERVER_ENDIP, SETTINGS_USB_DHCPSERVER_ENDIP,
SETTINGS_USB_DNS1, SETTINGS_USB_DNS1,
SETTINGS_USB_DNS2, SETTINGS_USB_DNS2,
SETTINGS_USB_ENABLED]; SETTINGS_USB_ENABLED,
SETTINGS_WIFI_DHCPSERVER_STARTIP,
SETTINGS_WIFI_DHCPSERVER_ENDIP];
this.wantConnectionEvent = null; this.wantConnectionEvent = null;
this.setAndConfigureActive(); this.setAndConfigureActive();
@ -664,6 +677,9 @@ NetworkManager.prototype = {
this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP] = DEFAULT_USB_DHCPSERVER_ENDIP; this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP] = DEFAULT_USB_DHCPSERVER_ENDIP;
this.tetheringSettings[SETTINGS_USB_DNS1] = DEFAULT_DNS1; this.tetheringSettings[SETTINGS_USB_DNS1] = DEFAULT_DNS1;
this.tetheringSettings[SETTINGS_USB_DNS2] = DEFAULT_DNS2; this.tetheringSettings[SETTINGS_USB_DNS2] = DEFAULT_DNS2;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP] = DEFAULT_WIFI_DHCPSERVER_STARTIP;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP;
}, },
_requestCount: 0, _requestCount: 0,
@ -678,6 +694,8 @@ NetworkManager.prototype = {
case SETTINGS_USB_DHCPSERVER_ENDIP: case SETTINGS_USB_DHCPSERVER_ENDIP:
case SETTINGS_USB_DNS1: case SETTINGS_USB_DNS1:
case SETTINGS_USB_DNS2: case SETTINGS_USB_DNS2:
case SETTINGS_WIFI_DHCPSERVER_STARTIP:
case SETTINGS_WIFI_DHCPSERVER_ENDIP:
if (aResult !== null) { if (aResult !== null) {
this.tetheringSettings[aName] = aResult; this.tetheringSettings[aName] = aResult;
} }
@ -772,8 +790,10 @@ NetworkManager.prototype = {
getUSBTetheringParameters: function getUSBTetheringParameters(enable, tetheringinterface) { getUSBTetheringParameters: function getUSBTetheringParameters(enable, tetheringinterface) {
let interfaceIp; let interfaceIp;
let prefix; let prefix;
let dhcpStartIp; let wifiDhcpStartIp;
let dhcpEndIp; let wifiDhcpEndIp;
let usbDhcpStartIp;
let usbDhcpEndIp;
let dns1; let dns1;
let dns2; let dns2;
let internalInterface = tetheringinterface.internalInterface; let internalInterface = tetheringinterface.internalInterface;
@ -781,14 +801,17 @@ NetworkManager.prototype = {
interfaceIp = this.tetheringSettings[SETTINGS_USB_IP]; interfaceIp = this.tetheringSettings[SETTINGS_USB_IP];
prefix = this.tetheringSettings[SETTINGS_USB_PREFIX]; prefix = this.tetheringSettings[SETTINGS_USB_PREFIX];
dhcpStartIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP]; wifiDhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP];
dhcpEndIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP]; 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_USB_DNS1]; dns1 = this.tetheringSettings[SETTINGS_USB_DNS1];
dns2 = this.tetheringSettings[SETTINGS_USB_DNS2]; dns2 = this.tetheringSettings[SETTINGS_USB_DNS2];
// Using the default values here until application support these settings. // Using the default values here until application support these settings.
if (interfaceIp == "" || prefix == "" || if (interfaceIp == "" || prefix == "" ||
dhcpStartIp == "" || dhcpEndIp == "") { wifiDhcpStartIp == "" || wifiDhcpEndIp == "" ||
usbDhcpStartIp == "" || usbDhcpEndIp == "") {
debug("Invalid subnet information."); debug("Invalid subnet information.");
return null; return null;
} }
@ -797,8 +820,10 @@ NetworkManager.prototype = {
ifname: internalInterface, ifname: internalInterface,
ip: interfaceIp, ip: interfaceIp,
prefix: prefix, prefix: prefix,
startIp: dhcpStartIp, wifiStartIp: wifiDhcpStartIp,
endIp: dhcpEndIp, wifiEndIp: wifiDhcpEndIp,
usbStartIp: usbDhcpStartIp,
usbEndIp: usbDhcpEndIp,
dns1: dns1, dns1: dns1,
dns2: dns2, dns2: dns2,
internalIfname: internalInterface, internalIfname: internalInterface,

Просмотреть файл

@ -1300,7 +1300,7 @@ RILContentHelper.prototype = {
this.rilContext.retryCount = data.retryCount; this.rilContext.retryCount = data.retryCount;
if (this.rilContext.cardState != data.cardState) { if (this.rilContext.cardState != data.cardState) {
this.rilContext.cardState = data.cardState; this.rilContext.cardState = data.cardState;
this._deliverEvent("_mobileConnectionListeners", this._deliverEvent("_iccListeners",
"notifyCardStateChanged", "notifyCardStateChanged",
null); null);
} }

Просмотреть файл

@ -979,8 +979,8 @@ RadioInterface.prototype = {
break; break;
case "cardstatechange": case "cardstatechange":
this.rilContext.cardState = message.cardState; this.rilContext.cardState = message.cardState;
gMessageManager.sendMobileConnectionMessage("RIL:CardStateChanged", gMessageManager.sendIccMessage("RIL:CardStateChanged",
this.clientId, message); this.clientId, message);
break; break;
case "sms-received": case "sms-received":
let ackOk = this.handleSmsReceived(message); let ackOk = this.handleSmsReceived(message);

Просмотреть файл

@ -27,6 +27,9 @@ const USB_FUNCTION_ADB = "adb";
const kNetdInterfaceChangedTopic = "netd-interface-change"; const kNetdInterfaceChangedTopic = "netd-interface-change";
const kNetdBandwidthControlTopic = "netd-bandwidth-control"; const kNetdBandwidthControlTopic = "netd-bandwidth-control";
// Use this command to continue the function chain.
const DUMMY_COMMAND = "tether status";
// Retry 20 times (2 seconds) for usb state transition. // Retry 20 times (2 seconds) for usb state transition.
const USB_FUNCTION_RETRY_TIMES = 20; const USB_FUNCTION_RETRY_TIMES = 20;
// Check "sys.usb.state" every 100ms. // Check "sys.usb.state" every 100ms.
@ -69,6 +72,11 @@ function isComplete(code) {
return (type != NETD_COMMAND_PROCEEDING); return (type != NETD_COMMAND_PROCEEDING);
} }
function isProceeding(code) {
let type = netdResponseType(code);
return (type === NETD_COMMAND_PROCEEDING);
}
function sendBroadcastMessage(code, reason) { function sendBroadcastMessage(code, reason) {
let topic = null; let topic = null;
switch (code) { switch (code) {
@ -268,6 +276,7 @@ let gCommandQueue = [];
let gCurrentCommand = null; let gCurrentCommand = null;
let gCurrentCallback = null; let gCurrentCallback = null;
let gPending = false; let gPending = false;
let gReason = [];
/** /**
* Handle received data from netd. * Handle received data from netd.
@ -294,23 +303,33 @@ function onNetdMessage(data) {
reason += String.fromCharCode(octet); reason += String.fromCharCode(octet);
} }
if (isBroadcastMessage(code)) {
debug("Receiving broadcast message from netd.");
debug(" ==> Code: " + code + " Reason: " + reason);
sendBroadcastMessage(code, reason);
nextNetdCommand();
return;
}
// Set pending to false before we handle next command. // Set pending to false before we handle next command.
debug("Receiving '" + gCurrentCommand + "' command response from netd."); debug("Receiving '" + gCurrentCommand + "' command response from netd.");
debug(" ==> Code: " + code + " Reason: " + reason); debug(" ==> Code: " + code + " Reason: " + reason);
gReason.push(reason);
// 1xx response code regards as command is proceeding, we need to wait for // 1xx response code regards as command is proceeding, we need to wait for
// final response code such as 2xx, 4xx and 5xx before sending next command. // final response code such as 2xx, 4xx and 5xx before sending next command.
if (isBroadcastMessage(code)) { if (isProceeding(code)) {
sendBroadcastMessage(code, reason);
nextNetdCommand();
return; return;
} }
if (isComplete(code)) { if (isComplete(code)) {
gPending = false; gPending = false;
} }
if (gCurrentCallback) { if (gCurrentCallback) {
gCurrentCallback(isError(code), {code: code, reason: reason}); gCurrentCallback(isError(code), {code: code, reason: gReason.join(" ")});
gReason = [];
} }
// Handling pending commands if any. // Handling pending commands if any.
@ -356,18 +375,45 @@ function setIpForwardingEnabled(params, callback) {
if (params.enable) { if (params.enable) {
command = "ipfwd enable"; command = "ipfwd enable";
} else { } else {
command = "ipfwd disable"; // Don't disable ip forwarding because others interface still need it.
// Send the dummy command to continue the function chain.
if (params.interfaceList.length > 1) {
command = DUMMY_COMMAND;
} else {
command = "ipfwd disable";
}
} }
return doCommand(command, callback); return doCommand(command, callback);
} }
function startTethering(params, callback) { function startTethering(params, callback) {
let command = "tether start " + params.startIp + " " + params.endIp; let command;
// We don't need to start tethering again.
// Send the dummy command to continue the function chain.
if (params.resultReason.indexOf("started") !== -1) {
command = DUMMY_COMMAND;
} else {
command = "tether start " + params.wifiStartIp + " " + params.wifiEndIp +
" " + params.usbStartIp + " " + params.usbEndIp;
}
return doCommand(command, callback);
}
function tetheringStatus(params, callback) {
let command = "tether status";
return doCommand(command, callback); return doCommand(command, callback);
} }
function stopTethering(params, callback) { function stopTethering(params, callback) {
let command = "tether stop"; let command;
// Don't stop tethering because others interface still need it.
// Send the dummy to continue the function chain.
if (params.interfaceList.length > 1) {
command = DUMMY_COMMAND;
} else {
command = "tether stop";
}
return doCommand(command, callback); return doCommand(command, callback);
} }
@ -376,6 +422,19 @@ function tetherInterface(params, callback) {
return doCommand(command, callback); return doCommand(command, callback);
} }
function preTetherInterfaceList(params, callback) {
let command = "tether interface list 0";
return doCommand(command, callback);
}
function postTetherInterfaceList(params, callback) {
params.interfaceList = params.resultReason.split(" ");
// Send the dummy command to continue the function chain.
let command = DUMMY_COMMAND;
return doCommand(command, callback);
}
function untetherInterface(params, callback) { function untetherInterface(params, callback) {
let command = "tether interface remove " + params.ifname; let command = "tether interface remove " + params.ifname;
return doCommand(command, callback); return doCommand(command, callback);
@ -393,8 +452,16 @@ function enableNat(params, callback) {
} }
function disableNat(params, callback) { function disableNat(params, callback) {
let command = "nat disable " + params.internalIfname + " " + let command;
params.externalIfname + " " + "0";
// Don't disable nat because others interface still need it.
// Send the dummy command to continue the function chain.
if (params.interfaceList.length > 1) {
command = DUMMY_COMMAND;
} else {
command = "nat disable " + params.internalIfname + " " +
params.externalIfname + " " + "0";
}
return doCommand(command, callback); return doCommand(command, callback);
} }
@ -594,6 +661,7 @@ let gWifiEnableChain = [wifiFirmwareReload,
setInterfaceUp, setInterfaceUp,
tetherInterface, tetherInterface,
setIpForwardingEnabled, setIpForwardingEnabled,
tetheringStatus,
startTethering, startTethering,
setDnsForwarders, setDnsForwarders,
enableNat, enableNat,
@ -602,8 +670,10 @@ let gWifiEnableChain = [wifiFirmwareReload,
let gWifiDisableChain = [stopSoftAP, let gWifiDisableChain = [stopSoftAP,
stopAccessPointDriver, stopAccessPointDriver,
wifiFirmwareReload, wifiFirmwareReload,
disableNat,
untetherInterface, untetherInterface,
preTetherInterfaceList,
postTetherInterfaceList,
disableNat,
setIpForwardingEnabled, setIpForwardingEnabled,
stopTethering, stopTethering,
wifiTetheringSuccess]; wifiTetheringSuccess];
@ -651,14 +721,17 @@ let gUSBEnableChain = [setInterfaceUp,
enableNat, enableNat,
setIpForwardingEnabled, setIpForwardingEnabled,
tetherInterface, tetherInterface,
tetheringStatus,
startTethering, startTethering,
setDnsForwarders, setDnsForwarders,
usbTetheringSuccess]; usbTetheringSuccess];
let gUSBDisableChain = [disableNat, let gUSBDisableChain = [untetherInterface,
preTetherInterfaceList,
postTetherInterfaceList,
disableNat,
setIpForwardingEnabled, setIpForwardingEnabled,
stopTethering, stopTethering,
untetherInterface,
usbTetheringSuccess]; usbTetheringSuccess];
/** /**

Просмотреть файл

@ -26,6 +26,7 @@ function exposeCurrentNetwork(currentNetwork) {
exposeCurrentNetwork.currentNetworkApi = { exposeCurrentNetwork.currentNetworkApi = {
ssid: "r", ssid: "r",
security: "r",
capabilities: "r", capabilities: "r",
known: "r" known: "r"
}; };

Просмотреть файл

@ -39,6 +39,10 @@ const SETTINGS_WIFI_DHCPSERVER_ENDIP = "tethering.wifi.dhcpserver.endip";
const SETTINGS_WIFI_DNS1 = "tethering.wifi.dns1"; const SETTINGS_WIFI_DNS1 = "tethering.wifi.dns1";
const SETTINGS_WIFI_DNS2 = "tethering.wifi.dns2"; 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. // Default value for WIFI tethering.
const DEFAULT_WIFI_IP = "192.168.1.1"; const DEFAULT_WIFI_IP = "192.168.1.1";
const DEFAULT_WIFI_PREFIX = "24"; const DEFAULT_WIFI_PREFIX = "24";
@ -50,6 +54,10 @@ const DEFAULT_WIFI_SECURITY_PASSWORD = "1234567890";
const DEFAULT_DNS1 = "8.8.8.8"; const DEFAULT_DNS1 = "8.8.8.8";
const DEFAULT_DNS2 = "8.8.4.4"; 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_AP = "AP";
const WIFI_FIRMWARE_STATION = "STA"; const WIFI_FIRMWARE_STATION = "STA";
const WIFI_SECURITY_TYPE_NONE = "open"; const WIFI_SECURITY_TYPE_NONE = "open";
@ -380,8 +388,10 @@ var WifiManager = (function() {
doBooleanCommand("WPS_PBC", "OK", callback); doBooleanCommand("WPS_PBC", "OK", callback);
} }
function wpsPinCommand(pin, callback) { function wpsPinCommand(detail, callback) {
doStringCommand("WPS_PIN any" + (pin === undefined ? "" : (" " + pin)), doStringCommand("WPS_PIN " +
(detail.bssid === undefined ? "any" : detail.bssid) +
(detail.pin === undefined ? "" : (" " + detail.pin)),
callback); callback);
} }
@ -1566,29 +1576,29 @@ function getNetworkKey(network)
var ssid = "", var ssid = "",
encryption = "OPEN"; encryption = "OPEN";
if ("capabilities" in network) { if ("security" in network) {
// manager network object, represents an AP // manager network object, represents an AP
// object structure // object structure
// { // {
// .ssid : SSID of AP // .ssid : SSID of AP
// .capabilities[] : "WPA-PSK" for WPA-PSK // .security[] : "WPA-PSK" for WPA-PSK
// "WPA-EAP" for WPA-EAP // "WPA-EAP" for WPA-EAP
// "WEP" for WEP // "WEP" for WEP
// "" for OPEN // "" for OPEN
// other keys // other keys
// } // }
var capabilities = network.capabilities; var security = network.security;
ssid = network.ssid; ssid = network.ssid;
for (let j = 0; j < capabilities.length; j++) { for (let j = 0; j < security.length; j++) {
if (capabilities[j] === "WPA-PSK") { if (security[j] === "WPA-PSK") {
encryption = "WPA-PSK"; encryption = "WPA-PSK";
break; break;
} else if (capabilities[j] === "WPA-EAP") { } else if (security[j] === "WPA-EAP") {
encryption = "WPA-EAP"; encryption = "WPA-EAP";
break; break;
} else if (capabilities[j] === "WEP") { } else if (security[j] === "WEP") {
encryption = "WEP"; encryption = "WEP";
break; break;
} }
@ -1640,6 +1650,16 @@ function getKeyManagement(flags) {
return types; 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 // These constants shamelessly ripped from WifiManager.java
// strength is the value returned by scan_results. It is nominally in dB. We // 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 // transform it into a percentage for clients looking to simply show a
@ -1662,12 +1682,14 @@ function calculateSignal(strength) {
return Math.floor(((strength - MIN_RSSI) / (MAX_RSSI - MIN_RSSI)) * 100); return Math.floor(((strength - MIN_RSSI) / (MAX_RSSI - MIN_RSSI)) * 100);
} }
function Network(ssid, capabilities, password) { function Network(ssid, security, password, capabilities) {
this.ssid = ssid; this.ssid = ssid;
this.capabilities = capabilities; this.security = security;
if (typeof password !== "undefined") if (typeof password !== "undefined")
this.password = password; this.password = password;
if (capabilities !== undefined)
this.capabilities = capabilities;
// TODO connected here as well? // TODO connected here as well?
this.__exposedProps__ = Network.api; this.__exposedProps__ = Network.api;
@ -1675,6 +1697,7 @@ function Network(ssid, capabilities, password) {
Network.api = { Network.api = {
ssid: "r", ssid: "r",
security: "r",
capabilities: "r", capabilities: "r",
known: "r", known: "r",
@ -1692,7 +1715,8 @@ Network.api = {
// Note: We never use ScanResult.prototype, so the fact that it's unrelated to // Note: We never use ScanResult.prototype, so the fact that it's unrelated to
// Network.prototype is OK. // Network.prototype is OK.
function ScanResult(ssid, bssid, flags, signal) { function ScanResult(ssid, bssid, flags, signal) {
Network.call(this, ssid, getKeyManagement(flags)); Network.call(this, ssid, getKeyManagement(flags), undefined,
getCapabilities(flags));
this.bssid = bssid; this.bssid = bssid;
this.signalStrength = signal; this.signalStrength = signal;
this.relSignalStrength = calculateSignal(Number(signal)); this.relSignalStrength = calculateSignal(Number(signal));
@ -1868,11 +1892,9 @@ function WifiWorker() {
// self.configuredNetworks and prepares it for the DOM. // self.configuredNetworks and prepares it for the DOM.
netToDOM = function(net) { netToDOM = function(net) {
var ssid = dequote(net.ssid); var ssid = dequote(net.ssid);
var capabilities = (net.key_mgmt === "NONE" && net.wep_key0) var security = (net.key_mgmt === "NONE" && net.wep_key0) ? ["WEP"] :
? ["WEP"] (net.key_mgmt && net.key_mgmt !== "NONE") ? [net.key_mgmt] :
: (net.key_mgmt && net.key_mgmt !== "NONE") [];
? [net.key_mgmt]
: [];
var password; var password;
if (("psk" in net && net.psk) || if (("psk" in net && net.psk) ||
("password" in net && net.password) || ("password" in net && net.password) ||
@ -1880,7 +1902,7 @@ function WifiWorker() {
password = "*"; password = "*";
} }
var pub = new Network(ssid, capabilities, password); var pub = new Network(ssid, security, password);
if (net.identity) if (net.identity)
pub.identity = dequote(net.identity); pub.identity = dequote(net.identity);
if (net.netId) if (net.netId)
@ -1901,6 +1923,7 @@ function WifiWorker() {
delete net.bssid; delete net.bssid;
delete net.signalStrength; delete net.signalStrength;
delete net.relSignalStrength; delete net.relSignalStrength;
delete net.security;
delete net.capabilities; delete net.capabilities;
if (!configured) if (!configured)
@ -2252,17 +2275,17 @@ function WifiWorker() {
network.password = "*"; network.password = "*";
} }
} else if (!self._allowWpaEap && } else if (!self._allowWpaEap &&
(eapIndex = network.capabilities.indexOf("WPA-EAP")) >= 0) { (eapIndex = network.security.indexOf("WPA-EAP")) >= 0) {
// Don't offer to connect to WPA-EAP networks unless one has been // Don't offer to connect to WPA-EAP networks unless one has been
// configured through other means (e.g. it was added directly to // configured through other means (e.g. it was added directly to
// wpa_supplicant.conf). Here, we have an unknown WPA-EAP network, // wpa_supplicant.conf). Here, we have an unknown WPA-EAP network,
// so we ignore it entirely if it only supports WPA-EAP, otherwise // so we ignore it entirely if it only supports WPA-EAP, otherwise
// we take EAP out of the list and offer the rest of the // we take EAP out of the list and offer the rest of the
// capabilities. // security.
if (network.capabilities.length === 1) if (network.security.length === 1)
continue; continue;
network.capabilities.splice(eapIndex, 1); network.security.splice(eapIndex, 1);
} }
self.networksArray.push(network); self.networksArray.push(network);
@ -2333,6 +2356,9 @@ function WifiWorker() {
lock.get(SETTINGS_WIFI_DNS2, this); lock.get(SETTINGS_WIFI_DNS2, this);
lock.get(SETTINGS_WIFI_TETHERING_ENABLED, 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, this._wifiTetheringSettingsToRead = [SETTINGS_WIFI_SSID,
SETTINGS_WIFI_SECURITY_TYPE, SETTINGS_WIFI_SECURITY_TYPE,
SETTINGS_WIFI_SECURITY_PASSWORD, SETTINGS_WIFI_SECURITY_PASSWORD,
@ -2342,8 +2368,9 @@ function WifiWorker() {
SETTINGS_WIFI_DHCPSERVER_ENDIP, SETTINGS_WIFI_DHCPSERVER_ENDIP,
SETTINGS_WIFI_DNS1, SETTINGS_WIFI_DNS1,
SETTINGS_WIFI_DNS2, SETTINGS_WIFI_DNS2,
SETTINGS_WIFI_TETHERING_ENABLED]; SETTINGS_WIFI_TETHERING_ENABLED,
SETTINGS_USB_DHCPSERVER_STARTIP,
SETTINGS_USB_DHCPSERVER_ENDIP];
} }
function translateState(state) { function translateState(state) {
@ -2401,6 +2428,9 @@ WifiWorker.prototype = {
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP; this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP;
this.tetheringSettings[SETTINGS_WIFI_DNS1] = DEFAULT_DNS1; this.tetheringSettings[SETTINGS_WIFI_DNS1] = DEFAULT_DNS1;
this.tetheringSettings[SETTINGS_WIFI_DNS2] = DEFAULT_DNS2; 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. // Internal methods.
@ -2736,15 +2766,15 @@ WifiWorker.prototype = {
if (id === "__exposedProps__") { if (id === "__exposedProps__") {
continue; continue;
} }
if (id === "capabilities") { if (id === "security") {
result[id] = 0; result[id] = 0;
var capabilities = element[id]; var security = element[id];
for (let j = 0; j < capabilities.length; j++) { for (let j = 0; j < security.length; j++) {
if (capabilities[j] === "WPA-PSK") { if (security[j] === "WPA-PSK") {
result[id] |= Ci.nsIWifiScanResult.WPA_PSK; result[id] |= Ci.nsIWifiScanResult.WPA_PSK;
} else if (capabilities[j] === "WPA-EAP") { } else if (security[j] === "WPA-EAP") {
result[id] |= Ci.nsIWifiScanResult.WPA_EAP; result[id] |= Ci.nsIWifiScanResult.WPA_EAP;
} else if (capabilities[j] === "WEP") { } else if (security[j] === "WEP") {
result[id] |= Ci.nsIWifiScanResult.WEP; result[id] |= Ci.nsIWifiScanResult.WEP;
} else { } else {
result[id] = 0; result[id] = 0;
@ -2870,8 +2900,10 @@ WifiWorker.prototype = {
let securityId; let securityId;
let interfaceIp; let interfaceIp;
let prefix; let prefix;
let dhcpStartIp; let wifiDhcpStartIp;
let dhcpEndIp; let wifiDhcpEndIp;
let usbDhcpStartIp;
let usbDhcpEndIp;
let dns1; let dns1;
let dns2; let dns2;
@ -2880,8 +2912,10 @@ WifiWorker.prototype = {
securityId = this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD]; securityId = this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD];
interfaceIp = this.tetheringSettings[SETTINGS_WIFI_IP]; interfaceIp = this.tetheringSettings[SETTINGS_WIFI_IP];
prefix = this.tetheringSettings[SETTINGS_WIFI_PREFIX]; prefix = this.tetheringSettings[SETTINGS_WIFI_PREFIX];
dhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP]; wifiDhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP];
dhcpEndIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP]; 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]; dns1 = this.tetheringSettings[SETTINGS_WIFI_DNS1];
dns2 = this.tetheringSettings[SETTINGS_WIFI_DNS2]; dns2 = this.tetheringSettings[SETTINGS_WIFI_DNS2];
@ -2903,7 +2937,8 @@ WifiWorker.prototype = {
} }
// Using the default values here until application supports these settings. // Using the default values here until application supports these settings.
if (interfaceIp == "" || prefix == "" || if (interfaceIp == "" || prefix == "" ||
dhcpStartIp == "" || dhcpEndIp == "") { wifiDhcpStartIp == "" || wifiDhcpEndIp == "" ||
usbDhcpStartIp == "" || usbDhcpEndIp == "") {
debug("Invalid subnet information."); debug("Invalid subnet information.");
return null; return null;
} }
@ -2914,8 +2949,10 @@ WifiWorker.prototype = {
key: securityId, key: securityId,
ip: interfaceIp, ip: interfaceIp,
prefix: prefix, prefix: prefix,
startIp: dhcpStartIp, wifiStartIp: wifiDhcpStartIp,
endIp: dhcpEndIp, wifiEndIp: wifiDhcpEndIp,
usbStartIp: usbDhcpStartIp,
usbEndIp: usbDhcpEndIp,
dns1: dns1, dns1: dns1,
dns2: dns2, dns2: dns2,
enable: enable, enable: enable,
@ -3068,7 +3105,7 @@ WifiWorker.prototype = {
self._sendMessage(message, false, "WPS PBC failed", msg); self._sendMessage(message, false, "WPS PBC failed", msg);
}); });
} else if (detail.method === "pin") { } else if (detail.method === "pin") {
WifiManager.wpsPin(detail.pin, function(pin) { WifiManager.wpsPin(detail, function(pin) {
if (pin) if (pin)
self._sendMessage(message, true, pin, msg); self._sendMessage(message, true, pin, msg);
else else
@ -3262,6 +3299,8 @@ WifiWorker.prototype = {
case SETTINGS_WIFI_DHCPSERVER_ENDIP: case SETTINGS_WIFI_DHCPSERVER_ENDIP:
case SETTINGS_WIFI_DNS1: case SETTINGS_WIFI_DNS1:
case SETTINGS_WIFI_DNS2: case SETTINGS_WIFI_DNS2:
case SETTINGS_USB_DHCPSERVER_STARTIP:
case SETTINGS_USB_DHCPSERVER_ENDIP:
if (aResult !== null) { if (aResult !== null) {
this.tetheringSettings[aName] = aResult; this.tetheringSettings[aName] = aResult;
} }

Просмотреть файл

@ -113,6 +113,8 @@ interface nsIDOMWifiManager : nsISupports
* - cancel: Request to cancel WPS in progress. * - cancel: Request to cancel WPS in progress.
* If method field is 'pin', 'pin' field can exist and has * If method field is 'pin', 'pin' field can exist and has
* a PIN number. * a PIN number.
* If method field is 'pin', 'bssid' field can exist and has
* a opposite BSSID.
* onsuccess: We have successfully started/canceled wps. * onsuccess: We have successfully started/canceled wps.
* onerror: We have failed to start/cancel wps. * onerror: We have failed to start/cancel wps.
*/ */