| /* | |
| * 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. | |
| */ | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <errno.h> | |
| #define LOG_TAG "WifiController" | |
| #include <cutils/log.h> | |
| #include "Supplicant.h" | |
| #include "WifiController.h" | |
| #include "NetworkManager.h" | |
| #include "ResponseCode.h" | |
| #include "WifiNetwork.h" | |
| #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" | |
| #include "WifiStatusPoller.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)); | |
| mLatestScanResults = new ScanResultCollection(); | |
| pthread_mutex_init(&mLatestScanResultsLock, NULL); | |
| pthread_mutex_init(&mLock, NULL); | |
| mSupplicant = new Supplicant(this, this); | |
| mActiveScan = false; | |
| mEnabled = false; | |
| mScanOnly = false; | |
| mPacketFilter = false; | |
| mBluetoothCoexScan = false; | |
| mBluetoothCoexMode = 0; | |
| mCurrentlyConnectedNetworkId = -1; | |
| mStatusPoller = new WifiStatusPoller(this); | |
| mRssiEventThreshold = 5; | |
| mLastLinkSpeed = 0; | |
| mSupplicantState = SupplicantState::UNKNOWN; | |
| mStaticProperties.propEnabled = new WifiEnabledProperty(this); | |
| mStaticProperties.propScanOnly = new WifiScanOnlyProperty(this); | |
| mStaticProperties.propAllowedChannels = new WifiAllowedChannelsProperty(this); | |
| mStaticProperties.propRssiEventThreshold = | |
| new IntegerPropertyHelper("RssiEventThreshold", false, &mRssiEventThreshold); | |
| mDynamicProperties.propSupplicantState = new WifiSupplicantStateProperty(this); | |
| mDynamicProperties.propActiveScan = new WifiActiveScanProperty(this); | |
| mDynamicProperties.propInterface = new WifiInterfaceProperty(this); | |
| mDynamicProperties.propSearching = new WifiSearchingProperty(this); | |
| mDynamicProperties.propPacketFilter = new WifiPacketFilterProperty(this); | |
| mDynamicProperties.propBluetoothCoexScan = new WifiBluetoothCoexScanProperty(this); | |
| mDynamicProperties.propBluetoothCoexMode = new WifiBluetoothCoexModeProperty(this); | |
| mDynamicProperties.propCurrentNetwork = new WifiCurrentNetworkProperty(this); | |
| mDynamicProperties.propRssi = new IntegerPropertyHelper("Rssi", true, &mLastRssi); | |
| mDynamicProperties.propLinkSpeed = new IntegerPropertyHelper("LinkSpeed", true, &mLastLinkSpeed); | |
| mDynamicProperties.propSuspended = new WifiSuspendedProperty(this); | |
| mDynamicProperties.propNetCount = new WifiNetCountProperty(this); | |
| mDynamicProperties.propTriggerScan = new WifiTriggerScanProperty(this); | |
| } | |
| int WifiController::start() { | |
| mPropMngr->attachProperty("wifi", mStaticProperties.propEnabled); | |
| mPropMngr->attachProperty("wifi", mStaticProperties.propScanOnly); | |
| mPropMngr->attachProperty("wifi", mStaticProperties.propAllowedChannels); | |
| mPropMngr->attachProperty("wifi", mStaticProperties.propRssiEventThreshold); | |
| return 0; | |
| } | |
| int WifiController::stop() { | |
| mPropMngr->detachProperty("wifi", mStaticProperties.propEnabled); | |
| mPropMngr->detachProperty("wifi", mStaticProperties.propScanOnly); | |
| mPropMngr->detachProperty("wifi", mStaticProperties.propAllowedChannels); | |
| mPropMngr->detachProperty("wifi", mStaticProperties.propRssiEventThreshold); | |
| return 0; | |
| } | |
| int WifiController::enable() { | |
| if (!isPoweredUp()) { | |
| LOGI("Powering up"); | |
| sendStatusBroadcast("Powering up WiFi hardware"); | |
| if (powerUp()) { | |
| LOGE("Powerup failed (%s)", strerror(errno)); | |
| return -1; | |
| } | |
| } | |
| if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) { | |
| LOGI("Loading driver"); | |
| sendStatusBroadcast("Loading WiFi driver"); | |
| if (loadKernelModule(mModulePath, mModuleArgs)) { | |
| LOGE("Kernel module load failed (%s)", strerror(errno)); | |
| goto out_powerdown; | |
| } | |
| } | |
| if (!isFirmwareLoaded()) { | |
| LOGI("Loading firmware"); | |
| sendStatusBroadcast("Loading WiFI firmware"); | |
| if (loadFirmware()) { | |
| LOGE("Firmware load failed (%s)", strerror(errno)); | |
| goto out_powerdown; | |
| } | |
| } | |
| if (!mSupplicant->isStarted()) { | |
| LOGI("Starting WPA Supplicant"); | |
| sendStatusBroadcast("Starting WPA Supplicant"); | |
| if (mSupplicant->start()) { | |
| LOGE("Supplicant start failed (%s)", strerror(errno)); | |
| goto out_unloadmodule; | |
| } | |
| } | |
| 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)); | |
| LOGW("TODO: Set # of allowed regulatory channels!"); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propSupplicantState); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propActiveScan); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propInterface); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propSearching); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propPacketFilter); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexScan); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexMode); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propCurrentNetwork); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propRssi); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propLinkSpeed); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propSuspended); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propNetCount); | |
| mPropMngr->attachProperty("wifi", mDynamicProperties.propTriggerScan); | |
| LOGI("Enabled successfully"); | |
| 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; | |
| } | |
| bool WifiController::getSuspended() { | |
| pthread_mutex_lock(&mLock); | |
| bool r = mSuspended; | |
| pthread_mutex_unlock(&mLock); | |
| return r; | |
| } | |
| int WifiController::setSuspend(bool suspend) { | |
| pthread_mutex_lock(&mLock); | |
| if (suspend == mSuspended) { | |
| LOGW("Suspended state already = %d", suspend); | |
| pthread_mutex_unlock(&mLock); | |
| return 0; | |
| } | |
| if (suspend) { | |
| mHandlers->onControllerSuspending(this); | |
| char tmp[80]; | |
| LOGD("Suspending from supplicant state %s", | |
| SupplicantState::toString(mSupplicantState, | |
| tmp, | |
| sizeof(tmp))); | |
| if (mSupplicantState != SupplicantState::IDLE) { | |
| LOGD("Forcing Supplicant disconnect"); | |
| if (mSupplicant->disconnect()) { | |
| LOGW("Error disconnecting (%s)", strerror(errno)); | |
| } | |
| } | |
| LOGD("Stopping Supplicant driver"); | |
| if (mSupplicant->stopDriver()) { | |
| LOGE("Error stopping driver (%s)", strerror(errno)); | |
| pthread_mutex_unlock(&mLock); | |
| return -1; | |
| } | |
| } else { | |
| LOGD("Resuming"); | |
| if (mSupplicant->startDriver()) { | |
| LOGE("Error resuming driver (%s)", strerror(errno)); | |
| pthread_mutex_unlock(&mLock); | |
| return -1; | |
| } | |
| // XXX: set regulatory max channels | |
| if (mScanOnly) | |
| mSupplicant->triggerScan(); | |
| else | |
| mSupplicant->reconnect(); | |
| mHandlers->onControllerResumed(this); | |
| } | |
| mSuspended = suspend; | |
| pthread_mutex_unlock(&mLock); | |
| LOGD("Suspend / Resume completed"); | |
| return 0; | |
| } | |
| void WifiController::sendStatusBroadcast(const char *msg) { | |
| NetworkManager::Instance()-> | |
| getBroadcaster()-> | |
| sendBroadcast(ResponseCode::UnsolicitedInformational, msg, false); | |
| } | |
| int WifiController::disable() { | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propSupplicantState); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propActiveScan); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propInterface); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propSearching); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propPacketFilter); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexScan); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexMode); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propCurrentNetwork); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propRssi); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propLinkSpeed); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propSuspended); | |
| mPropMngr->detachProperty("wifi", mDynamicProperties.propNetCount); | |
| if (mSupplicant->isStarted()) { | |
| sendStatusBroadcast("Stopping WPA Supplicant"); | |
| if (mSupplicant->stop()) { | |
| LOGE("Supplicant stop failed (%s)", strerror(errno)); | |
| return -1; | |
| } | |
| } else | |
| LOGW("disable(): Supplicant not running?"); | |
| if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) { | |
| sendStatusBroadcast("Unloading WiFi driver"); | |
| if (unloadKernelModule(mModuleName)) { | |
| LOGE("Unable to unload module (%s)", strerror(errno)); | |
| return -1; | |
| } | |
| } | |
| if (isPoweredUp()) { | |
| sendStatusBroadcast("Powering down WiFi hardware"); | |
| if (powerDown()) { | |
| LOGE("Powerdown failed (%s)", strerror(errno)); | |
| return -1; | |
| } | |
| } | |
| return 0; | |
| } | |
| int WifiController::loadFirmware() { | |
| return 0; | |
| } | |
| int WifiController::triggerScan() { | |
| pthread_mutex_lock(&mLock); | |
| if (verifyNotSuspended()) { | |
| pthread_mutex_unlock(&mLock); | |
| return -1; | |
| } | |
| switch (mSupplicantState) { | |
| case SupplicantState::DISCONNECTED: | |
| case SupplicantState::INACTIVE: | |
| case SupplicantState::SCANNING: | |
| case SupplicantState::IDLE: | |
| break; | |
| default: | |
| // Switch to scan only mode | |
| mSupplicant->setApScanMode(2); | |
| break; | |
| } | |
| int rc = mSupplicant->triggerScan(); | |
| pthread_mutex_unlock(&mLock); | |
| return rc; | |
| } | |
| int WifiController::setActiveScan(bool active) { | |
| pthread_mutex_lock(&mLock); | |
| if (mActiveScan == active) { | |
| pthread_mutex_unlock(&mLock); | |
| return 0; | |
| } | |
| mActiveScan = active; | |
| int rc = mSupplicant->setScanMode(active); | |
| pthread_mutex_unlock(&mLock); | |
| return rc; | |
| } | |
| WifiNetwork *WifiController::createNetwork() { | |
| pthread_mutex_lock(&mLock); | |
| WifiNetwork *wn = mSupplicant->createNetwork(); | |
| pthread_mutex_unlock(&mLock); | |
| return wn; | |
| } | |
| int WifiController::removeNetwork(int networkId) { | |
| pthread_mutex_lock(&mLock); | |
| WifiNetwork *wn = mSupplicant->lookupNetwork(networkId); | |
| if (!wn) { | |
| pthread_mutex_unlock(&mLock); | |
| return -1; | |
| } | |
| int rc = mSupplicant->removeNetwork(wn); | |
| pthread_mutex_unlock(&mLock); | |
| return rc; | |
| } | |
| ScanResultCollection *WifiController::createScanResults() { | |
| 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() { | |
| return mSupplicant->createNetworkList(); | |
| } | |
| int WifiController::setPacketFilter(bool enable) { | |
| int rc; | |
| pthread_mutex_lock(&mLock); | |
| if (enable) | |
| rc = mSupplicant->enablePacketFilter(); | |
| else | |
| rc = mSupplicant->disablePacketFilter(); | |
| if (!rc) | |
| mPacketFilter = enable; | |
| pthread_mutex_unlock(&mLock); | |
| return rc; | |
| } | |
| int WifiController::setBluetoothCoexistenceScan(bool enable) { | |
| int rc; | |
| pthread_mutex_lock(&mLock); | |
| if (enable) | |
| rc = mSupplicant->enableBluetoothCoexistenceScan(); | |
| else | |
| rc = mSupplicant->disableBluetoothCoexistenceScan(); | |
| if (!rc) | |
| mBluetoothCoexScan = enable; | |
| pthread_mutex_unlock(&mLock); | |
| return rc; | |
| } | |
| int WifiController::setScanOnly(bool scanOnly) { | |
| pthread_mutex_lock(&mLock); | |
| int rc = mSupplicant->setApScanMode((scanOnly ? 2 : 1)); | |
| if (!rc) | |
| mScanOnly = scanOnly; | |
| if (!mSuspended) { | |
| if (scanOnly) | |
| mSupplicant->disconnect(); | |
| else | |
| mSupplicant->reconnect(); | |
| } | |
| pthread_mutex_unlock(&mLock); | |
| return rc; | |
| } | |
| int WifiController::setBluetoothCoexistenceMode(int mode) { | |
| pthread_mutex_lock(&mLock); | |
| int rc = mSupplicant->setBluetoothCoexistenceMode(mode); | |
| if (!rc) | |
| mBluetoothCoexMode = mode; | |
| pthread_mutex_unlock(&mLock); | |
| return rc; | |
| } | |
| 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()); | |
| 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; | |
| } | |
| mCurrentlyConnectedNetworkId = ss->getId(); | |
| if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) { | |
| LOGW("Error looking up connected network id %d (%s)", | |
| ss->getId(), strerror(errno)); | |
| return; | |
| } | |
| delete ss; | |
| mHandlers->onInterfaceConnected(this); | |
| } | |
| void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) { | |
| char *reply; | |
| if (!(reply = (char *) malloc(4096))) { | |
| LOGE("Out of memory"); | |
| return; | |
| } | |
| mNumScanResultsSinceLastStateChange++; | |
| if (mNumScanResultsSinceLastStateChange >= 3) | |
| mIsSupplicantSearching = false; | |
| 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)); | |
| // Switch handling of scan results back to normal mode | |
| mSupplicant->setApScanMode(1); | |
| char *tmp; | |
| asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size()); | |
| NetworkManager::Instance()->getBroadcaster()-> | |
| sendBroadcast(ResponseCode::ScanResultsReady, | |
| tmp, false); | |
| free(tmp); | |
| pthread_mutex_unlock(&mLatestScanResultsLock); | |
| free(reply); | |
| } | |
| void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) { | |
| char tmp[32]; | |
| char tmp2[32]; | |
| if (evt->getState() == mSupplicantState) | |
| return; | |
| LOGD("onStateChangeEvent(%s -> %s)", | |
| SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)), | |
| SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2))); | |
| if (evt->getState() != SupplicantState::SCANNING) { | |
| mIsSupplicantSearching = true; | |
| mNumScanResultsSinceLastStateChange = 0; | |
| } | |
| char *tmp3; | |
| asprintf(&tmp3, | |
| "Supplicant state changed from %d (%s) -> %d (%s)", | |
| mSupplicantState, tmp, evt->getState(), tmp2); | |
| mSupplicantState = evt->getState(); | |
| if (mSupplicantState == SupplicantState::COMPLETED) { | |
| mStatusPoller->start(); | |
| } else if (mStatusPoller->isStarted()) { | |
| mStatusPoller->stop(); | |
| } | |
| NetworkManager::Instance()->getBroadcaster()-> | |
| sendBroadcast(ResponseCode::SupplicantStateChange, | |
| tmp3, false); | |
| free(tmp3); | |
| } | |
| void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) { | |
| LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid()); | |
| } | |
| void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) { | |
| mCurrentlyConnectedNetworkId = -1; | |
| mHandlers->onInterfaceDisconnected(this); | |
| } | |
| #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 | |
| void WifiController::onStatusPollInterval() { | |
| pthread_mutex_lock(&mLock); | |
| int rssi; | |
| if (mSupplicant->getRssi(&rssi)) { | |
| LOGE("Failed to get rssi (%s)", strerror(errno)); | |
| pthread_mutex_unlock(&mLock); | |
| return; | |
| } | |
| if (abs(mLastRssi - rssi) > mRssiEventThreshold) { | |
| char *tmp3; | |
| asprintf(&tmp3, "RSSI changed from %d -> %d", | |
| mLastRssi, rssi); | |
| mLastRssi = rssi; | |
| NetworkManager::Instance()->getBroadcaster()-> | |
| sendBroadcast(ResponseCode::RssiChange, | |
| tmp3, false); | |
| free(tmp3); | |
| } | |
| int linkspeed = mSupplicant->getLinkSpeed(); | |
| if (linkspeed != mLastLinkSpeed) { | |
| char *tmp3; | |
| asprintf(&tmp3, "Link speed changed from %d -> %d", | |
| mLastLinkSpeed, linkspeed); | |
| mLastLinkSpeed = linkspeed; | |
| NetworkManager::Instance()->getBroadcaster()-> | |
| sendBroadcast(ResponseCode::LinkSpeedChange, | |
| tmp3, false); | |
| free(tmp3); | |
| } | |
| pthread_mutex_unlock(&mLock); | |
| } | |
| int WifiController::verifyNotSuspended() { | |
| if (mSuspended) { | |
| errno = ESHUTDOWN; | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| /* | |
| * Property inner classes | |
| */ | |
| WifiController::WifiIntegerProperty::WifiIntegerProperty(WifiController *c, | |
| const char *name, | |
| bool ro, | |
| int elements) : | |
| IntegerProperty(name, ro, elements) { | |
| mWc = c; | |
| } | |
| WifiController::WifiStringProperty::WifiStringProperty(WifiController *c, | |
| const char *name, | |
| bool ro, int elements) : | |
| StringProperty(name, ro, elements) { | |
| mWc = c; | |
| } | |
| WifiController::WifiEnabledProperty::WifiEnabledProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "Enabled", false, 1) { | |
| } | |
| int WifiController::WifiEnabledProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->mEnabled; | |
| return 0; | |
| } | |
| int WifiController::WifiEnabledProperty::set(int idx, int value) { | |
| int rc = (value ? mWc->enable() : mWc->disable()); | |
| if (!rc) | |
| mWc->mEnabled = value; | |
| return rc; | |
| } | |
| WifiController::WifiScanOnlyProperty::WifiScanOnlyProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "ScanOnly", false, 1) { | |
| } | |
| int WifiController::WifiScanOnlyProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->mScanOnly; | |
| return 0; | |
| } | |
| int WifiController::WifiScanOnlyProperty::set(int idx, int value) { | |
| return mWc->setScanOnly(value == 1); | |
| } | |
| WifiController::WifiAllowedChannelsProperty::WifiAllowedChannelsProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "AllowedChannels", false, 1) { | |
| } | |
| int WifiController::WifiAllowedChannelsProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->mNumAllowedChannels; | |
| return 0; | |
| } | |
| int WifiController::WifiAllowedChannelsProperty::set(int idx, int value) { | |
| // XXX: IMPL | |
| errno = ENOSYS; | |
| return -1; | |
| } | |
| WifiController::WifiSupplicantStateProperty::WifiSupplicantStateProperty(WifiController *c) : | |
| WifiStringProperty(c, "SupplicantState", true, 1) { | |
| } | |
| int WifiController::WifiSupplicantStateProperty::get(int idx, char *buffer, size_t max) { | |
| if (!SupplicantState::toString(mWc->mSupplicantState, buffer, max)) | |
| return -1; | |
| return 0; | |
| } | |
| WifiController::WifiActiveScanProperty::WifiActiveScanProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "ActiveScan", false, 1) { | |
| } | |
| int WifiController::WifiActiveScanProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->mActiveScan; | |
| return 0; | |
| } | |
| int WifiController::WifiActiveScanProperty::set(int idx, int value) { | |
| return mWc->setActiveScan(value); | |
| } | |
| WifiController::WifiInterfaceProperty::WifiInterfaceProperty(WifiController *c) : | |
| WifiStringProperty(c, "Interface", true, 1) { | |
| } | |
| int WifiController::WifiInterfaceProperty::get(int idx, char *buffer, size_t max) { | |
| strncpy(buffer, (mWc->getBoundInterface() ? mWc->getBoundInterface() : "none"), max); | |
| return 0; | |
| } | |
| WifiController::WifiSearchingProperty::WifiSearchingProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "Searching", true, 1) { | |
| } | |
| int WifiController::WifiSearchingProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->mIsSupplicantSearching; | |
| return 0; | |
| } | |
| WifiController::WifiPacketFilterProperty::WifiPacketFilterProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "PacketFilter", false, 1) { | |
| } | |
| int WifiController::WifiPacketFilterProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->mPacketFilter; | |
| return 0; | |
| } | |
| int WifiController::WifiPacketFilterProperty::set(int idx, int value) { | |
| return mWc->setPacketFilter(value); | |
| } | |
| WifiController::WifiBluetoothCoexScanProperty::WifiBluetoothCoexScanProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "BluetoothCoexScan", false, 1) { | |
| } | |
| int WifiController::WifiBluetoothCoexScanProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->mBluetoothCoexScan; | |
| return 0; | |
| } | |
| int WifiController::WifiBluetoothCoexScanProperty::set(int idx, int value) { | |
| return mWc->setBluetoothCoexistenceScan(value == 1); | |
| } | |
| WifiController::WifiBluetoothCoexModeProperty::WifiBluetoothCoexModeProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "BluetoothCoexMode", false, 1) { | |
| } | |
| int WifiController::WifiBluetoothCoexModeProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->mBluetoothCoexMode; | |
| return 0; | |
| } | |
| int WifiController::WifiBluetoothCoexModeProperty::set(int idx, int value) { | |
| return mWc->setBluetoothCoexistenceMode(value); | |
| } | |
| WifiController::WifiCurrentNetworkProperty::WifiCurrentNetworkProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "CurrentlyConnectedNetworkId", true, 1) { | |
| } | |
| int WifiController::WifiCurrentNetworkProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->mCurrentlyConnectedNetworkId; | |
| return 0; | |
| } | |
| WifiController::WifiSuspendedProperty::WifiSuspendedProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "Suspended", false, 1) { | |
| } | |
| int WifiController::WifiSuspendedProperty::get(int idx, int *buffer) { | |
| *buffer = mWc->getSuspended(); | |
| return 0; | |
| } | |
| int WifiController::WifiSuspendedProperty::set(int idx, int value) { | |
| return mWc->setSuspend(value == 1); | |
| } | |
| WifiController::WifiNetCountProperty::WifiNetCountProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "NetCount", true, 1) { | |
| } | |
| int WifiController::WifiNetCountProperty::get(int idx, int *buffer) { | |
| pthread_mutex_lock(&mWc->mLock); | |
| *buffer = mWc->mSupplicant->getNetworkCount(); | |
| pthread_mutex_unlock(&mWc->mLock); | |
| return 0; | |
| } | |
| WifiController::WifiTriggerScanProperty::WifiTriggerScanProperty(WifiController *c) : | |
| WifiIntegerProperty(c, "TriggerScan", false, 1) { | |
| } | |
| int WifiController::WifiTriggerScanProperty::get(int idx, int *buffer) { | |
| // XXX: Need action type | |
| *buffer = 0; | |
| return 0; | |
| } | |
| int WifiController::WifiTriggerScanProperty::set(int idx, int value) { | |
| return mWc->triggerScan(); | |
| } | |