| |
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/. */ |
| |
6 |
| |
7 "use strict"; |
| |
8 |
| |
9 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; |
| |
10 |
| |
11 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
| |
12 Cu.import("resource://gre/modules/systemlibs.js"); |
| |
13 |
| |
14 XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", |
| |
15 "@mozilla.org/network/service;1", |
| |
16 "nsINetworkService"); |
| |
17 |
| |
18 this.EXPORTED_SYMBOLS = ["WifiNetUtil"]; |
| |
19 |
| |
20 const DHCP_PROP = "init.svc.dhcpcd"; |
| |
21 const DHCP = "dhcpcd"; |
| |
22 const DEBUG = false; |
| |
23 |
| |
24 this.WifiNetUtil = function(controlMessage) { |
| |
25 function debug(msg) { |
| |
26 if (DEBUG) { |
| |
27 dump('-------------- NetUtil: ' + msg); |
| |
28 } |
| |
29 } |
| |
30 |
| |
31 var util = {}; |
| |
32 |
| |
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 }; |
| |
41 |
| |
42 controlMessage(message, function(data) { |
| |
43 callback(!data.status); |
| |
44 }); |
| |
45 }; |
| |
46 |
| |
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 }; |
| |
53 |
| |
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 }; |
| |
64 |
| |
65 util.enableInterface = function (ifname, callback) { |
| |
66 controlMessage({ cmd: "ifc_enable", ifname: ifname }, function (data) { |
| |
67 callback(!data.status); |
| |
68 }); |
| |
69 }; |
| |
70 |
| |
71 util.disableInterface = function (ifname, callback) { |
| |
72 controlMessage({ cmd: "ifc_disable", ifname: ifname }, function (data) { |
| |
73 callback(!data.status); |
| |
74 }); |
| |
75 }; |
| |
76 |
| |
77 util.startDhcpServer = function (config, callback) { |
| |
78 gNetworkService.setDhcpServer(true, config, function (error) { |
| |
79 callback(!error); |
| |
80 }); |
| |
81 }; |
| |
82 |
| |
83 util.stopDhcpServer = function (callback) { |
| |
84 gNetworkService.setDhcpServer(false, null, function (error) { |
| |
85 callback(!error); |
| |
86 }); |
| |
87 }; |
| |
88 |
| |
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 }; |
| |
94 |
| |
95 util.removeHostRoutes = function (ifname, callback) { |
| |
96 controlMessage({ cmd: "ifc_remove_host_routes", ifname: ifname }, function(data) { |
| |
97 callback(!data.status); |
| |
98 }); |
| |
99 }; |
| |
100 |
| |
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 }; |
| |
106 |
| |
107 util.getDefaultRoute = function (ifname, callback) { |
| |
108 controlMessage({ cmd: "ifc_get_default_route", ifname: ifname }, function(data) { |
| |
109 callback(!data.route); |
| |
110 }); |
| |
111 }; |
| |
112 |
| |
113 util.removeDefaultRoute = function (ifname, callback) { |
| |
114 controlMessage({ cmd: "ifc_remove_default_route", ifname: ifname }, function(data) { |
| |
115 callback(!data.status); |
| |
116 }); |
| |
117 }; |
| |
118 |
| |
119 util.resetConnections = function (ifname, callback) { |
| |
120 controlMessage({ cmd: "ifc_reset_connections", ifname: ifname }, function(data) { |
| |
121 callback(!data.status); |
| |
122 }); |
| |
123 }; |
| |
124 |
| |
125 util.releaseDhcpLease = function (ifname, callback) { |
| |
126 controlMessage({ cmd: "dhcp_release_lease", ifname: ifname }, function(data) { |
| |
127 callback(!data.status); |
| |
128 }); |
| |
129 }; |
| |
130 |
| |
131 util.getDhcpError = function (callback) { |
| |
132 controlMessage({ cmd: "dhcp_get_errmsg" }, function(data) { |
| |
133 callback(data.error); |
| |
134 }); |
| |
135 }; |
| |
136 |
| |
137 util.runDhcpRenew = function (ifname, callback) { |
| |
138 controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) { |
| |
139 callback(data.status ? null : data); |
| |
140 }); |
| |
141 }; |
| |
142 |
| |
143 util.runIpConfig = function (name, data, callback) { |
| |
144 if (!data) { |
| |
145 debug("IP config failed to run"); |
| |
146 callback({ info: data }); |
| |
147 return; |
| |
148 } |
| |
149 |
| |
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 }; |
| |
173 |
| |
174 //-------------------------------------------------- |
| |
175 // Helper functions. |
| |
176 //-------------------------------------------------- |
| |
177 |
| |
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 } |
| |
193 |
| |
194 // Else it's still running, continue waiting. |
| |
195 timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); |
| |
196 } |
| |
197 |
| |
198 setProperty("ctl.stop", process, tick); |
| |
199 } |
| |
200 |
| |
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 } |
| |
213 |
| |
214 function ipToString(n) { |
| |
215 return String((n >> 0) & 0xFF) + "." + |
| |
216 ((n >> 8) & 0xFF) + "." + |
| |
217 ((n >> 16) & 0xFF) + "." + |
| |
218 ((n >> 24) & 0xFF); |
| |
219 } |
| |
220 |
| |
221 return util; |
| |
222 }; |