blob: b7bd6edade1866713320c5d112b6b914d3d0f162 [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 Mehat0f486582009-06-16 10:50:47 -070072
San Mehat1441e762009-05-07 11:37:10 -070073 if (!isPoweredUp()) {
San Mehat0f486582009-06-16 10:50:47 -070074 LOGI("Powering up");
San Mehat3aff2d12009-06-15 14:10:44 -070075 sendStatusBroadcast("Powering up WiFi hardware");
San Mehat1441e762009-05-07 11:37:10 -070076 if (powerUp()) {
77 LOGE("Powerup failed (%s)", strerror(errno));
78 return -1;
79 }
San Mehatdc266072009-05-06 11:16:52 -070080 }
San Mehat1441e762009-05-07 11:37:10 -070081
San Mehatdc266072009-05-06 11:16:52 -070082 if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
San Mehat0f486582009-06-16 10:50:47 -070083 LOGI("Loading driver");
San Mehat3aff2d12009-06-15 14:10:44 -070084 sendStatusBroadcast("Loading WiFi driver");
San Mehatdc266072009-05-06 11:16:52 -070085 if (loadKernelModule(mModulePath, mModuleArgs)) {
86 LOGE("Kernel module load failed (%s)", strerror(errno));
87 goto out_powerdown;
88 }
89 }
90
San Mehat1441e762009-05-07 11:37:10 -070091 if (!isFirmwareLoaded()) {
San Mehat0f486582009-06-16 10:50:47 -070092 LOGI("Loading firmware");
San Mehat3aff2d12009-06-15 14:10:44 -070093 sendStatusBroadcast("Loading WiFI firmware");
San Mehat1441e762009-05-07 11:37:10 -070094 if (loadFirmware()) {
95 LOGE("Firmware load failed (%s)", strerror(errno));
96 goto out_powerdown;
97 }
San Mehatdc266072009-05-06 11:16:52 -070098 }
99
San Mehat1441e762009-05-07 11:37:10 -0700100 if (!mSupplicant->isStarted()) {
San Mehat0f486582009-06-16 10:50:47 -0700101 LOGI("Starting WPA Supplicant");
San Mehat3aff2d12009-06-15 14:10:44 -0700102 sendStatusBroadcast("Starting WPA Supplicant");
San Mehat1441e762009-05-07 11:37:10 -0700103 if (mSupplicant->start()) {
104 LOGE("Supplicant start failed (%s)", strerror(errno));
105 goto out_unloadmodule;
106 }
San Mehatdc266072009-05-06 11:16:52 -0700107 }
108
San Mehat3c5a6f02009-05-22 15:36:13 -0700109 if (Controller::bindInterface(mSupplicant->getInterfaceName())) {
110 LOGE("Error binding interface (%s)", strerror(errno));
111 goto out_unloadmodule;
112 }
113
114 if (mSupplicant->refreshNetworkList())
115 LOGW("Error getting list of networks (%s)", strerror(errno));
116
San Mehat3aff2d12009-06-15 14:10:44 -0700117 mPropMngr->registerProperty("wifi.supplicant.state", this);
San Mehat3c5a6f02009-05-22 15:36:13 -0700118 mPropMngr->registerProperty("wifi.scanmode", this);
119 mPropMngr->registerProperty("wifi.interface", this);
120
San Mehat0f486582009-06-16 10:50:47 -0700121 LOGI("Enabled successfully");
San Mehatdc266072009-05-06 11:16:52 -0700122 return 0;
123
124out_unloadmodule:
125 if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
126 if (unloadKernelModule(mModuleName)) {
127 LOGE("Unable to unload module after failure!");
128 }
129 }
130
131out_powerdown:
132 if (powerDown()) {
133 LOGE("Unable to powerdown after failure!");
134 }
135 return -1;
136}
137
San Mehat48765672009-05-20 15:28:43 -0700138void WifiController::sendStatusBroadcast(const char *msg) {
San Mehat8d3fc3f2009-05-12 14:36:32 -0700139 NetworkManager::Instance()->
140 getBroadcaster()->
141 sendBroadcast(ErrorCode::UnsolicitedInformational, msg, false);
San Mehat1441e762009-05-07 11:37:10 -0700142}
143
144int WifiController::disable() {
145
San Mehat3c5a6f02009-05-22 15:36:13 -0700146 mPropMngr->unregisterProperty("wifi.scanmode");
San Mehat3aff2d12009-06-15 14:10:44 -0700147 mPropMngr->unregisterProperty("wifi.supplicant.state");
148 mPropMngr->unregisterProperty("wifi.scanmode");
149
San Mehat1441e762009-05-07 11:37:10 -0700150 if (mSupplicant->isStarted()) {
San Mehat3aff2d12009-06-15 14:10:44 -0700151 sendStatusBroadcast("Stopping WPA Supplicant");
San Mehat1441e762009-05-07 11:37:10 -0700152 if (mSupplicant->stop()) {
153 LOGE("Supplicant stop failed (%s)", strerror(errno));
154 return -1;
155 }
San Mehat3c5a6f02009-05-22 15:36:13 -0700156 } else
San Mehat1441e762009-05-07 11:37:10 -0700157 LOGW("disable(): Supplicant not running?");
San Mehatdc266072009-05-06 11:16:52 -0700158
159 if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
San Mehat3aff2d12009-06-15 14:10:44 -0700160 sendStatusBroadcast("Unloading WiFi driver");
San Mehatdc266072009-05-06 11:16:52 -0700161 if (unloadKernelModule(mModuleName)) {
162 LOGE("Unable to unload module (%s)", strerror(errno));
163 return -1;
164 }
165 }
166
San Mehat1441e762009-05-07 11:37:10 -0700167 if (isPoweredUp()) {
San Mehat3aff2d12009-06-15 14:10:44 -0700168 sendStatusBroadcast("Powering down WiFi hardware");
San Mehat1441e762009-05-07 11:37:10 -0700169 if (powerDown()) {
170 LOGE("Powerdown failed (%s)", strerror(errno));
171 return -1;
172 }
San Mehatdc266072009-05-06 11:16:52 -0700173 }
174 return 0;
175}
176
177int WifiController::loadFirmware() {
178 return 0;
179}
180
San Mehat1441e762009-05-07 11:37:10 -0700181int WifiController::setScanMode(uint32_t mode) {
San Mehatdc266072009-05-06 11:16:52 -0700182 int rc = 0;
183
184 if (mCurrentScanMode == mode)
185 return 0;
186
187 if (!(mode & SCAN_ENABLE_MASK)) {
188 if (mCurrentScanMode & SCAN_REPEAT_MASK)
San Mehate67651c2009-05-12 15:50:49 -0700189 mScanner->stop();
San Mehatdc266072009-05-06 11:16:52 -0700190 } else if (mode & SCAN_REPEAT_MASK)
San Mehate67651c2009-05-12 15:50:49 -0700191 rc = mScanner->start(mode & SCAN_ACTIVE_MASK);
San Mehatdc266072009-05-06 11:16:52 -0700192 else
193 rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
San Mehate67651c2009-05-12 15:50:49 -0700194
195 mCurrentScanMode = mode;
San Mehatdc266072009-05-06 11:16:52 -0700196 return rc;
197}
198
San Mehat3c5a6f02009-05-22 15:36:13 -0700199WifiNetwork *WifiController::createNetwork() {
200 WifiNetwork *wn = mSupplicant->createNetwork();
201 return wn;
San Mehat82a21162009-05-12 17:26:28 -0700202}
203
204int WifiController::removeNetwork(int networkId) {
San Mehat3c5a6f02009-05-22 15:36:13 -0700205 WifiNetwork *wn = mSupplicant->lookupNetwork(networkId);
206
207 if (!wn)
208 return -1;
209 return mSupplicant->removeNetwork(wn);
San Mehat82a21162009-05-12 17:26:28 -0700210}
211
San Mehat1441e762009-05-07 11:37:10 -0700212ScanResultCollection *WifiController::createScanResults() {
San Mehat3aff2d12009-06-15 14:10:44 -0700213 ScanResultCollection *d = new ScanResultCollection();
214 ScanResultCollection::iterator i;
215
216 pthread_mutex_lock(&mLatestScanResultsLock);
217 for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i)
218 d->push_back((*i)->clone());
219
220 pthread_mutex_unlock(&mLatestScanResultsLock);
221 return d;
San Mehatdc266072009-05-06 11:16:52 -0700222}
San Mehat82a21162009-05-12 17:26:28 -0700223
San Mehat82a21162009-05-12 17:26:28 -0700224WifiNetworkCollection *WifiController::createNetworkList() {
225 return mSupplicant->createNetworkList();
226}
San Mehat48765672009-05-20 15:28:43 -0700227
San Mehat3c5a6f02009-05-22 15:36:13 -0700228int WifiController::set(const char *name, const char *value) {
229 int rc;
San Mehat48765672009-05-20 15:28:43 -0700230
San Mehat3c5a6f02009-05-22 15:36:13 -0700231 if (!strcmp(name, "wifi.enabled")) {
232 int en = atoi(value);
233
234 if (en == mEnabled)
235 return 0;
236 rc = (en ? enable() : disable());
237 if (!rc)
238 mEnabled = en;
239 } else if (!strcmp(name, "wifi.interface")) {
240 errno = EROFS;
241 return -1;
242 } else if (!strcmp(name, "wifi.scanmode"))
243 return setScanMode((uint32_t) strtoul(value, NULL, 0));
San Mehat3aff2d12009-06-15 14:10:44 -0700244 else if (!strcmp(name, "wifi.supplicant.state")) {
245 errno = EROFS;
246 return -1;
247 } else
San Mehat3c5a6f02009-05-22 15:36:13 -0700248 return Controller::set(name, value);
249 return rc;
San Mehat48765672009-05-20 15:28:43 -0700250}
251
San Mehat3c5a6f02009-05-22 15:36:13 -0700252const char *WifiController::get(const char *name, char *buffer, size_t maxsize) {
San Mehat48765672009-05-20 15:28:43 -0700253
San Mehat3c5a6f02009-05-22 15:36:13 -0700254 if (!strcmp(name, "wifi.enabled"))
255 snprintf(buffer, maxsize, "%d", mEnabled);
256 else if (!strcmp(name, "wifi.interface")) {
257 snprintf(buffer, maxsize, "%s",
258 (getBoundInterface() ? getBoundInterface() : "none"));
259 } else if (!strcmp(name, "wifi.scanmode"))
260 snprintf(buffer, maxsize, "0x%.8x", mCurrentScanMode);
San Mehat3aff2d12009-06-15 14:10:44 -0700261 else if (!strcmp(name, "wifi.supplicant.state"))
262 return SupplicantState::toString(mSupplicantState, buffer, maxsize);
San Mehat3c5a6f02009-05-22 15:36:13 -0700263 else
264 return Controller::get(name, buffer, maxsize);
265
266 return buffer;
San Mehat48765672009-05-20 15:28:43 -0700267}
268
San Mehat3aff2d12009-06-15 14:10:44 -0700269void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) {
270 LOGD("onAssociatingEvent(%s, %s, %d)",
271 (evt->getBssid() ? evt->getBssid() : "n/a"),
272 (evt->getSsid() ? evt->getSsid() : "n/a"),
273 evt->getFreq());
274}
275
276void WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) {
277 LOGD("onAssociatedEvent(%s)", evt->getBssid());
278}
279
280void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
281 LOGD("onConnectedEvent(%s, %d)", evt->getBssid(), evt->getReassociated());
282 if (!evt->getReassociated()) {
283 SupplicantStatus *ss = mSupplicant->getStatus();
284 WifiNetwork *wn;
285
286 if (ss->getWpaState() != SupplicantState::COMPLETED) {
287 char tmp[32];
288
289 LOGW("onConnected() with SupplicantState = %s!",
290 SupplicantState::toString(ss->getWpaState(), tmp,
291 sizeof(tmp)));
292 return;
293 }
294
295 if (ss->getId() == -1) {
296 LOGW("onConnected() with id = -1!");
297 return;
298 }
299
300 if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) {
301 LOGW("Error looking up connected network id %d (%s)",
302 ss->getId(), strerror(errno));
303 return;
304 }
305
306 delete ss;
307 mHandlers->onInterfaceStarted(this, wn->getIfaceCfg());
308 }
309}
310
311void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
312 char *reply;
313
314 if (!(reply = (char *) malloc(4096))) {
315 LOGE("Out of memory");
316 return;
317 }
318
319 size_t len = 4096;
320
321 if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
322 LOGW("onScanResultsEvent: Error getting scan results (%s)",
323 strerror(errno));
324 free(reply);
325 return;
326 }
327
328 pthread_mutex_lock(&mLatestScanResultsLock);
329 if (!mLatestScanResults->empty()) {
330 ScanResultCollection::iterator i;
331
332 for (i = mLatestScanResults->begin();
333 i !=mLatestScanResults->end(); ++i) {
334 delete *i;
335 }
336 mLatestScanResults->clear();
337 }
338
339 char *linep;
340 char *linep_next = NULL;
341
342 if (!strtok_r(reply, "\n", &linep_next)) {
343 free(reply);
344 pthread_mutex_unlock(&mLatestScanResultsLock);
345 return;
346 }
347
348 while((linep = strtok_r(NULL, "\n", &linep_next)))
349 mLatestScanResults->push_back(new ScanResult(linep));
350
351 char *tmp;
352 asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size());
353 NetworkManager::Instance()->getBroadcaster()->
354 sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false);
355 free(tmp);
356 pthread_mutex_unlock(&mLatestScanResultsLock);
357 free(reply);
358}
359
360void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) {
361 char tmp[32];
362 char tmp2[32];
363
364 LOGD("onStateChangeEvent(%s -> %s)",
365 SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)),
366 SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2)));
367
368 mSupplicantState = evt->getState();
369}
370
371void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
372 LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid());
373}
374
375void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
376 LOGD("onDisconnectedEvent()");
377}
378
379#if 0
380void WifiController::onTerminatingEvent(SupplicantEvent *evt) {
381 LOGD("onTerminatingEvent(%s)", evt->getEvent());
382}
383
384void WifiController::onPasswordChangedEvent(SupplicantEvent *evt) {
385 LOGD("onPasswordChangedEvent(%s)", evt->getEvent());
386}
387
388void WifiController::onEapNotificationEvent(SupplicantEvent *evt) {
389 LOGD("onEapNotificationEvent(%s)", evt->getEvent());
390}
391
392void WifiController::onEapStartedEvent(SupplicantEvent *evt) {
393 LOGD("onEapStartedEvent(%s)", evt->getEvent());
394}
395
396void WifiController::onEapMethodEvent(SupplicantEvent *evt) {
397 LOGD("onEapMethodEvent(%s)", evt->getEvent());
398}
399
400void WifiController::onEapSuccessEvent(SupplicantEvent *evt) {
401 LOGD("onEapSuccessEvent(%s)", evt->getEvent());
402}
403
404void WifiController::onEapFailureEvent(SupplicantEvent *evt) {
405 LOGD("onEapFailureEvent(%s)", evt->getEvent());
406}
407
408void WifiController::onLinkSpeedEvent(SupplicantEvent *evt) {
409 LOGD("onLinkSpeedEvent(%s)", evt->getEvent());
410}
411
412void WifiController::onDriverStateEvent(SupplicantEvent *evt) {
413 LOGD("onDriverStateEvent(%s)", evt->getEvent());
414}
415#endif