2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #define LOG_TAG "WifiController"
22 #include <cutils/log.h>
24 #include "Supplicant.h"
25 #include "WifiController.h"
26 #include "NetworkManager.h"
27 #include "ResponseCode.h"
28 #include "WifiNetwork.h"
29 #include "ISupplicantEventHandler.h"
30 #include "SupplicantState.h"
31 #include "SupplicantStatus.h"
32 #include "SupplicantAssociatingEvent.h"
33 #include "SupplicantAssociatedEvent.h"
34 #include "SupplicantConnectedEvent.h"
35 #include "SupplicantScanResultsEvent.h"
36 #include "SupplicantStateChangeEvent.h"
37 #include "SupplicantConnectionTimeoutEvent.h"
38 #include "SupplicantDisconnectedEvent.h"
39 #include "WifiStatusPoller.h"
41 WifiController::WifiController(PropertyManager *mPropMngr,
42 IControllerHandler *handlers,
43 char *modpath, char *modname, char *modargs) :
44 Controller("wifi", mPropMngr, handlers) {
45 strncpy(mModulePath, modpath, sizeof(mModulePath));
46 strncpy(mModuleName, modname, sizeof(mModuleName));
47 strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
49 mLatestScanResults = new ScanResultCollection();
50 pthread_mutex_init(&mLatestScanResultsLock, NULL);
52 pthread_mutex_init(&mLock, NULL);
54 mSupplicant = new Supplicant(this, this);
58 mPacketFilter = false;
59 mBluetoothCoexScan = false;
60 mBluetoothCoexMode = 0;
61 mCurrentlyConnectedNetworkId = -1;
62 mStatusPoller = new WifiStatusPoller(this);
63 mRssiEventThreshold = 5;
66 mSupplicantState = SupplicantState::UNKNOWN;
68 mStaticProperties.propEnabled = new WifiEnabledProperty(this);
69 mStaticProperties.propScanOnly = new WifiScanOnlyProperty(this);
70 mStaticProperties.propAllowedChannels = new WifiAllowedChannelsProperty(this);
72 mStaticProperties.propRssiEventThreshold =
73 new IntegerPropertyHelper("RssiEventThreshold", false, &mRssiEventThreshold);
75 mDynamicProperties.propSupplicantState = new WifiSupplicantStateProperty(this);
76 mDynamicProperties.propActiveScan = new WifiActiveScanProperty(this);
77 mDynamicProperties.propInterface = new WifiInterfaceProperty(this);
78 mDynamicProperties.propSearching = new WifiSearchingProperty(this);
79 mDynamicProperties.propPacketFilter = new WifiPacketFilterProperty(this);
80 mDynamicProperties.propBluetoothCoexScan = new WifiBluetoothCoexScanProperty(this);
81 mDynamicProperties.propBluetoothCoexMode = new WifiBluetoothCoexModeProperty(this);
82 mDynamicProperties.propCurrentNetwork = new WifiCurrentNetworkProperty(this);
84 mDynamicProperties.propRssi = new IntegerPropertyHelper("Rssi", true, &mLastRssi);
85 mDynamicProperties.propLinkSpeed = new IntegerPropertyHelper("LinkSpeed", true, &mLastLinkSpeed);
87 mDynamicProperties.propSuspended = new WifiSuspendedProperty(this);
88 mDynamicProperties.propNetCount = new WifiNetCountProperty(this);
89 mDynamicProperties.propTriggerScan = new WifiTriggerScanProperty(this);
92 int WifiController::start() {
93 mPropMngr->attachProperty("wifi", mStaticProperties.propEnabled);
94 mPropMngr->attachProperty("wifi", mStaticProperties.propScanOnly);
95 mPropMngr->attachProperty("wifi", mStaticProperties.propAllowedChannels);
96 mPropMngr->attachProperty("wifi", mStaticProperties.propRssiEventThreshold);
100 int WifiController::stop() {
101 mPropMngr->detachProperty("wifi", mStaticProperties.propEnabled);
102 mPropMngr->detachProperty("wifi", mStaticProperties.propScanOnly);
103 mPropMngr->detachProperty("wifi", mStaticProperties.propAllowedChannels);
104 mPropMngr->detachProperty("wifi", mStaticProperties.propRssiEventThreshold);
108 int WifiController::enable() {
110 if (!isPoweredUp()) {
112 sendStatusBroadcast("Powering up WiFi hardware");
114 LOGE("Powerup failed (%s)", strerror(errno));
119 if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
120 LOGI("Loading driver");
121 sendStatusBroadcast("Loading WiFi driver");
122 if (loadKernelModule(mModulePath, mModuleArgs)) {
123 LOGE("Kernel module load failed (%s)", strerror(errno));
128 if (!isFirmwareLoaded()) {
129 LOGI("Loading firmware");
130 sendStatusBroadcast("Loading WiFI firmware");
131 if (loadFirmware()) {
132 LOGE("Firmware load failed (%s)", strerror(errno));
137 if (!mSupplicant->isStarted()) {
138 LOGI("Starting WPA Supplicant");
139 sendStatusBroadcast("Starting WPA Supplicant");
140 if (mSupplicant->start()) {
141 LOGE("Supplicant start failed (%s)", strerror(errno));
142 goto out_unloadmodule;
146 if (Controller::bindInterface(mSupplicant->getInterfaceName())) {
147 LOGE("Error binding interface (%s)", strerror(errno));
148 goto out_unloadmodule;
151 if (mSupplicant->refreshNetworkList())
152 LOGW("Error getting list of networks (%s)", strerror(errno));
154 LOGW("TODO: Set # of allowed regulatory channels!");
156 mPropMngr->attachProperty("wifi", mDynamicProperties.propSupplicantState);
157 mPropMngr->attachProperty("wifi", mDynamicProperties.propActiveScan);
158 mPropMngr->attachProperty("wifi", mDynamicProperties.propInterface);
159 mPropMngr->attachProperty("wifi", mDynamicProperties.propSearching);
160 mPropMngr->attachProperty("wifi", mDynamicProperties.propPacketFilter);
161 mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
162 mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
163 mPropMngr->attachProperty("wifi", mDynamicProperties.propCurrentNetwork);
164 mPropMngr->attachProperty("wifi", mDynamicProperties.propRssi);
165 mPropMngr->attachProperty("wifi", mDynamicProperties.propLinkSpeed);
166 mPropMngr->attachProperty("wifi", mDynamicProperties.propSuspended);
167 mPropMngr->attachProperty("wifi", mDynamicProperties.propNetCount);
168 mPropMngr->attachProperty("wifi", mDynamicProperties.propTriggerScan);
170 LOGI("Enabled successfully");
174 if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
175 if (unloadKernelModule(mModuleName)) {
176 LOGE("Unable to unload module after failure!");
182 LOGE("Unable to powerdown after failure!");
187 bool WifiController::getSuspended() {
188 pthread_mutex_lock(&mLock);
190 pthread_mutex_unlock(&mLock);
194 int WifiController::setSuspend(bool suspend) {
196 pthread_mutex_lock(&mLock);
197 if (suspend == mSuspended) {
198 LOGW("Suspended state already = %d", suspend);
199 pthread_mutex_unlock(&mLock);
204 mHandlers->onControllerSuspending(this);
207 LOGD("Suspending from supplicant state %s",
208 SupplicantState::toString(mSupplicantState,
212 if (mSupplicantState != SupplicantState::IDLE) {
213 LOGD("Forcing Supplicant disconnect");
214 if (mSupplicant->disconnect()) {
215 LOGW("Error disconnecting (%s)", strerror(errno));
219 LOGD("Stopping Supplicant driver");
220 if (mSupplicant->stopDriver()) {
221 LOGE("Error stopping driver (%s)", strerror(errno));
222 pthread_mutex_unlock(&mLock);
228 if (mSupplicant->startDriver()) {
229 LOGE("Error resuming driver (%s)", strerror(errno));
230 pthread_mutex_unlock(&mLock);
233 // XXX: set regulatory max channels
235 mSupplicant->triggerScan();
237 mSupplicant->reconnect();
239 mHandlers->onControllerResumed(this);
242 mSuspended = suspend;
243 pthread_mutex_unlock(&mLock);
244 LOGD("Suspend / Resume completed");
248 void WifiController::sendStatusBroadcast(const char *msg) {
249 NetworkManager::Instance()->
251 sendBroadcast(ResponseCode::UnsolicitedInformational, msg, false);
254 int WifiController::disable() {
256 mPropMngr->detachProperty("wifi", mDynamicProperties.propSupplicantState);
257 mPropMngr->detachProperty("wifi", mDynamicProperties.propActiveScan);
258 mPropMngr->detachProperty("wifi", mDynamicProperties.propInterface);
259 mPropMngr->detachProperty("wifi", mDynamicProperties.propSearching);
260 mPropMngr->detachProperty("wifi", mDynamicProperties.propPacketFilter);
261 mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
262 mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
263 mPropMngr->detachProperty("wifi", mDynamicProperties.propCurrentNetwork);
264 mPropMngr->detachProperty("wifi", mDynamicProperties.propRssi);
265 mPropMngr->detachProperty("wifi", mDynamicProperties.propLinkSpeed);
266 mPropMngr->detachProperty("wifi", mDynamicProperties.propSuspended);
267 mPropMngr->detachProperty("wifi", mDynamicProperties.propNetCount);
269 if (mSupplicant->isStarted()) {
270 sendStatusBroadcast("Stopping WPA Supplicant");
271 if (mSupplicant->stop()) {
272 LOGE("Supplicant stop failed (%s)", strerror(errno));
276 LOGW("disable(): Supplicant not running?");
278 if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
279 sendStatusBroadcast("Unloading WiFi driver");
280 if (unloadKernelModule(mModuleName)) {
281 LOGE("Unable to unload module (%s)", strerror(errno));
287 sendStatusBroadcast("Powering down WiFi hardware");
289 LOGE("Powerdown failed (%s)", strerror(errno));
296 int WifiController::loadFirmware() {
300 int WifiController::triggerScan() {
301 pthread_mutex_lock(&mLock);
302 if (verifyNotSuspended()) {
303 pthread_mutex_unlock(&mLock);
307 switch (mSupplicantState) {
308 case SupplicantState::DISCONNECTED:
309 case SupplicantState::INACTIVE:
310 case SupplicantState::SCANNING:
311 case SupplicantState::IDLE:
314 // Switch to scan only mode
315 mSupplicant->setApScanMode(2);
319 int rc = mSupplicant->triggerScan();
320 pthread_mutex_unlock(&mLock);
324 int WifiController::setActiveScan(bool active) {
325 pthread_mutex_lock(&mLock);
326 if (mActiveScan == active) {
327 pthread_mutex_unlock(&mLock);
330 mActiveScan = active;
332 int rc = mSupplicant->setScanMode(active);
333 pthread_mutex_unlock(&mLock);
337 WifiNetwork *WifiController::createNetwork() {
338 pthread_mutex_lock(&mLock);
339 WifiNetwork *wn = mSupplicant->createNetwork();
340 pthread_mutex_unlock(&mLock);
344 int WifiController::removeNetwork(int networkId) {
345 pthread_mutex_lock(&mLock);
346 WifiNetwork *wn = mSupplicant->lookupNetwork(networkId);
349 pthread_mutex_unlock(&mLock);
352 int rc = mSupplicant->removeNetwork(wn);
353 pthread_mutex_unlock(&mLock);
357 ScanResultCollection *WifiController::createScanResults() {
358 ScanResultCollection *d = new ScanResultCollection();
359 ScanResultCollection::iterator i;
361 pthread_mutex_lock(&mLatestScanResultsLock);
362 for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i)
363 d->push_back((*i)->clone());
365 pthread_mutex_unlock(&mLatestScanResultsLock);
369 WifiNetworkCollection *WifiController::createNetworkList() {
370 return mSupplicant->createNetworkList();
373 int WifiController::setPacketFilter(bool enable) {
376 pthread_mutex_lock(&mLock);
378 rc = mSupplicant->enablePacketFilter();
380 rc = mSupplicant->disablePacketFilter();
383 mPacketFilter = enable;
384 pthread_mutex_unlock(&mLock);
388 int WifiController::setBluetoothCoexistenceScan(bool enable) {
391 pthread_mutex_lock(&mLock);
394 rc = mSupplicant->enableBluetoothCoexistenceScan();
396 rc = mSupplicant->disableBluetoothCoexistenceScan();
399 mBluetoothCoexScan = enable;
400 pthread_mutex_unlock(&mLock);
404 int WifiController::setScanOnly(bool scanOnly) {
405 pthread_mutex_lock(&mLock);
406 int rc = mSupplicant->setApScanMode((scanOnly ? 2 : 1));
408 mScanOnly = scanOnly;
411 mSupplicant->disconnect();
413 mSupplicant->reconnect();
415 pthread_mutex_unlock(&mLock);
419 int WifiController::setBluetoothCoexistenceMode(int mode) {
420 pthread_mutex_lock(&mLock);
421 int rc = mSupplicant->setBluetoothCoexistenceMode(mode);
423 mBluetoothCoexMode = mode;
424 pthread_mutex_unlock(&mLock);
428 void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) {
429 LOGD("onAssociatingEvent(%s, %s, %d)",
430 (evt->getBssid() ? evt->getBssid() : "n/a"),
431 (evt->getSsid() ? evt->getSsid() : "n/a"),
435 void WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) {
436 LOGD("onAssociatedEvent(%s)", evt->getBssid());
439 void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
440 LOGD("onConnectedEvent(%s, %d)", evt->getBssid(), evt->getReassociated());
441 SupplicantStatus *ss = mSupplicant->getStatus();
444 if (ss->getWpaState() != SupplicantState::COMPLETED) {
447 LOGW("onConnected() with SupplicantState = %s!",
448 SupplicantState::toString(ss->getWpaState(), tmp,
453 if (ss->getId() == -1) {
454 LOGW("onConnected() with id = -1!");
458 mCurrentlyConnectedNetworkId = ss->getId();
459 if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) {
460 LOGW("Error looking up connected network id %d (%s)",
461 ss->getId(), strerror(errno));
466 mHandlers->onInterfaceConnected(this);
469 void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
472 if (!(reply = (char *) malloc(4096))) {
473 LOGE("Out of memory");
477 mNumScanResultsSinceLastStateChange++;
478 if (mNumScanResultsSinceLastStateChange >= 3)
479 mIsSupplicantSearching = false;
483 if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
484 LOGW("onScanResultsEvent: Error getting scan results (%s)",
490 pthread_mutex_lock(&mLatestScanResultsLock);
491 if (!mLatestScanResults->empty()) {
492 ScanResultCollection::iterator i;
494 for (i = mLatestScanResults->begin();
495 i !=mLatestScanResults->end(); ++i) {
498 mLatestScanResults->clear();
502 char *linep_next = NULL;
504 if (!strtok_r(reply, "\n", &linep_next)) {
506 pthread_mutex_unlock(&mLatestScanResultsLock);
510 while((linep = strtok_r(NULL, "\n", &linep_next)))
511 mLatestScanResults->push_back(new ScanResult(linep));
513 // Switch handling of scan results back to normal mode
514 mSupplicant->setApScanMode(1);
517 asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size());
518 NetworkManager::Instance()->getBroadcaster()->
519 sendBroadcast(ResponseCode::ScanResultsReady,
522 pthread_mutex_unlock(&mLatestScanResultsLock);
526 void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) {
530 if (evt->getState() == mSupplicantState)
533 LOGD("onStateChangeEvent(%s -> %s)",
534 SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)),
535 SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2)));
537 if (evt->getState() != SupplicantState::SCANNING) {
538 mIsSupplicantSearching = true;
539 mNumScanResultsSinceLastStateChange = 0;
544 "Supplicant state changed from %d (%s) -> %d (%s)",
545 mSupplicantState, tmp, evt->getState(), tmp2);
547 mSupplicantState = evt->getState();
549 if (mSupplicantState == SupplicantState::COMPLETED) {
550 mStatusPoller->start();
551 } else if (mStatusPoller->isStarted()) {
552 mStatusPoller->stop();
555 NetworkManager::Instance()->getBroadcaster()->
556 sendBroadcast(ResponseCode::SupplicantStateChange,
561 void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
562 LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid());
565 void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
566 mCurrentlyConnectedNetworkId = -1;
567 mHandlers->onInterfaceDisconnected(this);
571 void WifiController::onTerminatingEvent(SupplicantEvent *evt) {
572 LOGD("onTerminatingEvent(%s)", evt->getEvent());
575 void WifiController::onPasswordChangedEvent(SupplicantEvent *evt) {
576 LOGD("onPasswordChangedEvent(%s)", evt->getEvent());
579 void WifiController::onEapNotificationEvent(SupplicantEvent *evt) {
580 LOGD("onEapNotificationEvent(%s)", evt->getEvent());
583 void WifiController::onEapStartedEvent(SupplicantEvent *evt) {
584 LOGD("onEapStartedEvent(%s)", evt->getEvent());
587 void WifiController::onEapMethodEvent(SupplicantEvent *evt) {
588 LOGD("onEapMethodEvent(%s)", evt->getEvent());
591 void WifiController::onEapSuccessEvent(SupplicantEvent *evt) {
592 LOGD("onEapSuccessEvent(%s)", evt->getEvent());
595 void WifiController::onEapFailureEvent(SupplicantEvent *evt) {
596 LOGD("onEapFailureEvent(%s)", evt->getEvent());
599 void WifiController::onLinkSpeedEvent(SupplicantEvent *evt) {
600 LOGD("onLinkSpeedEvent(%s)", evt->getEvent());
603 void WifiController::onDriverStateEvent(SupplicantEvent *evt) {
604 LOGD("onDriverStateEvent(%s)", evt->getEvent());
608 void WifiController::onStatusPollInterval() {
609 pthread_mutex_lock(&mLock);
611 if (mSupplicant->getRssi(&rssi)) {
612 LOGE("Failed to get rssi (%s)", strerror(errno));
613 pthread_mutex_unlock(&mLock);
617 if (abs(mLastRssi - rssi) > mRssiEventThreshold) {
619 asprintf(&tmp3, "RSSI changed from %d -> %d",
622 NetworkManager::Instance()->getBroadcaster()->
623 sendBroadcast(ResponseCode::RssiChange,
628 int linkspeed = mSupplicant->getLinkSpeed();
629 if (linkspeed != mLastLinkSpeed) {
631 asprintf(&tmp3, "Link speed changed from %d -> %d",
632 mLastLinkSpeed, linkspeed);
633 mLastLinkSpeed = linkspeed;
634 NetworkManager::Instance()->getBroadcaster()->
635 sendBroadcast(ResponseCode::LinkSpeedChange,
640 pthread_mutex_unlock(&mLock);
643 int WifiController::verifyNotSuspended() {
652 * Property inner classes
655 WifiController::WifiIntegerProperty::WifiIntegerProperty(WifiController *c,
659 IntegerProperty(name, ro, elements) {
663 WifiController::WifiStringProperty::WifiStringProperty(WifiController *c,
665 bool ro, int elements) :
666 StringProperty(name, ro, elements) {
670 WifiController::WifiEnabledProperty::WifiEnabledProperty(WifiController *c) :
671 WifiIntegerProperty(c, "Enabled", false, 1) {
674 int WifiController::WifiEnabledProperty::get(int idx, int *buffer) {
675 *buffer = mWc->mEnabled;
678 int WifiController::WifiEnabledProperty::set(int idx, int value) {
679 int rc = (value ? mWc->enable() : mWc->disable());
681 mWc->mEnabled = value;
685 WifiController::WifiScanOnlyProperty::WifiScanOnlyProperty(WifiController *c) :
686 WifiIntegerProperty(c, "ScanOnly", false, 1) {
688 int WifiController::WifiScanOnlyProperty::get(int idx, int *buffer) {
689 *buffer = mWc->mScanOnly;
692 int WifiController::WifiScanOnlyProperty::set(int idx, int value) {
693 return mWc->setScanOnly(value == 1);
696 WifiController::WifiAllowedChannelsProperty::WifiAllowedChannelsProperty(WifiController *c) :
697 WifiIntegerProperty(c, "AllowedChannels", false, 1) {
699 int WifiController::WifiAllowedChannelsProperty::get(int idx, int *buffer) {
700 *buffer = mWc->mNumAllowedChannels;
703 int WifiController::WifiAllowedChannelsProperty::set(int idx, int value) {
709 WifiController::WifiSupplicantStateProperty::WifiSupplicantStateProperty(WifiController *c) :
710 WifiStringProperty(c, "SupplicantState", true, 1) {
712 int WifiController::WifiSupplicantStateProperty::get(int idx, char *buffer, size_t max) {
713 if (!SupplicantState::toString(mWc->mSupplicantState, buffer, max))
718 WifiController::WifiActiveScanProperty::WifiActiveScanProperty(WifiController *c) :
719 WifiIntegerProperty(c, "ActiveScan", false, 1) {
721 int WifiController::WifiActiveScanProperty::get(int idx, int *buffer) {
722 *buffer = mWc->mActiveScan;
725 int WifiController::WifiActiveScanProperty::set(int idx, int value) {
726 return mWc->setActiveScan(value);
729 WifiController::WifiInterfaceProperty::WifiInterfaceProperty(WifiController *c) :
730 WifiStringProperty(c, "Interface", true, 1) {
732 int WifiController::WifiInterfaceProperty::get(int idx, char *buffer, size_t max) {
733 strncpy(buffer, (mWc->getBoundInterface() ? mWc->getBoundInterface() : "none"), max);
737 WifiController::WifiSearchingProperty::WifiSearchingProperty(WifiController *c) :
738 WifiIntegerProperty(c, "Searching", true, 1) {
740 int WifiController::WifiSearchingProperty::get(int idx, int *buffer) {
741 *buffer = mWc->mIsSupplicantSearching;
745 WifiController::WifiPacketFilterProperty::WifiPacketFilterProperty(WifiController *c) :
746 WifiIntegerProperty(c, "PacketFilter", false, 1) {
748 int WifiController::WifiPacketFilterProperty::get(int idx, int *buffer) {
749 *buffer = mWc->mPacketFilter;
752 int WifiController::WifiPacketFilterProperty::set(int idx, int value) {
753 return mWc->setPacketFilter(value);
756 WifiController::WifiBluetoothCoexScanProperty::WifiBluetoothCoexScanProperty(WifiController *c) :
757 WifiIntegerProperty(c, "BluetoothCoexScan", false, 1) {
759 int WifiController::WifiBluetoothCoexScanProperty::get(int idx, int *buffer) {
760 *buffer = mWc->mBluetoothCoexScan;
763 int WifiController::WifiBluetoothCoexScanProperty::set(int idx, int value) {
764 return mWc->setBluetoothCoexistenceScan(value == 1);
767 WifiController::WifiBluetoothCoexModeProperty::WifiBluetoothCoexModeProperty(WifiController *c) :
768 WifiIntegerProperty(c, "BluetoothCoexMode", false, 1) {
770 int WifiController::WifiBluetoothCoexModeProperty::get(int idx, int *buffer) {
771 *buffer = mWc->mBluetoothCoexMode;
774 int WifiController::WifiBluetoothCoexModeProperty::set(int idx, int value) {
775 return mWc->setBluetoothCoexistenceMode(value);
778 WifiController::WifiCurrentNetworkProperty::WifiCurrentNetworkProperty(WifiController *c) :
779 WifiIntegerProperty(c, "CurrentlyConnectedNetworkId", true, 1) {
781 int WifiController::WifiCurrentNetworkProperty::get(int idx, int *buffer) {
782 *buffer = mWc->mCurrentlyConnectedNetworkId;
786 WifiController::WifiSuspendedProperty::WifiSuspendedProperty(WifiController *c) :
787 WifiIntegerProperty(c, "Suspended", false, 1) {
789 int WifiController::WifiSuspendedProperty::get(int idx, int *buffer) {
790 *buffer = mWc->getSuspended();
793 int WifiController::WifiSuspendedProperty::set(int idx, int value) {
794 return mWc->setSuspend(value == 1);
797 WifiController::WifiNetCountProperty::WifiNetCountProperty(WifiController *c) :
798 WifiIntegerProperty(c, "NetCount", true, 1) {
800 int WifiController::WifiNetCountProperty::get(int idx, int *buffer) {
801 pthread_mutex_lock(&mWc->mLock);
802 *buffer = mWc->mSupplicant->getNetworkCount();
803 pthread_mutex_unlock(&mWc->mLock);
807 WifiController::WifiTriggerScanProperty::WifiTriggerScanProperty(WifiController *c) :
808 WifiIntegerProperty(c, "TriggerScan", false, 1) {
810 int WifiController::WifiTriggerScanProperty::get(int idx, int *buffer) {
811 // XXX: Need action type
816 int WifiController::WifiTriggerScanProperty::set(int idx, int value) {
817 return mWc->triggerScan();