diff options
Diffstat (limited to 'dom/wifi/WifiP2pManager.jsm')
-rw-r--r-- | dom/wifi/WifiP2pManager.jsm | 1649 |
1 files changed, 0 insertions, 1649 deletions
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; |