зеркало из https://github.com/mozilla/pjs.git
Bug 712629 - Make Wifi work under gonk. There are large parts of this that are still sketches, but this gets us limping along. r=gal
--HG-- extra : rebase_source : 7fb2de1e4eb22250dbe0958a46e551012ff54ac3
This commit is contained in:
Родитель
4e7545ab62
Коммит
3d440a920c
|
@ -147,6 +147,7 @@
|
|||
@BINPATH@/components/dom_base.xpt
|
||||
#ifdef MOZ_B2G_RIL
|
||||
@BINPATH@/components/dom_telephony.xpt
|
||||
@BINPATH@/components/dom_wifi.xpt
|
||||
@BINPATH@/components/dom_system_b2g.xpt
|
||||
#endif
|
||||
@BINPATH@/components/dom_battery.xpt
|
||||
|
@ -396,6 +397,8 @@
|
|||
@BINPATH@/components/nsTelephonyWorker.js
|
||||
@BINPATH@/components/Telephony.manifest
|
||||
@BINPATH@/components/Telephony.js
|
||||
@BINPATH@/components/nsWifiWorker.js
|
||||
@BINPATH@/components/nsWifiWorker.manifest
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
@BINPATH@/components/libalerts_s.dylib
|
||||
|
|
|
@ -138,6 +138,7 @@
|
|||
@BINPATH@/components/dom_base.xpt
|
||||
#ifdef MOZ_B2G_RIL
|
||||
@BINPATH@/components/dom_telephony.xpt
|
||||
@BINPATH@/components/dom_wifi.xpt
|
||||
@BINPATH@/components/dom_system_b2g.xpt
|
||||
#endif
|
||||
@BINPATH@/components/dom_battery.xpt
|
||||
|
@ -366,6 +367,8 @@
|
|||
@BINPATH@/components/nsTelephonyWorker.js
|
||||
@BINPATH@/components/Telephony.manifest
|
||||
@BINPATH@/components/Telephony.js
|
||||
@BINPATH@/components/nsWifiWorker.js
|
||||
@BINPATH@/components/nsWifiWorker.manifest
|
||||
#endif
|
||||
@BINPATH@/components/BrowserProfileMigrators.manifest
|
||||
@BINPATH@/components/ChromeProfileMigrator.js
|
||||
|
|
|
@ -70,6 +70,7 @@ components/pluginGlue.js
|
|||
components/sidebar.xpt
|
||||
#ifdef MOZ_B2G_RIL
|
||||
components/dom_telephony.xpt
|
||||
components/dom_wifi.xpt
|
||||
components/dom_system_b2g.xpt
|
||||
#endif
|
||||
components/uconvd.dll
|
||||
|
@ -922,6 +923,8 @@ xpicleanup@BIN_SUFFIX@
|
|||
components/nsTelephonyWorker.js
|
||||
components/Telephony.manifest
|
||||
components/Telephony.js
|
||||
components/nsWifiWorker.js
|
||||
components/nsWifiWorker.manifest
|
||||
#endif
|
||||
components/txEXSLTRegExFunctions.js
|
||||
components/Weave.js
|
||||
|
@ -1143,6 +1146,7 @@ xpicleanup@BIN_SUFFIX@
|
|||
components/dom_base.xpt
|
||||
#ifdef MOZ_B2G_RIL
|
||||
components/dom_telephony.xpt
|
||||
components/dom_wifi.xpt
|
||||
components/dom_system_b2g.xpt
|
||||
#endif
|
||||
components/dom_canvas.xpt
|
||||
|
|
|
@ -84,7 +84,10 @@ DIRS += \
|
|||
$(NULL)
|
||||
|
||||
ifdef MOZ_B2G_RIL #{
|
||||
DIRS += telephony
|
||||
DIRS += \
|
||||
telephony \
|
||||
wifi \
|
||||
$(NULL)
|
||||
endif #}
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
|
|
|
@ -66,6 +66,7 @@ XPIDLSRCS = \
|
|||
LOCAL_INCLUDES = \
|
||||
-I$(topsrcdir)/dom/base \
|
||||
-I$(topsrcdir)/dom/telephony \
|
||||
-I$(topsrcdir)/dom/wifi \
|
||||
-I$(topsrcdir)/content/events/src \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -45,7 +45,11 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "mozilla/dom/workers/Workers.h"
|
||||
#include "jstypedarray.h"
|
||||
|
||||
#include "nsTelephonyWorker.h"
|
||||
#include "nsITelephone.h"
|
||||
#include "nsWifiWorker.h"
|
||||
#include "nsIWifi.h"
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
|
@ -60,6 +64,7 @@ USING_WORKERS_NAMESPACE
|
|||
using namespace mozilla::ipc;
|
||||
|
||||
static NS_DEFINE_CID(kTelephonyWorkerCID, NS_TELEPHONYWORKER_CID);
|
||||
static NS_DEFINE_CID(kWifiWorkerCID, NS_WIFIWORKER_CID);
|
||||
|
||||
// Topic we listen to for shutdown.
|
||||
#define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change"
|
||||
|
@ -225,16 +230,6 @@ RadioManager::Init()
|
|||
nsresult rv = obs->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The telephony worker component is a hack that gives us a global object for
|
||||
// our own functions and makes creating the worker possible.
|
||||
nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kTelephonyWorkerCID));
|
||||
NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
|
||||
|
||||
jsval workerval;
|
||||
rv = worker->GetWorker(&workerval);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(!JSVAL_IS_PRIMITIVE(workerval), "bad worker value");
|
||||
|
||||
JSContext *cx;
|
||||
rv = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -243,30 +238,11 @@ RadioManager::Init()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSObject *workerobj = JSVAL_TO_OBJECT(workerval);
|
||||
rv = InitTelephone(cx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, workerobj)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
WorkerCrossThreadDispatcher *wctd = GetWorkerCrossThreadDispatcher(cx, workerval);
|
||||
if (!wctd) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
|
||||
if (!wctd->PostTask(connection)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Now that we're set up, connect ourselves to the RIL thread.
|
||||
mozilla::RefPtr<RILReceiver> receiver = new RILReceiver(wctd);
|
||||
StartRil(receiver);
|
||||
|
||||
mTelephone = do_QueryInterface(worker);
|
||||
NS_ENSURE_TRUE(mTelephone, NS_ERROR_FAILURE);
|
||||
rv = InitWifi(cx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -278,6 +254,7 @@ RadioManager::Shutdown()
|
|||
|
||||
StopRil();
|
||||
mTelephone = nsnull;
|
||||
mWifi = nsnull;
|
||||
|
||||
mShutdown = true;
|
||||
}
|
||||
|
@ -316,6 +293,59 @@ RadioManager::GetTelephone()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
RadioManager::InitTelephone(JSContext *cx)
|
||||
{
|
||||
// The telephony worker component is a hack that gives us a global object for
|
||||
// our own functions and makes creating the worker possible.
|
||||
nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kTelephonyWorkerCID));
|
||||
NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
|
||||
|
||||
jsval workerval;
|
||||
nsresult rv = worker->GetWorker(&workerval);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(!JSVAL_IS_PRIMITIVE(workerval), "bad worker value");
|
||||
|
||||
JSObject *workerobj = JSVAL_TO_OBJECT(workerval);
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, workerobj)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
WorkerCrossThreadDispatcher *wctd = GetWorkerCrossThreadDispatcher(cx, workerval);
|
||||
if (!wctd) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
|
||||
if (!wctd->PostTask(connection)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Now that we're set up, connect ourselves to the RIL thread.
|
||||
mozilla::RefPtr<RILReceiver> receiver = new RILReceiver(wctd);
|
||||
StartRil(receiver);
|
||||
|
||||
mTelephone = do_QueryInterface(worker);
|
||||
NS_ENSURE_TRUE(mTelephone, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
RadioManager::InitWifi(JSContext *cx)
|
||||
{
|
||||
nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kWifiWorkerCID));
|
||||
NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
|
||||
|
||||
mWifi = do_QueryInterface(worker);
|
||||
NS_ENSURE_TRUE(mWifi, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(RadioManager, nsIObserver)
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
|
||||
#include "nsIObserver.h"
|
||||
#include "mozilla/ipc/Ril.h"
|
||||
#include "nsITelephone.h"
|
||||
|
||||
#define TELEPHONYRADIO_CONTRACTID "@mozilla.org/telephony/radio;1"
|
||||
#define TELEPHONYRADIOINTERFACE_CONTRACTID "@mozilla.org/telephony/radio-interface;1"
|
||||
|
@ -70,6 +69,8 @@
|
|||
|
||||
|
||||
class nsIXPConnectJSObjectHolder;
|
||||
class nsITelephone;
|
||||
class nsIWifi;
|
||||
|
||||
BEGIN_TELEPHONY_NAMESPACE
|
||||
|
||||
|
@ -92,7 +93,11 @@ protected:
|
|||
RadioManager();
|
||||
~RadioManager();
|
||||
|
||||
nsresult InitTelephone(JSContext *cx);
|
||||
nsresult InitWifi(JSContext *cx);
|
||||
|
||||
nsCOMPtr<nsITelephone> mTelephone;
|
||||
nsCOMPtr<nsIWifi> mWifi;
|
||||
bool mShutdown;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Telephony.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Ben Turner <bent.mozilla@gmail.com> (Original Author)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = dom
|
||||
LIBRARY_NAME = domwifi_s
|
||||
XPIDL_MODULE = dom_wifi
|
||||
LIBXUL_LIBRARY = 1
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/dom/dom-config.mk
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIWifi.idl \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_COMPONENTS = \
|
||||
nsWifiWorker.js \
|
||||
nsWifiWorker.manifest \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_JS_MODULES = \
|
||||
libcutils.js \
|
||||
libhardware_legacy.js \
|
||||
libnetutils.js \
|
||||
network_worker.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
"use strict";
|
||||
|
||||
let libcutils = (function () {
|
||||
let library = ctypes.open("/system/lib/libcutils.so");
|
||||
|
||||
return {
|
||||
property_get: library.declare("property_get", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.char.ptr),
|
||||
property_set: library.declare("property_set", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr)
|
||||
};
|
||||
})();
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
"use strict";
|
||||
|
||||
let libhardware_legacy = (function () {
|
||||
let library = ctypes.open("/system/lib/libhardware_legacy.so");
|
||||
|
||||
return {
|
||||
// Load wifi driver, 0 on success, < 0 on failure.
|
||||
load_driver: library.declare("wifi_load_driver", ctypes.default_abi, ctypes.int),
|
||||
|
||||
// Unload wifi driver, 0 on success, < 0 on failure.
|
||||
unload_driver: library.declare("wifi_unload_driver", ctypes.default_abi, ctypes.int),
|
||||
|
||||
// Start supplicant, 0 on success, < 0 on failure.
|
||||
start_supplicant: library.declare("wifi_start_supplicant", ctypes.default_abi, ctypes.int),
|
||||
|
||||
// Stop supplicant, 0 on success, < 0 on failure.
|
||||
stop_supplicant: library.declare("wifi_stop_supplicant", ctypes.default_abi, ctypes.int),
|
||||
|
||||
// Open a connection to the supplicant, 0 on success, < 0 on failure.
|
||||
connect_to_supplicant: library.declare("wifi_connect_to_supplicant", ctypes.default_abi, ctypes.int),
|
||||
|
||||
// Close connection to connection to the supplicant, 0 on success, < 0 on failure.
|
||||
close_supplicant_connection: library.declare("wifi_close_supplicant_connection", ctypes.default_abi, ctypes.int),
|
||||
|
||||
// Block until a wifi event is returned, buf is the buffer, len is the max length of the buffer.
|
||||
// Return value is number of bytes in buffer, or 0 if no event (no connection for instance), and < 0 on failure.
|
||||
wait_for_event: library.declare("wifi_wait_for_event", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.size_t),
|
||||
|
||||
// Issue a command to the wifi driver. command is the command string, reply will hold the reply, reply_len contains
|
||||
// the maximum reply length initially and is updated with the actual length. 0 is returned on success, < 0 on failure.
|
||||
command: library.declare("wifi_command", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.size_t.ptr),
|
||||
};
|
||||
})();
|
|
@ -0,0 +1,30 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
"use strict";
|
||||
|
||||
let libnetutils = (function () {
|
||||
let library = ctypes.open("/system/lib/libnetutils.so");
|
||||
|
||||
return {
|
||||
ifc_enable: library.declare("ifc_enable", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
|
||||
ifc_disable: library.declare("ifc_disable", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
|
||||
ifc_add_host_route: library.declare("ifc_add_host_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.int),
|
||||
ifc_remove_host_routes: library.declare("ifc_remove_host_routes", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
|
||||
ifc_set_default_route: library.declare("ifc_set_default_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.int),
|
||||
ifc_get_default_route: library.declare("ifc_get_default_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
|
||||
ifc_remove_default_route: library.declare("ifc_remove_default_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
|
||||
ifc_reset_connections: library.declare("ifc_reset_connections", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
|
||||
ifc_configure: library.declare("ifc_configure", ctypes.default_abi, ctypes.int, ctypes.char.ptr,
|
||||
ctypes.int, ctypes.int, ctypes.int, ctypes.int, ctypes.int),
|
||||
dhcp_do_request: library.declare("dhcp_do_request", ctypes.default_abi, ctypes.int,
|
||||
ctypes.char.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr,
|
||||
ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr),
|
||||
dhcp_stop: library.declare("dhcp_stop", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
|
||||
dhcp_release_lease: library.declare("dhcp_release_lease", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
|
||||
dhcp_get_errmsg: library.declare("dhcp_get_errmsg", ctypes.default_abi, ctypes.char.ptr),
|
||||
dhcp_do_request_renew: library.declare("dhcp_do_request_renew", ctypes.default_abi, ctypes.int,
|
||||
ctypes.char.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr,
|
||||
ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr)
|
||||
};
|
||||
})();
|
|
@ -0,0 +1,94 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
"use strict";
|
||||
|
||||
importScripts("libhardware_legacy.js", "libnetutils.js", "libcutils.js");
|
||||
|
||||
var cbuf = ctypes.char.array(4096)();
|
||||
var hwaddr = ctypes.uint8_t.array(6)();
|
||||
var len = ctypes.size_t();
|
||||
var ints = ctypes.int.array(8)();
|
||||
|
||||
self.onmessage = function(e) {
|
||||
var data = e.data;
|
||||
var id = data.id;
|
||||
var cmd = data.cmd;
|
||||
|
||||
switch (cmd) {
|
||||
case "command":
|
||||
len.value = 4096;
|
||||
var ret = libhardware_legacy.command(data.request, cbuf, len.address());
|
||||
dump("For command " + data.request + " ret is " + ret + "\n");
|
||||
var reply = "";
|
||||
if (!ret) {
|
||||
var reply_len = len.value;
|
||||
var str = cbuf.readString();
|
||||
if (str[reply_len-1] == "\n")
|
||||
--reply_len;
|
||||
reply = str.substr(0, reply_len);
|
||||
}
|
||||
postMessage({ id: id, status: ret, reply: reply });
|
||||
break;
|
||||
case "wait_for_event":
|
||||
var ret = libhardware_legacy.wait_for_event(cbuf, 4096);
|
||||
var event = cbuf.readString().substr(0, ret.value);
|
||||
postMessage({ id: id, event: event });
|
||||
break;
|
||||
case "ifc_enable":
|
||||
case "ifc_disable":
|
||||
case "ifc_remove_host_routes":
|
||||
case "ifc_remove_default_route":
|
||||
case "ifc_reset_connections":
|
||||
case "dhcp_stop":
|
||||
case "dhcp_release_lease":
|
||||
var ret = libnetutils[cmd](data.ifname);
|
||||
postMessage({ id: id, status: ret });
|
||||
break;
|
||||
case "ifc_get_default_route":
|
||||
var route = libnetutils.ifc_get_default_route(data.ifname);
|
||||
postMessage({ id: id, route: route });
|
||||
break;
|
||||
case "ifc_add_host_route":
|
||||
case "ifc_set_default_route":
|
||||
var ret = libnetutils[cmd](data.ifname, data.route);
|
||||
postMessage({ id: id, status: ret });
|
||||
break;
|
||||
case "ifc_configure":
|
||||
dump("WIFI: data: " + uneval(data) + "\n");
|
||||
var ret = libnetutils.ifc_configure(data.ifname, data.ipaddr, data.mask, data.gateway, data.dns1, data.dns2);
|
||||
postMessage({ id: id, status: ret });
|
||||
break;
|
||||
case "dhcp_get_errmsg":
|
||||
var error = libnetutils.get_dhcp_get_errmsg();
|
||||
postMessage({ id: id, error: error.readString() });
|
||||
break;
|
||||
case "dhcp_do_request":
|
||||
case "dhcp_do_request_renew":
|
||||
var ret = libnetutils[cmd](data.ifname,
|
||||
ints.addressOfElement(0),
|
||||
ints.addressOfElement(1),
|
||||
ints.addressOfElement(2),
|
||||
ints.addressOfElement(3),
|
||||
ints.addressOfElement(4),
|
||||
ints.addressOfElement(5),
|
||||
ints.addressOfElement(6));
|
||||
postMessage({ id: id, status: ret, ipaddr: ints[0], gateway: ints[1], mask: ints[2],
|
||||
dns1: ints[3], dns2: ints[4], server: ints[5], lease: ints[6]});
|
||||
break;
|
||||
case "property_get":
|
||||
var ret = libcutils.property_get(data.key, cbuf, data.defaultValue);
|
||||
postMessage({ id: id, status: ret, value: cbuf.readString() });
|
||||
break;
|
||||
case "property_set":
|
||||
var ret = libcutils.property_set(data.key, data.value);
|
||||
postMessage({ id: id, status: ret });
|
||||
break;
|
||||
default:
|
||||
var f = libhardware_legacy[cmd] || libnetutils[cmd];
|
||||
var ret = f();
|
||||
dump("WIFI: " + cmd + " returned: " + ret);
|
||||
postMessage({ id: id, status: ret });
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Telephony.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Philipp von Weitershausen <philipp@weitershausen.de>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(9DCE05BF-659C-4427-A050-0EAC3BB6C1C0)]
|
||||
interface nsIWifi : nsISupports {
|
||||
};
|
|
@ -0,0 +1,40 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Telephony.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Turner <bent.mozilla@gmail.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#define NS_WIFIWORKER_CID \
|
||||
{ 0xA14E8977, 0xD259, 0x433A, \
|
||||
{ 0xA8, 0x8D, 0x58, 0xDD, 0x44, 0x65, 0x7E, 0x5B } }
|
|
@ -0,0 +1,853 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Telephony.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andreas Gal <gal@mozilla.com>
|
||||
* Blake Kaplan <mrbkap@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const DEBUG = true; // set to false to suppress 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/network_worker.js";
|
||||
|
||||
var WifiManager = (function() {
|
||||
var controlWorker = new ChromeWorker(WIFIWORKER_WORKER);
|
||||
var eventWorker = new ChromeWorker(WIFIWORKER_WORKER);
|
||||
|
||||
// Callbacks to invoke when a reply arrives from the controlWorker.
|
||||
var controlCallbacks = Object.create(null);
|
||||
var idgen = 0;
|
||||
|
||||
function controlMessage(obj, callback) {
|
||||
var id = idgen++;
|
||||
obj.id = id;
|
||||
if (callback)
|
||||
controlCallbacks[id] = callback;
|
||||
controlWorker.postMessage(obj);
|
||||
}
|
||||
|
||||
function onerror(e) {
|
||||
// It is very important to call preventDefault on the event here.
|
||||
// If an exception is thrown on the worker, it bubbles out to the
|
||||
// component that created it. If that component doesn't have an
|
||||
// onerror handler, the worker will try to call the error reporter
|
||||
// on the context it was created on. However, That doesn't work
|
||||
// for component contexts and can result in crashes. This onerror
|
||||
// handler has to make sure that it calls preventDefault on the
|
||||
// incoming event.
|
||||
e.preventDefault();
|
||||
|
||||
var worker = (this === controlWorker) ? "control" : "event";
|
||||
|
||||
debug("Got an error from the " + worker + " worker: " + e.filename +
|
||||
":" + e.lineno + ": " + e.message + "\n");
|
||||
}
|
||||
|
||||
controlWorker.onerror = onerror;
|
||||
eventWorker.onerror = onerror;
|
||||
|
||||
controlWorker.onmessage = function(e) {
|
||||
var data = e.data;
|
||||
var id = data.id;
|
||||
var callback = controlCallbacks[id];
|
||||
if (callback) {
|
||||
callback(data);
|
||||
delete controlCallbacks[id];
|
||||
}
|
||||
};
|
||||
|
||||
// Polling the status worker
|
||||
var recvErrors = 0;
|
||||
eventWorker.onmessage = function(e) {
|
||||
// process the event and tell the event worker to listen for more events
|
||||
if (handleEvent(e.data.event))
|
||||
waitForEvent();
|
||||
};
|
||||
|
||||
function waitForEvent() {
|
||||
eventWorker.postMessage({ cmd: "wait_for_event" });
|
||||
}
|
||||
|
||||
// Commands to the control worker
|
||||
|
||||
function voidControlMessage(cmd, callback) {
|
||||
controlMessage({ cmd: cmd }, function (data) {
|
||||
callback(data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function loadDriver(callback) {
|
||||
voidControlMessage("load_driver", callback);
|
||||
}
|
||||
|
||||
function unloadDriver(callback) {
|
||||
voidControlMessage("unload_driver", callback);
|
||||
}
|
||||
|
||||
function startSupplicant(callback) {
|
||||
voidControlMessage("start_supplicant", callback);
|
||||
}
|
||||
|
||||
function stopSupplicant(callback) {
|
||||
voidControlMessage("stop_supplicant", callback);
|
||||
}
|
||||
|
||||
function connectToSupplicant(callback) {
|
||||
voidControlMessage("connect_to_supplicant", callback);
|
||||
}
|
||||
|
||||
function closeSupplicantConnection(callback) {
|
||||
voidControlMessage("close_supplicant_connection", callback);
|
||||
}
|
||||
|
||||
function doCommand(request, callback) {
|
||||
controlMessage({ cmd: "command", request: request }, 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 listNetworksCommand(callback) {
|
||||
doStringCommand("LIST_NETWORKS", callback);
|
||||
}
|
||||
|
||||
function addNetworkCommand(callback) {
|
||||
doIntCommand("ADD_NETWORK", callback);
|
||||
}
|
||||
|
||||
function setNetworkVariableCommand(netId, name, value, callback) {
|
||||
doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value, "OK", callback);
|
||||
}
|
||||
|
||||
function getNetworkVariableCommand(netId, name, callback) {
|
||||
doStringCommand("GET_NETWORK " + netId + " " + name, callback);
|
||||
}
|
||||
|
||||
function removeNetworkCommand(netId, callback) {
|
||||
doBooleanCommand("REMOVE_NETWORK " + netId, callback);
|
||||
}
|
||||
|
||||
function enableNetworkCommand(netId, disableOthers, callback) {
|
||||
doBooleanCommand((disableOthers ? "SELECT_NETWORK " : "ENABLE_NETWORK ") + netId, "OK", callback);
|
||||
}
|
||||
|
||||
function disableNetworkCommand(netId, callback) {
|
||||
doBooleanCommand("DISABLE_NETWORK " + netId, "OK", callback);
|
||||
}
|
||||
|
||||
function statusCommand(callback) {
|
||||
doStringCommand("STATUS", callback);
|
||||
}
|
||||
|
||||
function pingCommand(callback) {
|
||||
doBooleanCommand("PING", "PONG", callback);
|
||||
}
|
||||
|
||||
function scanResultsCommand(callback) {
|
||||
doStringCommand("SCAN_RESULTS", callback);
|
||||
}
|
||||
|
||||
function disconnectCommand(callback) {
|
||||
doBooleanCommand("DISCONNECT", "OK", callback);
|
||||
}
|
||||
|
||||
function reconnectCommand(callback) {
|
||||
doBooleanCommand("RECONNECT", "OK", callback);
|
||||
}
|
||||
|
||||
function reassociateCommand(callback) {
|
||||
doBooleanCommand("REASSOCIATE", "OK", callback);
|
||||
}
|
||||
|
||||
var scanModeActive = false;
|
||||
|
||||
function doSetScanModeCommand(setActive, callback) {
|
||||
doBooleanCommand(setActive ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE", "OK", callback);
|
||||
}
|
||||
|
||||
function scanCommand(forceActive, callback) {
|
||||
if (forceActive && !scanModeActive) {
|
||||
doSetScanModeCommand(true, function(ok) {
|
||||
ok && doBooleanCommand("SCAN", "OK", function(ok) {
|
||||
ok && doSetScanModeCommand(false, callback);
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
doBooleanCommand("SCAN", "OK", callback);
|
||||
}
|
||||
|
||||
function setScanModeCommand(setActive, callback) {
|
||||
sScanModeActive = setActive;
|
||||
doSetScanModeCommand(setActive, callback);
|
||||
}
|
||||
|
||||
function startDriverCommand(callback) {
|
||||
doBooleanCommand("DRIVER START", "OK");
|
||||
}
|
||||
|
||||
function stopDriverCommand(callback) {
|
||||
doBooleanCommand("DRIVER STOP", "OK");
|
||||
}
|
||||
|
||||
function startPacketFiltering(callback) {
|
||||
doBooleanCommand("DRIVER RXFILTER-ADD 0", "OK", function(ok) {
|
||||
ok && doBooleanCommand("DRIVER RXFILTER-ADD 1", "OK", function(ok) {
|
||||
ok && doBooleanCommand("DRIVER RXFILTER-ADD 3", "OK", function(ok) {
|
||||
ok && doBooleanCommand("DRIVER RXFILTER-START", "OK", callback)
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function stopPacketFiltering(callback) {
|
||||
doBooleanCommand("DRIVER RXFILTER-STOP", "OK", function(ok) {
|
||||
ok && doBooleanCommand("DRIVER RXFILTER-REMOVE 3", "OK", function(ok) {
|
||||
ok && doBooleanCommand("DRIVER RXFILTER-REMOVE 1", "OK", function(ok) {
|
||||
ok && doBooleanCommand("DRIVER RXFILTER-REMOVE 0", "OK", callback)
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function doGetRssiCommand(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);
|
||||
});
|
||||
}
|
||||
|
||||
function getRssiCommand(callback) {
|
||||
doGetRssiCommand("DRIVER RSSI", callback);
|
||||
}
|
||||
|
||||
function getRssiApproxCommand(callback) {
|
||||
doGetRssiCommand("DRIVER RSSI-APPROX", callback);
|
||||
}
|
||||
|
||||
function getLinkSpeedCommand(callback) {
|
||||
doStringCommand("DRIVER LINKSPEED", function(reply) {
|
||||
if (reply)
|
||||
reply = reply.split()[1] | 0; // Format: LinkSpeed XX
|
||||
callback(reply);
|
||||
});
|
||||
}
|
||||
|
||||
function getMacAddressCommand(callback) {
|
||||
doStringCommand("DRIVER MACADDR", function(reply) {
|
||||
if (reply)
|
||||
reply = reply.split(" ")[2]; // Format: Macaddr = XX.XX.XX.XX.XX.XX
|
||||
callback(reply);
|
||||
});
|
||||
}
|
||||
|
||||
function setPowerModeCommand(mode, callback) {
|
||||
doBooleanCommand("DRIVER POWERMODE " + mode, "OK", callback);
|
||||
}
|
||||
|
||||
function getPowerModeCommand(callback) {
|
||||
doStringCommand("DRIVER GETPOWER", function(reply) {
|
||||
if (reply)
|
||||
reply = (reply.split()[2]|0); // Format: powermode = XX
|
||||
callback(reply);
|
||||
});
|
||||
}
|
||||
|
||||
function setNumAllowedChannelsCommand(numChannels, callback) {
|
||||
doBooleanCommand("DRIVER SCAN-CHANNELS " + numChannels, "OK", callback);
|
||||
}
|
||||
|
||||
function getNumAllowedChannelsCommand(callback) {
|
||||
doStringCommand("DRIVER SCAN-CHANNELS", function(reply) {
|
||||
if (reply)
|
||||
reply = (reply.split()[2]|0); // Format: Scan-Channels = X
|
||||
callback(reply);
|
||||
});
|
||||
}
|
||||
|
||||
function setBluetoothCoexistenceModeCommand(mode, callback) {
|
||||
doBooleanCommand("DRIVER BTCOEXMODE " + mode, "OK", callback);
|
||||
}
|
||||
|
||||
function setBluetoothCoexistenceScanModeCommand(mode, callback) {
|
||||
doBooleanCommand("DRIVER BTCOEXSCAN-" + (mode ? "START" : "STOP"), "OK", callback);
|
||||
}
|
||||
|
||||
function saveConfigCommand(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);
|
||||
});
|
||||
}
|
||||
|
||||
function reloadConfigCommand(callback) {
|
||||
doBooleanCommand("RECONFIGURE", "OK", callback);
|
||||
}
|
||||
|
||||
function setScanResultHandlingCommand(mode, callback) {
|
||||
doBooleanCommand("AP_SCAN " + mode, "OK", callback);
|
||||
}
|
||||
|
||||
function addToBlacklistCommand(bssid, callback) {
|
||||
doBooleanCommand("BLACKLIST " + bssid, "OK", callback);
|
||||
}
|
||||
|
||||
function clearBlacklistCommand(callback) {
|
||||
doBooleanCommand("BLACKLIST clear", "OK", callback);
|
||||
}
|
||||
|
||||
function setSuspendOptimizationsCommand(enabled, callback) {
|
||||
doBooleanCommand("DRIVER SETSUSPENDOPT " + (enabled ? 0 : 1), "OK", callback);
|
||||
}
|
||||
|
||||
function getProperty(key, defaultValue, callback) {
|
||||
controlMessage({ cmd: "property_get", key: key, defaultValue: defaultValue }, function(data) {
|
||||
callback(data.status < 0 ? null : data.value);
|
||||
});
|
||||
}
|
||||
|
||||
function setProperty(key, value, callback) {
|
||||
controlMessage({ cmd: "property_set", key: key, value: value }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function enableInterface(ifname, callback) {
|
||||
controlMessage({ cmd: "ifc_enable", ifname: ifname }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function disableInterface(ifname, callback) {
|
||||
controlMessage({ cmd: "ifc_disable", ifname: ifname }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function addHostRoute(ifname, route, callback) {
|
||||
controlMessage({ cmd: "ifc_add_host_route", ifname: ifname, route: route }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function removeHostRoutes(ifname, callback) {
|
||||
controlMessage({ cmd: "ifc_remove_host_routes", ifname: ifname }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function setDefaultRoute(ifname, route, callback) {
|
||||
controlMessage({ cmd: "ifc_set_default_route", ifname: ifname, route: route }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function getDefaultRoute(ifname, callback) {
|
||||
controlMessage({ cmd: "ifc_get_default_route", ifname: ifname }, function(data) {
|
||||
callback(!data.route);
|
||||
});
|
||||
}
|
||||
|
||||
function removeDefaultRoute(ifname, callback) {
|
||||
controlMessage({ cmd: "ifc_remove_default_route", ifname: ifname }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function resetConnections(ifname, callback) {
|
||||
controlMessage({ cmd: "ifc_reset_connections", ifname: ifname }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function runDhcp(ifname, callback) {
|
||||
controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
|
||||
callback(data.status ? null : data);
|
||||
});
|
||||
}
|
||||
|
||||
function stopDhcp(ifname, callback) {
|
||||
controlMessage({ cmd: "dhcp_stop", ifname: ifname }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function releaseDhcpLease(ifname, callback) {
|
||||
controlMessage({ cmd: "dhcp_release_lease", ifname: ifname }, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function getDhcpError(callback) {
|
||||
controlMessage({ cmd: "dhcp_get_errmsg" }, function(data) {
|
||||
callback(data.error);
|
||||
});
|
||||
}
|
||||
|
||||
function configureInterface(ifname, ipaddr, mask, gateway, dns1, dns2, callback) {
|
||||
controlMessage({ cmd: "ifc_configure", ifname: ifname,
|
||||
ipaddr: ipaddr, mask: mask, gateway: gateway,
|
||||
dns1: dns1, dns2: dns2}, function(data) {
|
||||
callback(!data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function runDhcpRenew(ifname, callback) {
|
||||
controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
|
||||
callback(data.status ? null : data);
|
||||
});
|
||||
}
|
||||
|
||||
var manager = {};
|
||||
|
||||
function notify(eventName, eventObject) {
|
||||
var handler = manager["on" + eventName];
|
||||
if (handler) {
|
||||
if (!eventObject)
|
||||
eventObject = ({});
|
||||
handler.call(eventObject);
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
waitForEvent();
|
||||
notify("supplicantconnection");
|
||||
return;
|
||||
}
|
||||
if (connectTries++ < 3) {
|
||||
// try again in 5 seconds
|
||||
if (!retryTimer)
|
||||
retryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
|
||||
retryTimer.initWithCallback(function(timer) {
|
||||
connectToSupplicant(connectCallback);
|
||||
}, 5000, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
return;
|
||||
}
|
||||
|
||||
retryTimer = null;
|
||||
notify("supplicantlost");
|
||||
}
|
||||
|
||||
manager.start = function() {
|
||||
connectToSupplicant(connectCallback);
|
||||
}
|
||||
|
||||
var supplicantStatesMap = ["DISCONNECTED", "INACTIVE", "SCANNING", "ASSOCIATING",
|
||||
"FOUR_WAY_HANDSHAKE", "GROUP_HANDSHAKE", "COMPLETED",
|
||||
"DORMANT", "UNINITIALIZED"];
|
||||
var driverEventMap = { STOPPED: "driverstopped", STARTED: "driverstarted", HANGED: "driverhung" };
|
||||
|
||||
// handle events sent to us by the event worker
|
||||
function handleEvent(event) {
|
||||
debug("Event coming in: " + event);
|
||||
if (event.indexOf("CTRL-EVENT-") !== 0) {
|
||||
debug("Got weird event, possibly not doing anything.");
|
||||
if (event.indexOf("WPA:") == 0 &&
|
||||
event.indexOf("pre-shared key may be incorrect") != -1) {
|
||||
notify("passwordmaybeincorrect");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var eventData = event.substr(0, event.indexOf(" ") + 1);
|
||||
if (eventData.indexOf("CTRL-EVENT-STATE-CHANGE") === 0) {
|
||||
// Parse the event data
|
||||
var fields = {};
|
||||
var tokens = eventData.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];
|
||||
notify("statechange", fields);
|
||||
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) {
|
||||
// If the monitor socket is closed, we have already stopped the
|
||||
// supplicant and we can stop waiting for more events and
|
||||
// simply exit here (we don't have to notify).
|
||||
if (eventData.indexOf("connection closed") !== -1)
|
||||
return false;
|
||||
|
||||
// As long we haven't seen too many recv errors yet, we
|
||||
// will keep going for a bit longer
|
||||
if (eventData.indexOf("recv error") !== -1 && ++recvErrors < 10)
|
||||
return true;
|
||||
|
||||
notify("supplicantlost");
|
||||
return false;
|
||||
}
|
||||
if (eventData.indexOf("CTRL-EVENT-DISCONNECTED") === 0) {
|
||||
notify("statechange", { state: "DISCONNECTED" });
|
||||
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 = eventData.split(" ")[4];
|
||||
var id = eventData.substr(eventData.indexOf("id=")).split(" ")[0];
|
||||
notify("statechange", { state: "CONNECTED", BSSID: bssid, id: id });
|
||||
return true;
|
||||
}
|
||||
if (eventData.indexOf("CTRL-EVENT-SCAN-RESULTS") === 0) {
|
||||
debug("Notifying of scn results available");
|
||||
notify("scanresultsavailable");
|
||||
return true;
|
||||
}
|
||||
// unknown event
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initial state
|
||||
var airplaneMode = false;
|
||||
|
||||
// Public interface of the wifi service
|
||||
manager.setWifiEnabled = function(enable, callback) {
|
||||
var targetState = enable ? "ENABLED" : "DISABLED";
|
||||
if (enable == targetState)
|
||||
return true;
|
||||
if (enable && airplaneMode)
|
||||
return false;
|
||||
if (enable) {
|
||||
loadDriver(function (ok) {
|
||||
(ok === 0) ? startSupplicant(callback) : callback(-1);
|
||||
});
|
||||
} else {
|
||||
stopSupplicant(function (ok) {
|
||||
(ok === 0) ? unloadDriver(callback) : callback(-1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
manager.disconnect = disconnectCommand;
|
||||
manager.reconnect = reconnectCommand;
|
||||
manager.reassociate = reassociateCommand;
|
||||
|
||||
var networkConfigurationFields = ["ssid", "bssid", "psk", "wep_key0", "wep_key1", "wep_key2", "wep_key3",
|
||||
"wep_tx_keyidx", "priority", "key_mgmt", "scan_ssid"];
|
||||
|
||||
manager.getNetworkConfiguration = function(config, callback) {
|
||||
var netId = config.netId;
|
||||
var done = 0;
|
||||
for (var n = 0; n < networkConfigurationFields; ++n) {
|
||||
var fieldName = networkConfigurationFields[n];
|
||||
getNetworkVariableCommand(netId, fieldName, function(value) {
|
||||
config[fieldName] = value;
|
||||
if (++done == networkConfigurationFields.length)
|
||||
callback(config);
|
||||
});
|
||||
}
|
||||
}
|
||||
manager.setNetworkConfiguration = function(config, callback) {
|
||||
var netId = config.netId;
|
||||
var done = 0;
|
||||
var errors = 0;
|
||||
for (var n = 0; n < networkConfigurationFields.length; ++n) {
|
||||
var fieldName = networkConfigurationFields[n];
|
||||
if (!(fieldName in config)) {
|
||||
++done;
|
||||
} else {
|
||||
setNetworkVariableCommand(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) {
|
||||
listNetworksCommand(function (reply) {
|
||||
var networks = {};
|
||||
var done = 0;
|
||||
var errors = 0;
|
||||
var lines = reply.split("\n");
|
||||
for (var n = 1; n < lines.length; ++n) {
|
||||
var result = lines[n].split("\t");
|
||||
var netId = result[0];
|
||||
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
|
||||
removeNetworkCommand(netId, function() {
|
||||
callback(null);
|
||||
});
|
||||
} else {
|
||||
callback(networks);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
manager.addNetwork = function(config, callback) {
|
||||
addNetworkCommand(function (netId) {
|
||||
config.netId = netId;
|
||||
manager.setNetworkConfiguration(config, callback);
|
||||
});
|
||||
}
|
||||
manager.updateNetwork = function(config, callback) {
|
||||
manager.setNetworkConfiguration(config, callback);
|
||||
}
|
||||
manager.removeNetwork = function(netId, callback) {
|
||||
removeNetworkCommand(netId, callback);
|
||||
}
|
||||
|
||||
function ipToString(n) {
|
||||
return String((n & (0xff << 24)) >> 24) + "." +
|
||||
((n & (0xff << 16)) >> 16) + "." +
|
||||
((n & (0xff << 8)) >> 8) + "." +
|
||||
((n & (0xff << 0)) >> 0);
|
||||
}
|
||||
|
||||
manager.enableNetwork = function(netId, disableOthers, callback) {
|
||||
getProperty("wifi.interface", "tiwlan0", function (ifname) {
|
||||
if (!ifname) {
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
enableInterface(ifname, function (ok) {
|
||||
if (!ok) {
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
enableNetworkCommand(netId, disableOthers, function (ok) {
|
||||
if (!ok) {
|
||||
disableInterface(ifname, function () {
|
||||
callback(false);
|
||||
});
|
||||
return;
|
||||
}
|
||||
runDhcp(ifname, function (data) {
|
||||
debug("After running dhcp, got data: " + uneval(data));
|
||||
if (!data) {
|
||||
disableInterface(ifname, function() {
|
||||
callback(false);
|
||||
});
|
||||
return;
|
||||
}
|
||||
setProperty("net.dns1", ipToString(data.dns1), function(ok) {
|
||||
if (!ok) {
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
getProperty("net.dnschange", "0", function(value) {
|
||||
if (value === null) {
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
setProperty("net.dnschange", String(Number(value) + 1), function(ok) {
|
||||
callback(ok);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
manager.disableNetwork = function(netId, callback) {
|
||||
disableNetworkCommand(netId, callback);
|
||||
}
|
||||
manager.getMacAddress = getMacAddressCommand;
|
||||
manager.getScanResults = scanResultsCommand;
|
||||
return manager;
|
||||
})();
|
||||
|
||||
function nsWifiWorker() {
|
||||
WifiManager.onsupplicantconnection = function() {
|
||||
debug("Connected to supplicant");
|
||||
WifiManager.getMacAddress(function (mac) {
|
||||
debug("Got mac: " + mac);
|
||||
});
|
||||
}
|
||||
WifiManager.onsupplicantlost = function() {
|
||||
debug("Couldn't connect to supplicant");
|
||||
}
|
||||
|
||||
var networks = Object.create(null);
|
||||
WifiManager.onscanresultsavailable = function() {
|
||||
debug("Scan results are available! Asking for them.");
|
||||
if (networks["Mozilla Guest"])
|
||||
return;
|
||||
WifiManager.getScanResults(function(r) {
|
||||
let lines = r.split("\n");
|
||||
// NB: Skip the header line.
|
||||
let added = !("Mozilla Guest" in networks);
|
||||
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)
|
||||
networks[match[5]] = match[1];
|
||||
else
|
||||
debug("Match didn't find anything for: " + lines[i]);
|
||||
}
|
||||
|
||||
if (("Mozilla Guest" in networks) && added) {
|
||||
debug("Mozilla Guest exists in networks, trying to connect!");
|
||||
var config = Object.create(null);
|
||||
config["ssid"] = '"Mozilla Guest"';
|
||||
//config["bssid"] = '"' + networks["Mozilla Guest"] + '"';
|
||||
config["key_mgmt"] = "NONE";
|
||||
config["scan_ssid"] = 1;
|
||||
WifiManager.addNetwork(config, function (ok) {
|
||||
if (ok) {
|
||||
WifiManager.enableNetwork(config.netId, false, function (ok) {
|
||||
if (ok)
|
||||
debug("Enabled the network!");
|
||||
else
|
||||
debug("Failed to enable the network :(");
|
||||
});
|
||||
} else {
|
||||
debug("Failed to add the network :(");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
WifiManager.setWifiEnabled(true, function (ok) {
|
||||
if (ok === 0)
|
||||
WifiManager.start();
|
||||
else
|
||||
debug("Couldn't start Wifi");
|
||||
});
|
||||
|
||||
debug("Wifi starting");
|
||||
}
|
||||
|
||||
nsWifiWorker.prototype = {
|
||||
classID: WIFIWORKER_CID,
|
||||
classInfo: XPCOMUtils.generateCI({classID: WIFIWORKER_CID,
|
||||
contractID: WIFIWORKER_CONTRACTID,
|
||||
classDescription: "WifiWorker",
|
||||
interfaces: [Ci.nsIRadioWorker,
|
||||
Ci.nsIWifi]}),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioWorker,
|
||||
Ci.nsIWifi]),
|
||||
|
||||
setWifiEnabled: function(enable) {
|
||||
WifiManager.setWifiEnabled(enable, function (ok) {
|
||||
debug(ok);
|
||||
});
|
||||
},
|
||||
|
||||
// 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() {
|
||||
this.setWifiEnabled(false);
|
||||
}
|
||||
};
|
||||
|
||||
const NSGetFactory = XPCOMUtils.generateNSGetFactory([nsWifiWorker]);
|
||||
|
||||
let debug;
|
||||
if (DEBUG) {
|
||||
debug = function (s) {
|
||||
dump("-*- nsWifiWorker component: " + s + "\n");
|
||||
};
|
||||
} else {
|
||||
debug = function (s) {};
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
component {a14e8977-d259-433a-a88d-58dd44657e5b} nsWifiWorker.js
|
|
@ -154,6 +154,7 @@
|
|||
@BINPATH@/components/dom_base.xpt
|
||||
#ifdef MOZ_B2G_RIL
|
||||
@BINPATH@/components/dom_telephony.xpt
|
||||
@BINPATH@/components/dom_wifi.xpt
|
||||
@BINPATH@/components/dom_system_b2g.xpt
|
||||
#endif
|
||||
@BINPATH@/components/dom_battery.xpt
|
||||
|
@ -398,6 +399,8 @@
|
|||
@BINPATH@/components/nsTelephonyWorker.js
|
||||
@BINPATH@/components/Telephony.manifest
|
||||
@BINPATH@/components/Telephony.js
|
||||
@BINPATH@/components/nsWifiWorker.js
|
||||
@BINPATH@/components/nsWifiWorker.manifest
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
@BINPATH@/components/libalerts_s.dylib
|
||||
|
|
Загрузка…
Ссылка в новой задаче