blob: 5c5db1a1dbfbea81de73357f48536286e6a38f38 [file] [log] [blame]
San Mehatdc266072009-05-06 11:16:52 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
San Mehat48765672009-05-20 15:28:43 -070016
17#include <stdlib.h>
San Mehatdc266072009-05-06 11:16:52 -070018#include <string.h>
19#include <errno.h>
20
21#define LOG_TAG "WifiController"
22#include <cutils/log.h>
23
24#include "Supplicant.h"
25#include "WifiController.h"
San Mehat1441e762009-05-07 11:37:10 -070026#include "WifiScanner.h"
27#include "NetworkManager.h"
San Mehat82a21162009-05-12 17:26:28 -070028#include "ErrorCode.h"
San Mehat3c5a6f02009-05-22 15:36:13 -070029#include "WifiNetwork.h"
San Mehat3aff2d12009-06-15 14:10:44 -070030#include "ISupplicantEventHandler.h"
31#include "SupplicantState.h"
32#include "SupplicantStatus.h"
33#include "SupplicantAssociatingEvent.h"
34#include "SupplicantAssociatedEvent.h"
35#include "SupplicantConnectedEvent.h"
36#include "SupplicantScanResultsEvent.h"
37#include "SupplicantStateChangeEvent.h"
38#include "SupplicantConnectionTimeoutEvent.h"
39#include "SupplicantDisconnectedEvent.h"
San Mehatdc266072009-05-06 11:16:52 -070040
San Mehat3aff2d12009-06-15 14:10:44 -070041WifiController::WifiController(PropertyManager *mPropMngr,
42 IControllerHandler *handlers,
43 char *modpath, char *modname, char *modargs) :
44 Controller("WIFI", mPropMngr, handlers) {
San Mehatdc266072009-05-06 11:16:52 -070045 strncpy(mModulePath, modpath, sizeof(mModulePath));
46 strncpy(mModuleName, modname, sizeof(mModuleName));
47 strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
48
San Mehat3aff2d12009-06-15 14:10:44 -070049 mLatestScanResults = new ScanResultCollection();
50 pthread_mutex_init(&mLatestScanResultsLock, NULL);
51
52 mSupplicant = new Supplicant(this, this);
San Mehat1441e762009-05-07 11:37:10 -070053 mScanner = new WifiScanner(mSupplicant, 10);
San Mehatdc266072009-05-06 11:16:52 -070054 mCurrentScanMode = 0;
San Mehat48765672009-05-20 15:28:43 -070055
San Mehat3c5a6f02009-05-22 15:36:13 -070056 mEnabled = false;
57
San Mehat3aff2d12009-06-15 14:10:44 -070058 mSupplicantState = SupplicantState::UNKNOWN;
San Mehatdc266072009-05-06 11:16:52 -070059}
60
61int WifiController::start() {
San Mehat3aff2d12009-06-15 14:10:44 -070062 mPropMngr->registerProperty("wifi.enabled", this);
San Mehatdc266072009-05-06 11:16:52 -070063 return 0;
64}
65
66int WifiController::stop() {
San Mehat3aff2d12009-06-15 14:10:44 -070067 mPropMngr->unregisterProperty("wifi.enabled");
68 return 0;
San Mehatdc266072009-05-06 11:16:52 -070069}
70
71int WifiController::enable() {
San Mehat1441e762009-05-07 11:37:10 -070072 if (!isPoweredUp()) {
San Mehat3aff2d12009-06-15 14:10:44 -070073 sendStatusBroadcast("Powering up WiFi hardware");
San Mehat1441e762009-05-07 11:37:10 -070074 if (powerUp()) {
75 LOGE("Powerup failed (%s)", strerror(errno));
76 return -1;
77 }
San Mehatdc266072009-05-06 11:16:52 -070078 }
San Mehat1441e762009-05-07 11:37:10 -070079
San Mehatdc266072009-05-06 11:16:52 -070080 if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
San Mehat3aff2d12009-06-15 14:10:44 -070081 sendStatusBroadcast("Loading WiFi driver");
San Mehatdc266072009-05-06 11:16:52 -070082 if (loadKernelModule(mModulePath, mModuleArgs)) {
83 LOGE("Kernel module load failed (%s)", strerror(errno));
84 goto out_powerdown;
85 }
86 }
87
San Mehat1441e762009-05-07 11:37:10 -070088 if (!isFirmwareLoaded()) {
San Mehat3aff2d12009-06-15 14:10:44 -070089 sendStatusBroadcast("Loading WiFI firmware");
San Mehat1441e762009-05-07 11:37:10 -070090 if (loadFirmware()) {
91 LOGE("Firmware load failed (%s)", strerror(errno));
92 goto out_powerdown;
93 }
San Mehatdc266072009-05-06 11:16:52 -070094 }
95
San Mehat1441e762009-05-07 11:37:10 -070096 if (!mSupplicant->isStarted()) {
San Mehat3aff2d12009-06-15 14:10:44 -070097 sendStatusBroadcast("Starting WPA Supplicant");
San Mehat1441e762009-05-07 11:37:10 -070098 if (mSupplicant->start()) {
99 LOGE("Supplicant start failed (%s)", strerror(errno));
100 goto out_unloadmodule;
101 }
San Mehatdc266072009-05-06 11:16:52 -0700102 }
103
San Mehat3c5a6f02009-05-22 15:36:13 -0700104 if (Controller::bindInterface(mSupplicant->getInterfaceName())) {
105 LOGE("Error binding interface (%s)", strerror(errno));
106 goto out_unloadmodule;
107 }
108
109 if (mSupplicant->refreshNetworkList())
110 LOGW("Error getting list of networks (%s)", strerror(errno));
111
San Mehat3aff2d12009-06-15 14:10:44 -0700112 mPropMngr->registerProperty("wifi.supplicant.state", this);
San Mehat3c5a6f02009-05-22 15:36:13 -0700113 mPropMngr->registerProperty("wifi.scanmode", this);
114 mPropMngr->registerProperty("wifi.interface", this);
115
San Mehatdc266072009-05-06 11:16:52 -0700116 return 0;
117
118out_unloadmodule:
119 if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
120 if (unloadKernelModule(mModuleName)) {
121 LOGE("Unable to unload module after failure!");
122 }
123 }
124
125out_powerdown:
126 if (powerDown()) {
127 LOGE("Unable to powerdown after failure!");
128 }
129 return -1;
130}
131
San Mehat48765672009-05-20 15:28:43 -0700132void WifiController::sendStatusBroadcast(const char *msg) {
San Mehat8d3fc3f2009-05-12 14:36:32 -0700133 NetworkManager::Instance()->
134 getBroadcaster()->
135 sendBroadcast(ErrorCode::UnsolicitedInformational, msg, false);
San Mehat1441e762009-05-07 11:37:10 -0700136}
137
138int WifiController::disable() {
139
San Mehat3c5a6f02009-05-22 15:36:13 -0700140 mPropMngr->unregisterProperty("wifi.scanmode");
San Mehat3aff2d12009-06-15 14:10:44 -0700141 mPropMngr->unregisterProperty("wifi.supplicant.state");
142 mPropMngr->unregisterProperty("wifi.scanmode");
143
San Mehat1441e762009-05-07 11:37:10 -0700144 if (mSupplicant->isStarted()) {
San Mehat3aff2d12009-06-15 14:10:44 -0700145 sendStatusBroadcast("Stopping WPA Supplicant");
San Mehat1441e762009-05-07 11:37:10 -0700146 if (mSupplicant->stop()) {
147 LOGE("Supplicant stop failed (%s)", strerror(errno));
148 return -1;
149 }
San Mehat3c5a6f02009-05-22 15:36:13 -0700150 } else
San Mehat1441e762009-05-07 11:37:10 -0700151 LOGW("disable(): Supplicant not running?");
San Mehatdc266072009-05-06 11:16:52 -0700152
153 if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
San Mehat3aff2d12009-06-15 14:10:44 -0700154 sendStatusBroadcast("Unloading WiFi driver");
San Mehatdc266072009-05-06 11:16:52 -0700155 if (unloadKernelModule(mModuleName)) {
156 LOGE("Unable to unload module (%s)", strerror(errno));
157 return -1;
158 }
159 }
160
San Mehat1441e762009-05-07 11:37:10 -0700161 if (isPoweredUp()) {
San Mehat3aff2d12009-06-15 14:10:44 -0700162 sendStatusBroadcast("Powering down WiFi hardware");
San Mehat1441e762009-05-07 11:37:10 -0700163 if (powerDown()) {
164 LOGE("Powerdown failed (%s)", strerror(errno));
165 return -1;
166 }
San Mehatdc266072009-05-06 11:16:52 -0700167 }
168 return 0;
169}
170
171int WifiController::loadFirmware() {
172 return 0;
173}
174
San Mehat1441e762009-05-07 11:37:10 -0700175int WifiController::setScanMode(uint32_t mode) {
San Mehatdc266072009-05-06 11:16:52 -0700176 int rc = 0;
177
178 if (mCurrentScanMode == mode)
179 return 0;
180
181 if (!(mode & SCAN_ENABLE_MASK)) {
182 if (mCurrentScanMode & SCAN_REPEAT_MASK)
San Mehate67651c2009-05-12 15:50:49 -0700183 mScanner->stop();
San Mehatdc266072009-05-06 11:16:52 -0700184 } else if (mode & SCAN_REPEAT_MASK)
San Mehate67651c2009-05-12 15:50:49 -0700185 rc = mScanner->start(mode & SCAN_ACTIVE_MASK);
San Mehatdc266072009-05-06 11:16:52 -0700186 else
187 rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
San Mehate67651c2009-05-12 15:50:49 -0700188
189 mCurrentScanMode = mode;
San Mehatdc266072009-05-06 11:16:52 -0700190 return rc;
191}
192
San Mehat3c5a6f02009-05-22 15:36:13 -0700193WifiNetwork *WifiController::createNetwork() {
194 WifiNetwork *wn = mSupplicant->createNetwork();
195 return wn;
San Mehat82a21162009-05-12 17:26:28 -0700196}
197
198int WifiController::removeNetwork(int networkId) {
San Mehat3c5a6f02009-05-22 15:36:13 -0700199 WifiNetwork *wn = mSupplicant->lookupNetwork(networkId);
200
201 if (!wn)
202 return -1;
203 return mSupplicant->removeNetwork(wn);
San Mehat82a21162009-05-12 17:26:28 -0700204}
205
San Mehat1441e762009-05-07 11:37:10 -0700206ScanResultCollection *WifiController::createScanResults() {
San Mehat3aff2d12009-06-15 14:10:44 -0700207 ScanResultCollection *d = new ScanResultCollection();
208 ScanResultCollection::iterator i;
209
210 pthread_mutex_lock(&mLatestScanResultsLock);
211 for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i)
212 d->push_back((*i)->clone());
213
214 pthread_mutex_unlock(&mLatestScanResultsLock);
215 return d;
San Mehatdc266072009-05-06 11:16:52 -0700216}
San Mehat82a21162009-05-12 17:26:28 -0700217
San Mehat82a21162009-05-12 17:26:28 -0700218WifiNetworkCollection *WifiController::createNetworkList() {
219 return mSupplicant->createNetworkList();
220}
San Mehat48765672009-05-20 15:28:43 -0700221
San Mehat3c5a6f02009-05-22 15:36:13 -0700222int WifiController::set(const char *name, const char *value) {
223 int rc;
San Mehat48765672009-05-20 15:28:43 -0700224
San Mehat3c5a6f02009-05-22 15:36:13 -0700225 if (!strcmp(name, "wifi.enabled")) {
226 int en = atoi(value);
227
228 if (en == mEnabled)
229 return 0;
230 rc = (en ? enable() : disable());
231 if (!rc)
232 mEnabled = en;
233 } else if (!strcmp(name, "wifi.interface")) {
234 errno = EROFS;
235 return -1;
236 } else if (!strcmp(name, "wifi.scanmode"))
237 return setScanMode((uint32_t) strtoul(value, NULL, 0));
San Mehat3aff2d12009-06-15 14:10:44 -0700238 else if (!strcmp(name, "wifi.supplicant.state")) {
239 errno = EROFS;
240 return -1;
241 } else
San Mehat3c5a6f02009-05-22 15:36:13 -0700242 return Controller::set(name, value);
243 return rc;
San Mehat48765672009-05-20 15:28:43 -0700244}
245
San Mehat3c5a6f02009-05-22 15:36:13 -0700246const char *WifiController::get(const char *name, char *buffer, size_t maxsize) {
San Mehat48765672009-05-20 15:28:43 -0700247
San Mehat3c5a6f02009-05-22 15:36:13 -0700248 if (!strcmp(name, "wifi.enabled"))
249 snprintf(buffer, maxsize, "%d", mEnabled);
250 else if (!strcmp(name, "wifi.interface")) {
251 snprintf(buffer, maxsize, "%s",
252 (getBoundInterface() ? getBoundInterface() : "none"));
253 } else if (!strcmp(name, "wifi.scanmode"))
254 snprintf(buffer, maxsize, "0x%.8x", mCurrentScanMode);
San Mehat3aff2d12009-06-15 14:10:44 -0700255 else if (!strcmp(name, "wifi.supplicant.state"))
256 return SupplicantState::toString(mSupplicantState, buffer, maxsize);
San Mehat3c5a6f02009-05-22 15:36:13 -0700257 else
258 return Controller::get(name, buffer, maxsize);
259
260 return buffer;
San Mehat48765672009-05-20 15:28:43 -0700261}
262
San Mehat3aff2d12009-06-15 14:10:44 -0700263void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) {
264 LOGD("onAssociatingEvent(%s, %s, %d)",
265 (evt->getBssid() ? evt->getBssid() : "n/a"),
266 (evt->getSsid() ? evt->getSsid() : "n/a"),
267 evt->getFreq());
268}
269
270void WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) {
271 LOGD("onAssociatedEvent(%s)", evt->getBssid());
272}
273
274void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
275 LOGD("onConnectedEvent(%s, %d)", evt->getBssid(), evt->getReassociated());
276 if (!evt->getReassociated()) {
277 SupplicantStatus *ss = mSupplicant->getStatus();
278 WifiNetwork *wn;
279
280 if (ss->getWpaState() != SupplicantState::COMPLETED) {
281 char tmp[32];
282
283 LOGW("onConnected() with SupplicantState = %s!",
284 SupplicantState::toString(ss->getWpaState(), tmp,
285 sizeof(tmp)));
286 return;
287 }
288
289 if (ss->getId() == -1) {
290 LOGW("onConnected() with id = -1!");
291 return;
292 }
293
294 if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) {
295 LOGW("Error looking up connected network id %d (%s)",
296 ss->getId(), strerror(errno));
297 return;
298 }
299
300 delete ss;
301 mHandlers->onInterfaceStarted(this, wn->getIfaceCfg());
302 }
303}
304
305void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
306 char *reply;
307
308 if (!(reply = (char *) malloc(4096))) {
309 LOGE("Out of memory");
310 return;
311 }
312
313 size_t len = 4096;
314
315 if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
316 LOGW("onScanResultsEvent: Error getting scan results (%s)",
317 strerror(errno));
318 free(reply);
319 return;
320 }
321
322 pthread_mutex_lock(&mLatestScanResultsLock);
323 if (!mLatestScanResults->empty()) {
324 ScanResultCollection::iterator i;
325
326 for (i = mLatestScanResults->begin();
327 i !=mLatestScanResults->end(); ++i) {
328 delete *i;
329 }
330 mLatestScanResults->clear();
331 }
332
333 char *linep;
334 char *linep_next = NULL;
335
336 if (!strtok_r(reply, "\n", &linep_next)) {
337 free(reply);
338 pthread_mutex_unlock(&mLatestScanResultsLock);
339 return;
340 }
341
342 while((linep = strtok_r(NULL, "\n", &linep_next)))
343 mLatestScanResults->push_back(new ScanResult(linep));
344
345 char *tmp;
346 asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size());
347 NetworkManager::Instance()->getBroadcaster()->
348 sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false);
349 free(tmp);
350 pthread_mutex_unlock(&mLatestScanResultsLock);
351 free(reply);
352}
353
354void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) {
355 char tmp[32];
356 char tmp2[32];
357
358 LOGD("onStateChangeEvent(%s -> %s)",
359 SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)),
360 SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2)));
361
362 mSupplicantState = evt->getState();
363}
364
365void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
366 LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid());
367}
368
369void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
370 LOGD("onDisconnectedEvent()");
371}
372
373#if 0
374void WifiController::onTerminatingEvent(SupplicantEvent *evt) {
375 LOGD("onTerminatingEvent(%s)", evt->getEvent());
376}
377
378void WifiController::onPasswordChangedEvent(SupplicantEvent *evt) {
379 LOGD("onPasswordChangedEvent(%s)", evt->getEvent());
380}
381
382void WifiController::onEapNotificationEvent(SupplicantEvent *evt) {
383 LOGD("onEapNotificationEvent(%s)", evt->getEvent());
384}
385
386void WifiController::onEapStartedEvent(SupplicantEvent *evt) {
387 LOGD("onEapStartedEvent(%s)", evt->getEvent());
388}
389
390void WifiController::onEapMethodEvent(SupplicantEvent *evt) {
391 LOGD("onEapMethodEvent(%s)", evt->getEvent());
392}
393
394void WifiController::onEapSuccessEvent(SupplicantEvent *evt) {
395 LOGD("onEapSuccessEvent(%s)", evt->getEvent());
396}
397
398void WifiController::onEapFailureEvent(SupplicantEvent *evt) {
399 LOGD("onEapFailureEvent(%s)", evt->getEvent());
400}
401
402void WifiController::onLinkSpeedEvent(SupplicantEvent *evt) {
403 LOGD("onLinkSpeedEvent(%s)", evt->getEvent());
404}
405
406void WifiController::onDriverStateEvent(SupplicantEvent *evt) {
407 LOGD("onDriverStateEvent(%s)", evt->getEvent());
408}
409#endif