2009-05-07 02:16:52 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2008 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
2009-05-21 06:28:43 +08:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
2009-05-07 02:16:52 +08:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#define LOG_TAG "WifiController"
|
|
|
|
#include <cutils/log.h>
|
|
|
|
|
|
|
|
#include "Supplicant.h"
|
|
|
|
#include "WifiController.h"
|
2009-05-08 02:37:10 +08:00
|
|
|
#include "WifiScanner.h"
|
|
|
|
#include "NetworkManager.h"
|
2009-05-13 08:26:28 +08:00
|
|
|
#include "ErrorCode.h"
|
2009-05-23 06:36:13 +08:00
|
|
|
#include "WifiNetwork.h"
|
2009-05-07 02:16:52 +08:00
|
|
|
|
2009-05-23 06:36:13 +08:00
|
|
|
WifiController::WifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs) :
|
|
|
|
Controller("WIFI", propmngr) {
|
2009-05-07 02:16:52 +08:00
|
|
|
strncpy(mModulePath, modpath, sizeof(mModulePath));
|
|
|
|
strncpy(mModuleName, modname, sizeof(mModuleName));
|
|
|
|
strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
|
|
|
|
|
2009-05-23 06:36:13 +08:00
|
|
|
mSupplicant = new Supplicant(this, propmngr);
|
2009-05-08 02:37:10 +08:00
|
|
|
mScanner = new WifiScanner(mSupplicant, 10);
|
2009-05-07 02:16:52 +08:00
|
|
|
mCurrentScanMode = 0;
|
2009-05-21 06:28:43 +08:00
|
|
|
|
2009-05-23 06:36:13 +08:00
|
|
|
mEnabled = false;
|
|
|
|
|
|
|
|
propmngr->registerProperty("wifi.enabled", this);
|
2009-05-07 02:16:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int WifiController::start() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int WifiController::stop() {
|
|
|
|
errno = ENOSYS;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int WifiController::enable() {
|
2009-05-08 02:37:10 +08:00
|
|
|
if (!isPoweredUp()) {
|
|
|
|
sendStatusBroadcast("POWERING_UP");
|
|
|
|
if (powerUp()) {
|
|
|
|
LOGE("Powerup failed (%s)", strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
2009-05-07 02:16:52 +08:00
|
|
|
}
|
2009-05-08 02:37:10 +08:00
|
|
|
|
2009-05-07 02:16:52 +08:00
|
|
|
if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
|
2009-05-08 02:37:10 +08:00
|
|
|
sendStatusBroadcast("LOADING_DRIVER");
|
2009-05-07 02:16:52 +08:00
|
|
|
if (loadKernelModule(mModulePath, mModuleArgs)) {
|
|
|
|
LOGE("Kernel module load failed (%s)", strerror(errno));
|
|
|
|
goto out_powerdown;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-08 02:37:10 +08:00
|
|
|
if (!isFirmwareLoaded()) {
|
|
|
|
sendStatusBroadcast("LOADING_FIRMWARE");
|
|
|
|
if (loadFirmware()) {
|
|
|
|
LOGE("Firmware load failed (%s)", strerror(errno));
|
|
|
|
goto out_powerdown;
|
|
|
|
}
|
2009-05-07 02:16:52 +08:00
|
|
|
}
|
|
|
|
|
2009-05-08 02:37:10 +08:00
|
|
|
if (!mSupplicant->isStarted()) {
|
|
|
|
sendStatusBroadcast("STARTING_SUPPLICANT");
|
|
|
|
if (mSupplicant->start()) {
|
|
|
|
LOGE("Supplicant start failed (%s)", strerror(errno));
|
|
|
|
goto out_unloadmodule;
|
|
|
|
}
|
2009-05-07 02:16:52 +08:00
|
|
|
}
|
|
|
|
|
2009-05-23 06:36:13 +08:00
|
|
|
if (Controller::bindInterface(mSupplicant->getInterfaceName())) {
|
|
|
|
LOGE("Error binding interface (%s)", strerror(errno));
|
|
|
|
goto out_unloadmodule;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mSupplicant->refreshNetworkList())
|
|
|
|
LOGW("Error getting list of networks (%s)", strerror(errno));
|
|
|
|
|
|
|
|
mPropMngr->registerProperty("wifi.scanmode", this);
|
|
|
|
mPropMngr->registerProperty("wifi.interface", this);
|
|
|
|
|
2009-05-07 02:16:52 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
out_unloadmodule:
|
|
|
|
if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
|
|
|
|
if (unloadKernelModule(mModuleName)) {
|
|
|
|
LOGE("Unable to unload module after failure!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
out_powerdown:
|
|
|
|
if (powerDown()) {
|
|
|
|
LOGE("Unable to powerdown after failure!");
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-05-21 06:28:43 +08:00
|
|
|
void WifiController::sendStatusBroadcast(const char *msg) {
|
2009-05-13 05:36:32 +08:00
|
|
|
NetworkManager::Instance()->
|
|
|
|
getBroadcaster()->
|
|
|
|
sendBroadcast(ErrorCode::UnsolicitedInformational, msg, false);
|
2009-05-08 02:37:10 +08:00
|
|
|
}
|
|
|
|
|
2009-05-07 02:16:52 +08:00
|
|
|
int WifiController::disable() {
|
|
|
|
|
2009-05-23 06:36:13 +08:00
|
|
|
mPropMngr->unregisterProperty("wifi.scanmode");
|
2009-05-08 02:37:10 +08:00
|
|
|
if (mSupplicant->isStarted()) {
|
|
|
|
sendStatusBroadcast("STOPPING_SUPPLICANT");
|
|
|
|
if (mSupplicant->stop()) {
|
|
|
|
LOGE("Supplicant stop failed (%s)", strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
2009-05-23 06:36:13 +08:00
|
|
|
} else
|
2009-05-08 02:37:10 +08:00
|
|
|
LOGW("disable(): Supplicant not running?");
|
2009-05-07 02:16:52 +08:00
|
|
|
|
|
|
|
if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
|
2009-05-08 02:37:10 +08:00
|
|
|
sendStatusBroadcast("UNLOADING_DRIVER");
|
2009-05-07 02:16:52 +08:00
|
|
|
if (unloadKernelModule(mModuleName)) {
|
|
|
|
LOGE("Unable to unload module (%s)", strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-08 02:37:10 +08:00
|
|
|
if (isPoweredUp()) {
|
|
|
|
sendStatusBroadcast("POWERING_DOWN");
|
|
|
|
if (powerDown()) {
|
|
|
|
LOGE("Powerdown failed (%s)", strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
2009-05-07 02:16:52 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int WifiController::loadFirmware() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-05-08 02:37:10 +08:00
|
|
|
int WifiController::setScanMode(uint32_t mode) {
|
2009-05-07 02:16:52 +08:00
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
if (mCurrentScanMode == mode)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!(mode & SCAN_ENABLE_MASK)) {
|
|
|
|
if (mCurrentScanMode & SCAN_REPEAT_MASK)
|
2009-05-13 06:50:49 +08:00
|
|
|
mScanner->stop();
|
2009-05-07 02:16:52 +08:00
|
|
|
} else if (mode & SCAN_REPEAT_MASK)
|
2009-05-13 06:50:49 +08:00
|
|
|
rc = mScanner->start(mode & SCAN_ACTIVE_MASK);
|
2009-05-07 02:16:52 +08:00
|
|
|
else
|
|
|
|
rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
|
2009-05-13 06:50:49 +08:00
|
|
|
|
|
|
|
mCurrentScanMode = mode;
|
2009-05-07 02:16:52 +08:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2009-05-23 06:36:13 +08:00
|
|
|
WifiNetwork *WifiController::createNetwork() {
|
|
|
|
WifiNetwork *wn = mSupplicant->createNetwork();
|
|
|
|
return wn;
|
2009-05-13 08:26:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int WifiController::removeNetwork(int networkId) {
|
2009-05-23 06:36:13 +08:00
|
|
|
WifiNetwork *wn = mSupplicant->lookupNetwork(networkId);
|
|
|
|
|
|
|
|
if (!wn)
|
|
|
|
return -1;
|
|
|
|
return mSupplicant->removeNetwork(wn);
|
2009-05-13 08:26:28 +08:00
|
|
|
}
|
|
|
|
|
2009-05-08 02:37:10 +08:00
|
|
|
ScanResultCollection *WifiController::createScanResults() {
|
|
|
|
return mSupplicant->createLatestScanResults();
|
2009-05-07 02:16:52 +08:00
|
|
|
}
|
2009-05-13 08:26:28 +08:00
|
|
|
|
|
|
|
WifiNetworkCollection *WifiController::createNetworkList() {
|
|
|
|
return mSupplicant->createNetworkList();
|
|
|
|
}
|
2009-05-21 06:28:43 +08:00
|
|
|
|
2009-05-23 06:36:13 +08:00
|
|
|
int WifiController::set(const char *name, const char *value) {
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (!strcmp(name, "wifi.enabled")) {
|
|
|
|
int en = atoi(value);
|
|
|
|
|
|
|
|
if (en == mEnabled)
|
|
|
|
return 0;
|
|
|
|
rc = (en ? enable() : disable());
|
|
|
|
if (!rc)
|
|
|
|
mEnabled = en;
|
|
|
|
} else if (!strcmp(name, "wifi.interface")) {
|
|
|
|
errno = EROFS;
|
|
|
|
return -1;
|
|
|
|
} else if (!strcmp(name, "wifi.scanmode"))
|
2009-05-21 06:28:43 +08:00
|
|
|
return setScanMode((uint32_t) strtoul(value, NULL, 0));
|
2009-05-23 06:36:13 +08:00
|
|
|
else
|
|
|
|
return Controller::set(name, value);
|
|
|
|
return rc;
|
2009-05-21 06:28:43 +08:00
|
|
|
}
|
|
|
|
|
2009-05-23 06:36:13 +08:00
|
|
|
const char *WifiController::get(const char *name, char *buffer, size_t maxsize) {
|
|
|
|
|
|
|
|
if (!strcmp(name, "wifi.enabled"))
|
|
|
|
snprintf(buffer, maxsize, "%d", mEnabled);
|
|
|
|
else if (!strcmp(name, "wifi.interface")) {
|
|
|
|
snprintf(buffer, maxsize, "%s",
|
|
|
|
(getBoundInterface() ? getBoundInterface() : "none"));
|
|
|
|
} else if (!strcmp(name, "wifi.scanmode"))
|
2009-05-21 06:28:43 +08:00
|
|
|
snprintf(buffer, maxsize, "0x%.8x", mCurrentScanMode);
|
2009-05-23 06:36:13 +08:00
|
|
|
else
|
|
|
|
return Controller::get(name, buffer, maxsize);
|
2009-05-21 06:28:43 +08:00
|
|
|
|
2009-05-23 06:36:13 +08:00
|
|
|
return buffer;
|
2009-05-21 06:28:43 +08:00
|
|
|
}
|
|
|
|
|