diff options
Diffstat (limited to 'nexus/WifiController.cpp')
-rw-r--r-- | nexus/WifiController.cpp | 212 |
1 files changed, 196 insertions, 16 deletions
diff --git a/nexus/WifiController.cpp b/nexus/WifiController.cpp index 3d06806..5c5db1a 100644 --- a/nexus/WifiController.cpp +++ b/nexus/WifiController.cpp @@ -27,34 +27,50 @@ #include "NetworkManager.h" #include "ErrorCode.h" #include "WifiNetwork.h" - -WifiController::WifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs) : - Controller("WIFI", propmngr) { +#include "ISupplicantEventHandler.h" +#include "SupplicantState.h" +#include "SupplicantStatus.h" +#include "SupplicantAssociatingEvent.h" +#include "SupplicantAssociatedEvent.h" +#include "SupplicantConnectedEvent.h" +#include "SupplicantScanResultsEvent.h" +#include "SupplicantStateChangeEvent.h" +#include "SupplicantConnectionTimeoutEvent.h" +#include "SupplicantDisconnectedEvent.h" + +WifiController::WifiController(PropertyManager *mPropMngr, + IControllerHandler *handlers, + char *modpath, char *modname, char *modargs) : + Controller("WIFI", mPropMngr, handlers) { strncpy(mModulePath, modpath, sizeof(mModulePath)); strncpy(mModuleName, modname, sizeof(mModuleName)); strncpy(mModuleArgs, modargs, sizeof(mModuleArgs)); - mSupplicant = new Supplicant(this, propmngr); + mLatestScanResults = new ScanResultCollection(); + pthread_mutex_init(&mLatestScanResultsLock, NULL); + + mSupplicant = new Supplicant(this, this); mScanner = new WifiScanner(mSupplicant, 10); mCurrentScanMode = 0; mEnabled = false; - propmngr->registerProperty("wifi.enabled", this); + mSupplicantState = SupplicantState::UNKNOWN; } int WifiController::start() { + mPropMngr->registerProperty("wifi.enabled", this); return 0; } int WifiController::stop() { - errno = ENOSYS; - return -1; + mPropMngr->unregisterProperty("wifi.enabled"); + return 0; } int WifiController::enable() { if (!isPoweredUp()) { - sendStatusBroadcast("POWERING_UP"); + sendStatusBroadcast("Powering up WiFi hardware"); if (powerUp()) { LOGE("Powerup failed (%s)", strerror(errno)); return -1; @@ -62,7 +78,7 @@ int WifiController::enable() { } if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) { - sendStatusBroadcast("LOADING_DRIVER"); + sendStatusBroadcast("Loading WiFi driver"); if (loadKernelModule(mModulePath, mModuleArgs)) { LOGE("Kernel module load failed (%s)", strerror(errno)); goto out_powerdown; @@ -70,7 +86,7 @@ int WifiController::enable() { } if (!isFirmwareLoaded()) { - sendStatusBroadcast("LOADING_FIRMWARE"); + sendStatusBroadcast("Loading WiFI firmware"); if (loadFirmware()) { LOGE("Firmware load failed (%s)", strerror(errno)); goto out_powerdown; @@ -78,7 +94,7 @@ int WifiController::enable() { } if (!mSupplicant->isStarted()) { - sendStatusBroadcast("STARTING_SUPPLICANT"); + sendStatusBroadcast("Starting WPA Supplicant"); if (mSupplicant->start()) { LOGE("Supplicant start failed (%s)", strerror(errno)); goto out_unloadmodule; @@ -93,6 +109,7 @@ int WifiController::enable() { if (mSupplicant->refreshNetworkList()) LOGW("Error getting list of networks (%s)", strerror(errno)); + mPropMngr->registerProperty("wifi.supplicant.state", this); mPropMngr->registerProperty("wifi.scanmode", this); mPropMngr->registerProperty("wifi.interface", this); @@ -121,8 +138,11 @@ void WifiController::sendStatusBroadcast(const char *msg) { int WifiController::disable() { mPropMngr->unregisterProperty("wifi.scanmode"); + mPropMngr->unregisterProperty("wifi.supplicant.state"); + mPropMngr->unregisterProperty("wifi.scanmode"); + if (mSupplicant->isStarted()) { - sendStatusBroadcast("STOPPING_SUPPLICANT"); + sendStatusBroadcast("Stopping WPA Supplicant"); if (mSupplicant->stop()) { LOGE("Supplicant stop failed (%s)", strerror(errno)); return -1; @@ -131,7 +151,7 @@ int WifiController::disable() { LOGW("disable(): Supplicant not running?"); if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) { - sendStatusBroadcast("UNLOADING_DRIVER"); + sendStatusBroadcast("Unloading WiFi driver"); if (unloadKernelModule(mModuleName)) { LOGE("Unable to unload module (%s)", strerror(errno)); return -1; @@ -139,7 +159,7 @@ int WifiController::disable() { } if (isPoweredUp()) { - sendStatusBroadcast("POWERING_DOWN"); + sendStatusBroadcast("Powering down WiFi hardware"); if (powerDown()) { LOGE("Powerdown failed (%s)", strerror(errno)); return -1; @@ -184,7 +204,15 @@ int WifiController::removeNetwork(int networkId) { } ScanResultCollection *WifiController::createScanResults() { - return mSupplicant->createLatestScanResults(); + ScanResultCollection *d = new ScanResultCollection(); + ScanResultCollection::iterator i; + + pthread_mutex_lock(&mLatestScanResultsLock); + for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i) + d->push_back((*i)->clone()); + + pthread_mutex_unlock(&mLatestScanResultsLock); + return d; } WifiNetworkCollection *WifiController::createNetworkList() { @@ -207,7 +235,10 @@ int WifiController::set(const char *name, const char *value) { return -1; } else if (!strcmp(name, "wifi.scanmode")) return setScanMode((uint32_t) strtoul(value, NULL, 0)); - else + else if (!strcmp(name, "wifi.supplicant.state")) { + errno = EROFS; + return -1; + } else return Controller::set(name, value); return rc; } @@ -221,9 +252,158 @@ const char *WifiController::get(const char *name, char *buffer, size_t maxsize) (getBoundInterface() ? getBoundInterface() : "none")); } else if (!strcmp(name, "wifi.scanmode")) snprintf(buffer, maxsize, "0x%.8x", mCurrentScanMode); + else if (!strcmp(name, "wifi.supplicant.state")) + return SupplicantState::toString(mSupplicantState, buffer, maxsize); else return Controller::get(name, buffer, maxsize); return buffer; } +void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) { + LOGD("onAssociatingEvent(%s, %s, %d)", + (evt->getBssid() ? evt->getBssid() : "n/a"), + (evt->getSsid() ? evt->getSsid() : "n/a"), + evt->getFreq()); +} + +void WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) { + LOGD("onAssociatedEvent(%s)", evt->getBssid()); +} + +void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) { + LOGD("onConnectedEvent(%s, %d)", evt->getBssid(), evt->getReassociated()); + if (!evt->getReassociated()) { + SupplicantStatus *ss = mSupplicant->getStatus(); + WifiNetwork *wn; + + if (ss->getWpaState() != SupplicantState::COMPLETED) { + char tmp[32]; + + LOGW("onConnected() with SupplicantState = %s!", + SupplicantState::toString(ss->getWpaState(), tmp, + sizeof(tmp))); + return; + } + + if (ss->getId() == -1) { + LOGW("onConnected() with id = -1!"); + return; + } + + if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) { + LOGW("Error looking up connected network id %d (%s)", + ss->getId(), strerror(errno)); + return; + } + + delete ss; + mHandlers->onInterfaceStarted(this, wn->getIfaceCfg()); + } +} + +void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) { + char *reply; + + if (!(reply = (char *) malloc(4096))) { + LOGE("Out of memory"); + return; + } + + size_t len = 4096; + + if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) { + LOGW("onScanResultsEvent: Error getting scan results (%s)", + strerror(errno)); + free(reply); + return; + } + + pthread_mutex_lock(&mLatestScanResultsLock); + if (!mLatestScanResults->empty()) { + ScanResultCollection::iterator i; + + for (i = mLatestScanResults->begin(); + i !=mLatestScanResults->end(); ++i) { + delete *i; + } + mLatestScanResults->clear(); + } + + char *linep; + char *linep_next = NULL; + + if (!strtok_r(reply, "\n", &linep_next)) { + free(reply); + pthread_mutex_unlock(&mLatestScanResultsLock); + return; + } + + while((linep = strtok_r(NULL, "\n", &linep_next))) + mLatestScanResults->push_back(new ScanResult(linep)); + + char *tmp; + asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size()); + NetworkManager::Instance()->getBroadcaster()-> + sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false); + free(tmp); + pthread_mutex_unlock(&mLatestScanResultsLock); + free(reply); +} + +void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) { + char tmp[32]; + char tmp2[32]; + + LOGD("onStateChangeEvent(%s -> %s)", + SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)), + SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2))); + + mSupplicantState = evt->getState(); +} + +void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) { + LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid()); +} + +void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) { + LOGD("onDisconnectedEvent()"); +} + +#if 0 +void WifiController::onTerminatingEvent(SupplicantEvent *evt) { + LOGD("onTerminatingEvent(%s)", evt->getEvent()); +} + +void WifiController::onPasswordChangedEvent(SupplicantEvent *evt) { + LOGD("onPasswordChangedEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapNotificationEvent(SupplicantEvent *evt) { + LOGD("onEapNotificationEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapStartedEvent(SupplicantEvent *evt) { + LOGD("onEapStartedEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapMethodEvent(SupplicantEvent *evt) { + LOGD("onEapMethodEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapSuccessEvent(SupplicantEvent *evt) { + LOGD("onEapSuccessEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapFailureEvent(SupplicantEvent *evt) { + LOGD("onEapFailureEvent(%s)", evt->getEvent()); +} + +void WifiController::onLinkSpeedEvent(SupplicantEvent *evt) { + LOGD("onLinkSpeedEvent(%s)", evt->getEvent()); +} + +void WifiController::onDriverStateEvent(SupplicantEvent *evt) { + LOGD("onDriverStateEvent(%s)", evt->getEvent()); +} +#endif |