Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
7 "use strict";
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",
16 "nsINetworkService");
18 this.EXPORTED_SYMBOLS = ["WifiNetUtil"];
20 const DHCP_PROP = "init.svc.dhcpcd";
21 const DHCP = "dhcpcd";
22 const DEBUG = false;
24 this.WifiNetUtil = function(controlMessage) {
25 function debug(msg) {
26 if (DEBUG) {
27 dump('-------------- NetUtil: ' + msg);
28 }
29 }
31 var util = {};
33 util.configureInterface = function(cfg, callback) {
34 let message = { cmd: "ifc_configure",
35 ifname: cfg.ifname,
36 ipaddr: cfg.ipaddr,
37 mask: cfg.mask,
38 gateway: cfg.gateway,
39 dns1: cfg.dns1,
40 dns2: cfg.dns2 };
42 controlMessage(message, function(data) {
43 callback(!data.status);
44 });
45 };
47 util.runDhcp = function (ifname, callback) {
48 controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
49 var dhcpInfo = data.status ? null : data;
50 util.runIpConfig(ifname, dhcpInfo, callback);
51 });
52 };
54 util.stopDhcp = function (ifname, callback) {
55 // This function does exactly what dhcp_stop does. Unforunately, if we call
56 // this function twice before the previous callback is returned. We may block
57 // our self waiting for the callback. It slows down the wifi startup procedure.
58 // Therefore, we have to roll our own version here.
59 let dhcpService = DHCP_PROP + "_" + ifname;
60 let suffix = (ifname.substr(0, 3) === "p2p") ? "p2p" : ifname;
61 let processName = DHCP + "_" + suffix;
62 stopProcess(dhcpService, processName, callback);
63 };
65 util.enableInterface = function (ifname, callback) {
66 controlMessage({ cmd: "ifc_enable", ifname: ifname }, function (data) {
67 callback(!data.status);
68 });
69 };
71 util.disableInterface = function (ifname, callback) {
72 controlMessage({ cmd: "ifc_disable", ifname: ifname }, function (data) {
73 callback(!data.status);
74 });
75 };
77 util.startDhcpServer = function (config, callback) {
78 gNetworkService.setDhcpServer(true, config, function (error) {
79 callback(!error);
80 });
81 };
83 util.stopDhcpServer = function (callback) {
84 gNetworkService.setDhcpServer(false, null, function (error) {
85 callback(!error);
86 });
87 };
89 util.addHostRoute = function (ifname, route, callback) {
90 controlMessage({ cmd: "ifc_add_host_route", ifname: ifname, route: route }, function(data) {
91 callback(!data.status);
92 });
93 };
95 util.removeHostRoutes = function (ifname, callback) {
96 controlMessage({ cmd: "ifc_remove_host_routes", ifname: ifname }, function(data) {
97 callback(!data.status);
98 });
99 };
101 util.setDefaultRoute = function (ifname, route, callback) {
102 controlMessage({ cmd: "ifc_set_default_route", ifname: ifname, route: route }, function(data) {
103 callback(!data.status);
104 });
105 };
107 util.getDefaultRoute = function (ifname, callback) {
108 controlMessage({ cmd: "ifc_get_default_route", ifname: ifname }, function(data) {
109 callback(!data.route);
110 });
111 };
113 util.removeDefaultRoute = function (ifname, callback) {
114 controlMessage({ cmd: "ifc_remove_default_route", ifname: ifname }, function(data) {
115 callback(!data.status);
116 });
117 };
119 util.resetConnections = function (ifname, callback) {
120 controlMessage({ cmd: "ifc_reset_connections", ifname: ifname }, function(data) {
121 callback(!data.status);
122 });
123 };
125 util.releaseDhcpLease = function (ifname, callback) {
126 controlMessage({ cmd: "dhcp_release_lease", ifname: ifname }, function(data) {
127 callback(!data.status);
128 });
129 };
131 util.getDhcpError = function (callback) {
132 controlMessage({ cmd: "dhcp_get_errmsg" }, function(data) {
133 callback(data.error);
134 });
135 };
137 util.runDhcpRenew = function (ifname, callback) {
138 controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
139 callback(data.status ? null : data);
140 });
141 };
143 util.runIpConfig = function (name, data, callback) {
144 if (!data) {
145 debug("IP config failed to run");
146 callback({ info: data });
147 return;
148 }
150 setProperty("net." + name + ".dns1", ipToString(data.dns1),
151 function(ok) {
152 if (!ok) {
153 debug("Unable to set net.<ifname>.dns1");
154 return;
155 }
156 setProperty("net." + name + ".dns2", ipToString(data.dns2),
157 function(ok) {
158 if (!ok) {
159 debug("Unable to set net.<ifname>.dns2");
160 return;
161 }
162 setProperty("net." + name + ".gw", ipToString(data.gateway),
163 function(ok) {
164 if (!ok) {
165 debug("Unable to set net.<ifname>.gw");
166 return;
167 }
168 callback({ info: data });
169 });
170 });
171 });
172 };
174 //--------------------------------------------------
175 // Helper functions.
176 //--------------------------------------------------
178 function stopProcess(service, process, callback) {
179 var count = 0;
180 var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
181 function tick() {
182 let result = libcutils.property_get(service);
183 if (result === null) {
184 callback();
185 return;
186 }
187 if (result === "stopped" || ++count >= 5) {
188 // Either we succeeded or ran out of time.
189 timer = null;
190 callback();
191 return;
192 }
194 // Else it's still running, continue waiting.
195 timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
196 }
198 setProperty("ctl.stop", process, tick);
199 }
201 // Wrapper around libcutils.property_set that returns true if setting the
202 // value was successful.
203 // Note that the callback is not called asynchronously.
204 function setProperty(key, value, callback) {
205 let ok = true;
206 try {
207 libcutils.property_set(key, value);
208 } catch(e) {
209 ok = false;
210 }
211 callback(ok);
212 }
214 function ipToString(n) {
215 return String((n >> 0) & 0xFF) + "." +
216 ((n >> 8) & 0xFF) + "." +
217 ((n >> 16) & 0xFF) + "." +
218 ((n >> 24) & 0xFF);
219 }
221 return util;
222 };