1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/wifi/WifiNetUtil.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,222 @@ 1.4 +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +"use strict"; 1.11 + 1.12 +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; 1.13 + 1.14 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.15 +Cu.import("resource://gre/modules/systemlibs.js"); 1.16 + 1.17 +XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", 1.18 + "@mozilla.org/network/service;1", 1.19 + "nsINetworkService"); 1.20 + 1.21 +this.EXPORTED_SYMBOLS = ["WifiNetUtil"]; 1.22 + 1.23 +const DHCP_PROP = "init.svc.dhcpcd"; 1.24 +const DHCP = "dhcpcd"; 1.25 +const DEBUG = false; 1.26 + 1.27 +this.WifiNetUtil = function(controlMessage) { 1.28 + function debug(msg) { 1.29 + if (DEBUG) { 1.30 + dump('-------------- NetUtil: ' + msg); 1.31 + } 1.32 + } 1.33 + 1.34 + var util = {}; 1.35 + 1.36 + util.configureInterface = function(cfg, callback) { 1.37 + let message = { cmd: "ifc_configure", 1.38 + ifname: cfg.ifname, 1.39 + ipaddr: cfg.ipaddr, 1.40 + mask: cfg.mask, 1.41 + gateway: cfg.gateway, 1.42 + dns1: cfg.dns1, 1.43 + dns2: cfg.dns2 }; 1.44 + 1.45 + controlMessage(message, function(data) { 1.46 + callback(!data.status); 1.47 + }); 1.48 + }; 1.49 + 1.50 + util.runDhcp = function (ifname, callback) { 1.51 + controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) { 1.52 + var dhcpInfo = data.status ? null : data; 1.53 + util.runIpConfig(ifname, dhcpInfo, callback); 1.54 + }); 1.55 + }; 1.56 + 1.57 + util.stopDhcp = function (ifname, callback) { 1.58 + // This function does exactly what dhcp_stop does. Unforunately, if we call 1.59 + // this function twice before the previous callback is returned. We may block 1.60 + // our self waiting for the callback. It slows down the wifi startup procedure. 1.61 + // Therefore, we have to roll our own version here. 1.62 + let dhcpService = DHCP_PROP + "_" + ifname; 1.63 + let suffix = (ifname.substr(0, 3) === "p2p") ? "p2p" : ifname; 1.64 + let processName = DHCP + "_" + suffix; 1.65 + stopProcess(dhcpService, processName, callback); 1.66 + }; 1.67 + 1.68 + util.enableInterface = function (ifname, callback) { 1.69 + controlMessage({ cmd: "ifc_enable", ifname: ifname }, function (data) { 1.70 + callback(!data.status); 1.71 + }); 1.72 + }; 1.73 + 1.74 + util.disableInterface = function (ifname, callback) { 1.75 + controlMessage({ cmd: "ifc_disable", ifname: ifname }, function (data) { 1.76 + callback(!data.status); 1.77 + }); 1.78 + }; 1.79 + 1.80 + util.startDhcpServer = function (config, callback) { 1.81 + gNetworkService.setDhcpServer(true, config, function (error) { 1.82 + callback(!error); 1.83 + }); 1.84 + }; 1.85 + 1.86 + util.stopDhcpServer = function (callback) { 1.87 + gNetworkService.setDhcpServer(false, null, function (error) { 1.88 + callback(!error); 1.89 + }); 1.90 + }; 1.91 + 1.92 + util.addHostRoute = function (ifname, route, callback) { 1.93 + controlMessage({ cmd: "ifc_add_host_route", ifname: ifname, route: route }, function(data) { 1.94 + callback(!data.status); 1.95 + }); 1.96 + }; 1.97 + 1.98 + util.removeHostRoutes = function (ifname, callback) { 1.99 + controlMessage({ cmd: "ifc_remove_host_routes", ifname: ifname }, function(data) { 1.100 + callback(!data.status); 1.101 + }); 1.102 + }; 1.103 + 1.104 + util.setDefaultRoute = function (ifname, route, callback) { 1.105 + controlMessage({ cmd: "ifc_set_default_route", ifname: ifname, route: route }, function(data) { 1.106 + callback(!data.status); 1.107 + }); 1.108 + }; 1.109 + 1.110 + util.getDefaultRoute = function (ifname, callback) { 1.111 + controlMessage({ cmd: "ifc_get_default_route", ifname: ifname }, function(data) { 1.112 + callback(!data.route); 1.113 + }); 1.114 + }; 1.115 + 1.116 + util.removeDefaultRoute = function (ifname, callback) { 1.117 + controlMessage({ cmd: "ifc_remove_default_route", ifname: ifname }, function(data) { 1.118 + callback(!data.status); 1.119 + }); 1.120 + }; 1.121 + 1.122 + util.resetConnections = function (ifname, callback) { 1.123 + controlMessage({ cmd: "ifc_reset_connections", ifname: ifname }, function(data) { 1.124 + callback(!data.status); 1.125 + }); 1.126 + }; 1.127 + 1.128 + util.releaseDhcpLease = function (ifname, callback) { 1.129 + controlMessage({ cmd: "dhcp_release_lease", ifname: ifname }, function(data) { 1.130 + callback(!data.status); 1.131 + }); 1.132 + }; 1.133 + 1.134 + util.getDhcpError = function (callback) { 1.135 + controlMessage({ cmd: "dhcp_get_errmsg" }, function(data) { 1.136 + callback(data.error); 1.137 + }); 1.138 + }; 1.139 + 1.140 + util.runDhcpRenew = function (ifname, callback) { 1.141 + controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) { 1.142 + callback(data.status ? null : data); 1.143 + }); 1.144 + }; 1.145 + 1.146 + util.runIpConfig = function (name, data, callback) { 1.147 + if (!data) { 1.148 + debug("IP config failed to run"); 1.149 + callback({ info: data }); 1.150 + return; 1.151 + } 1.152 + 1.153 + setProperty("net." + name + ".dns1", ipToString(data.dns1), 1.154 + function(ok) { 1.155 + if (!ok) { 1.156 + debug("Unable to set net.<ifname>.dns1"); 1.157 + return; 1.158 + } 1.159 + setProperty("net." + name + ".dns2", ipToString(data.dns2), 1.160 + function(ok) { 1.161 + if (!ok) { 1.162 + debug("Unable to set net.<ifname>.dns2"); 1.163 + return; 1.164 + } 1.165 + setProperty("net." + name + ".gw", ipToString(data.gateway), 1.166 + function(ok) { 1.167 + if (!ok) { 1.168 + debug("Unable to set net.<ifname>.gw"); 1.169 + return; 1.170 + } 1.171 + callback({ info: data }); 1.172 + }); 1.173 + }); 1.174 + }); 1.175 + }; 1.176 + 1.177 + //-------------------------------------------------- 1.178 + // Helper functions. 1.179 + //-------------------------------------------------- 1.180 + 1.181 + function stopProcess(service, process, callback) { 1.182 + var count = 0; 1.183 + var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); 1.184 + function tick() { 1.185 + let result = libcutils.property_get(service); 1.186 + if (result === null) { 1.187 + callback(); 1.188 + return; 1.189 + } 1.190 + if (result === "stopped" || ++count >= 5) { 1.191 + // Either we succeeded or ran out of time. 1.192 + timer = null; 1.193 + callback(); 1.194 + return; 1.195 + } 1.196 + 1.197 + // Else it's still running, continue waiting. 1.198 + timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); 1.199 + } 1.200 + 1.201 + setProperty("ctl.stop", process, tick); 1.202 + } 1.203 + 1.204 + // Wrapper around libcutils.property_set that returns true if setting the 1.205 + // value was successful. 1.206 + // Note that the callback is not called asynchronously. 1.207 + function setProperty(key, value, callback) { 1.208 + let ok = true; 1.209 + try { 1.210 + libcutils.property_set(key, value); 1.211 + } catch(e) { 1.212 + ok = false; 1.213 + } 1.214 + callback(ok); 1.215 + } 1.216 + 1.217 + function ipToString(n) { 1.218 + return String((n >> 0) & 0xFF) + "." + 1.219 + ((n >> 8) & 0xFF) + "." + 1.220 + ((n >> 16) & 0xFF) + "." + 1.221 + ((n >> 24) & 0xFF); 1.222 + } 1.223 + 1.224 + return util; 1.225 +};