1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
2 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
9 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
11 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
12 Cu.import("resource://gre/modules/systemlibs.js");
14 XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService",
15 "@mozilla.org/network/service;1",
18 this.EXPORTED_SYMBOLS = ["WifiNetUtil"];
20 const DHCP_PROP = "init.svc.dhcpcd";
21 const DHCP = "dhcpcd";
24 this.WifiNetUtil = function(controlMessage) {
27 dump('-------------- NetUtil: ' + msg);
33 util.configureInterface = function(cfg, callback) {
34 let message = { cmd: "ifc_configure",
42 controlMessage(message, function(data) {
43 callback(!data.status);
47 util.runDhcp = function (ifname, callback) {
48 util.stopDhcp(ifname, function() {
49 controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
50 var dhcpInfo = data.status ? null : data;
51 util.runIpConfig(ifname, dhcpInfo, callback);
56 util.stopDhcp = function (ifname, callback) {
57 // This function does exactly what dhcp_stop does. Unforunately, if we call
58 // this function twice before the previous callback is returned. We may block
59 // our self waiting for the callback. It slows down the wifi startup procedure.
60 // Therefore, we have to roll our own version here.
61 let dhcpService = DHCP_PROP + "_" + ifname;
62 let suffix = (ifname.substr(0, 3) === "p2p") ? "p2p" : ifname;
63 let processName = DHCP + "_" + suffix;
65 // The implementation of |dhcp_do_request| would wait until the
66 // |result_prop_name| (e.g. dhcp.wlan0.result) to be non-null
67 // or 30 second timeout. So we manually change the result property
68 // to 'ko' to avoid timeout.
70 // http://androidxref.com/4.4.4_r1/xref/system/core/libnetutils/dhcp_utils.c#234
71 setProperty('dhcp.' + suffix + '.result', 'ko', function() {
72 stopProcess(dhcpService, processName, callback);
76 util.enableInterface = function (ifname, callback) {
77 controlMessage({ cmd: "ifc_enable", ifname: ifname }, function (data) {
78 callback(!data.status);
82 util.disableInterface = function (ifname, callback) {
83 controlMessage({ cmd: "ifc_disable", ifname: ifname }, function (data) {
84 callback(!data.status);
88 util.startDhcpServer = function (config, callback) {
89 gNetworkService.setDhcpServer(true, config, function (error) {
94 util.stopDhcpServer = function (callback) {
95 gNetworkService.setDhcpServer(false, null, function (error) {
100 util.addHostRoute = function (ifname, route, callback) {
101 controlMessage({ cmd: "ifc_add_host_route", ifname: ifname, route: route }, function(data) {
102 callback(!data.status);
106 util.removeHostRoutes = function (ifname, callback) {
107 controlMessage({ cmd: "ifc_remove_host_routes", ifname: ifname }, function(data) {
108 callback(!data.status);
112 util.setDefaultRoute = function (ifname, route, callback) {
113 controlMessage({ cmd: "ifc_set_default_route", ifname: ifname, route: route }, function(data) {
114 callback(!data.status);
118 util.getDefaultRoute = function (ifname, callback) {
119 controlMessage({ cmd: "ifc_get_default_route", ifname: ifname }, function(data) {
120 callback(!data.route);
124 util.removeDefaultRoute = function (ifname, callback) {
125 controlMessage({ cmd: "ifc_remove_default_route", ifname: ifname }, function(data) {
126 callback(!data.status);
130 util.resetConnections = function (ifname, callback) {
131 controlMessage({ cmd: "ifc_reset_connections", ifname: ifname }, function(data) {
132 callback(!data.status);
136 util.releaseDhcpLease = function (ifname, callback) {
137 controlMessage({ cmd: "dhcp_release_lease", ifname: ifname }, function(data) {
138 callback(!data.status);
142 util.getDhcpError = function (callback) {
143 controlMessage({ cmd: "dhcp_get_errmsg" }, function(data) {
144 callback(data.error);
148 util.runDhcpRenew = function (ifname, callback) {
149 controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
150 callback(data.status ? null : data);
154 util.runIpConfig = function (name, data, callback) {
156 debug("IP config failed to run");
157 callback({ info: data });
161 setProperty("net." + name + ".dns1", ipToString(data.dns1),
164 debug("Unable to set net.<ifname>.dns1");
167 setProperty("net." + name + ".dns2", ipToString(data.dns2),
170 debug("Unable to set net.<ifname>.dns2");
173 setProperty("net." + name + ".gw", ipToString(data.gateway),
176 debug("Unable to set net.<ifname>.gw");
179 callback({ info: data });
185 //--------------------------------------------------
187 //--------------------------------------------------
189 function stopProcess(service, process, callback) {
191 var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
193 let result = libcutils.property_get(service);
194 if (result === null) {
198 if (result === "stopped" || ++count >= 5) {
199 // Either we succeeded or ran out of time.
205 // Else it's still running, continue waiting.
206 timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
209 setProperty("ctl.stop", process, tick);
212 // Wrapper around libcutils.property_set that returns true if setting the
213 // value was successful.
214 // Note that the callback is not called asynchronously.
215 function setProperty(key, value, callback) {
218 libcutils.property_set(key, value);
225 function ipToString(n) {
226 return String((n >> 0) & 0xFF) + "." +
227 ((n >> 8) & 0xFF) + "." +
228 ((n >> 16) & 0xFF) + "." +