• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 
17 #include <stdlib.h>
18 #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"
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"
40 
WifiController(PropertyManager * mPropMngr,IControllerHandler * handlers,char * modpath,char * modname,char * modargs)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));
48 
49     mLatestScanResults = new ScanResultCollection();
50     pthread_mutex_init(&mLatestScanResultsLock, NULL);
51 
52     pthread_mutex_init(&mLock, NULL);
53 
54     mSupplicant = new Supplicant(this, this);
55     mActiveScan = false;
56     mEnabled = false;
57     mScanOnly = false;
58     mPacketFilter = false;
59     mBluetoothCoexScan = false;
60     mBluetoothCoexMode = 0;
61     mCurrentlyConnectedNetworkId = -1;
62     mStatusPoller = new WifiStatusPoller(this);
63     mRssiEventThreshold = 5;
64     mLastLinkSpeed = 0;
65 
66     mSupplicantState = SupplicantState::UNKNOWN;
67 
68     mStaticProperties.propEnabled = new WifiEnabledProperty(this);
69     mStaticProperties.propScanOnly = new WifiScanOnlyProperty(this);
70     mStaticProperties.propAllowedChannels = new WifiAllowedChannelsProperty(this);
71 
72     mStaticProperties.propRssiEventThreshold =
73             new IntegerPropertyHelper("RssiEventThreshold", false, &mRssiEventThreshold);
74 
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);
83 
84     mDynamicProperties.propRssi = new IntegerPropertyHelper("Rssi", true, &mLastRssi);
85     mDynamicProperties.propLinkSpeed = new IntegerPropertyHelper("LinkSpeed", true, &mLastLinkSpeed);
86 
87     mDynamicProperties.propSuspended = new WifiSuspendedProperty(this);
88     mDynamicProperties.propNetCount = new WifiNetCountProperty(this);
89     mDynamicProperties.propTriggerScan = new WifiTriggerScanProperty(this);
90 }
91 
start()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);
97     return 0;
98 }
99 
stop()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);
105     return 0;
106 }
107 
enable()108 int WifiController::enable() {
109 
110     if (!isPoweredUp()) {
111         LOGI("Powering up");
112         sendStatusBroadcast("Powering up WiFi hardware");
113         if (powerUp()) {
114             LOGE("Powerup failed (%s)", strerror(errno));
115             return -1;
116         }
117     }
118 
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));
124             goto out_powerdown;
125         }
126     }
127 
128     if (!isFirmwareLoaded()) {
129         LOGI("Loading firmware");
130         sendStatusBroadcast("Loading WiFI firmware");
131         if (loadFirmware()) {
132             LOGE("Firmware load failed (%s)", strerror(errno));
133             goto out_powerdown;
134         }
135     }
136 
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;
143         }
144     }
145 
146     if (Controller::bindInterface(mSupplicant->getInterfaceName())) {
147         LOGE("Error binding interface (%s)", strerror(errno));
148         goto out_unloadmodule;
149     }
150 
151     if (mSupplicant->refreshNetworkList())
152         LOGW("Error getting list of networks (%s)", strerror(errno));
153 
154     LOGW("TODO: Set # of allowed regulatory channels!");
155 
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);
169 
170     LOGI("Enabled successfully");
171     return 0;
172 
173 out_unloadmodule:
174     if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
175         if (unloadKernelModule(mModuleName)) {
176             LOGE("Unable to unload module after failure!");
177         }
178     }
179 
180 out_powerdown:
181     if (powerDown()) {
182         LOGE("Unable to powerdown after failure!");
183     }
184     return -1;
185 }
186 
getSuspended()187 bool WifiController::getSuspended() {
188     pthread_mutex_lock(&mLock);
189     bool r = mSuspended;
190     pthread_mutex_unlock(&mLock);
191     return r;
192 }
193 
setSuspend(bool suspend)194 int WifiController::setSuspend(bool suspend) {
195 
196     pthread_mutex_lock(&mLock);
197     if (suspend == mSuspended) {
198         LOGW("Suspended state already = %d", suspend);
199         pthread_mutex_unlock(&mLock);
200         return 0;
201     }
202 
203     if (suspend) {
204         mHandlers->onControllerSuspending(this);
205 
206         char tmp[80];
207         LOGD("Suspending from supplicant state %s",
208              SupplicantState::toString(mSupplicantState,
209                                        tmp,
210                                        sizeof(tmp)));
211 
212         if (mSupplicantState != SupplicantState::IDLE) {
213             LOGD("Forcing Supplicant disconnect");
214             if (mSupplicant->disconnect()) {
215                 LOGW("Error disconnecting (%s)", strerror(errno));
216             }
217         }
218 
219         LOGD("Stopping Supplicant driver");
220         if (mSupplicant->stopDriver()) {
221             LOGE("Error stopping driver (%s)", strerror(errno));
222             pthread_mutex_unlock(&mLock);
223             return -1;
224         }
225     } else {
226         LOGD("Resuming");
227 
228         if (mSupplicant->startDriver()) {
229             LOGE("Error resuming driver (%s)", strerror(errno));
230             pthread_mutex_unlock(&mLock);
231             return -1;
232         }
233         // XXX: set regulatory max channels
234         if (mScanOnly)
235             mSupplicant->triggerScan();
236         else
237             mSupplicant->reconnect();
238 
239         mHandlers->onControllerResumed(this);
240     }
241 
242     mSuspended = suspend;
243     pthread_mutex_unlock(&mLock);
244     LOGD("Suspend / Resume completed");
245     return 0;
246 }
247 
sendStatusBroadcast(const char * msg)248 void WifiController::sendStatusBroadcast(const char *msg) {
249     NetworkManager::Instance()->
250                     getBroadcaster()->
251                     sendBroadcast(ResponseCode::UnsolicitedInformational, msg, false);
252 }
253 
disable()254 int WifiController::disable() {
255 
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);
268 
269     if (mSupplicant->isStarted()) {
270         sendStatusBroadcast("Stopping WPA Supplicant");
271         if (mSupplicant->stop()) {
272             LOGE("Supplicant stop failed (%s)", strerror(errno));
273             return -1;
274         }
275     } else
276         LOGW("disable(): Supplicant not running?");
277 
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));
282             return -1;
283         }
284     }
285 
286     if (isPoweredUp()) {
287         sendStatusBroadcast("Powering down WiFi hardware");
288         if (powerDown()) {
289             LOGE("Powerdown failed (%s)", strerror(errno));
290             return -1;
291         }
292     }
293     return 0;
294 }
295 
loadFirmware()296 int WifiController::loadFirmware() {
297     return 0;
298 }
299 
triggerScan()300 int WifiController::triggerScan() {
301     pthread_mutex_lock(&mLock);
302     if (verifyNotSuspended()) {
303         pthread_mutex_unlock(&mLock);
304         return -1;
305     }
306 
307     switch (mSupplicantState) {
308         case SupplicantState::DISCONNECTED:
309         case SupplicantState::INACTIVE:
310         case SupplicantState::SCANNING:
311         case SupplicantState::IDLE:
312             break;
313         default:
314             // Switch to scan only mode
315             mSupplicant->setApScanMode(2);
316             break;
317     }
318 
319     int rc = mSupplicant->triggerScan();
320     pthread_mutex_unlock(&mLock);
321     return rc;
322 }
323 
setActiveScan(bool active)324 int WifiController::setActiveScan(bool active) {
325     pthread_mutex_lock(&mLock);
326     if (mActiveScan == active) {
327         pthread_mutex_unlock(&mLock);
328         return 0;
329     }
330     mActiveScan = active;
331 
332     int rc = mSupplicant->setScanMode(active);
333     pthread_mutex_unlock(&mLock);
334     return rc;
335 }
336 
createNetwork()337 WifiNetwork *WifiController::createNetwork() {
338     pthread_mutex_lock(&mLock);
339     WifiNetwork *wn = mSupplicant->createNetwork();
340     pthread_mutex_unlock(&mLock);
341     return wn;
342 }
343 
removeNetwork(int networkId)344 int WifiController::removeNetwork(int networkId) {
345     pthread_mutex_lock(&mLock);
346     WifiNetwork *wn = mSupplicant->lookupNetwork(networkId);
347 
348     if (!wn) {
349         pthread_mutex_unlock(&mLock);
350         return -1;
351     }
352     int rc = mSupplicant->removeNetwork(wn);
353     pthread_mutex_unlock(&mLock);
354     return rc;
355 }
356 
createScanResults()357 ScanResultCollection *WifiController::createScanResults() {
358     ScanResultCollection *d = new ScanResultCollection();
359     ScanResultCollection::iterator i;
360 
361     pthread_mutex_lock(&mLatestScanResultsLock);
362     for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i)
363         d->push_back((*i)->clone());
364 
365     pthread_mutex_unlock(&mLatestScanResultsLock);
366     return d;
367 }
368 
createNetworkList()369 WifiNetworkCollection *WifiController::createNetworkList() {
370     return mSupplicant->createNetworkList();
371 }
372 
setPacketFilter(bool enable)373 int WifiController::setPacketFilter(bool enable) {
374     int rc;
375 
376     pthread_mutex_lock(&mLock);
377     if (enable)
378         rc = mSupplicant->enablePacketFilter();
379     else
380         rc = mSupplicant->disablePacketFilter();
381 
382     if (!rc)
383         mPacketFilter = enable;
384     pthread_mutex_unlock(&mLock);
385     return rc;
386 }
387 
setBluetoothCoexistenceScan(bool enable)388 int WifiController::setBluetoothCoexistenceScan(bool enable) {
389     int rc;
390 
391     pthread_mutex_lock(&mLock);
392 
393     if (enable)
394         rc = mSupplicant->enableBluetoothCoexistenceScan();
395     else
396         rc = mSupplicant->disableBluetoothCoexistenceScan();
397 
398     if (!rc)
399         mBluetoothCoexScan = enable;
400     pthread_mutex_unlock(&mLock);
401     return rc;
402 }
403 
setScanOnly(bool scanOnly)404 int WifiController::setScanOnly(bool scanOnly) {
405     pthread_mutex_lock(&mLock);
406     int rc = mSupplicant->setApScanMode((scanOnly ? 2 : 1));
407     if (!rc)
408         mScanOnly = scanOnly;
409     if (!mSuspended) {
410         if (scanOnly)
411             mSupplicant->disconnect();
412         else
413             mSupplicant->reconnect();
414     }
415     pthread_mutex_unlock(&mLock);
416     return rc;
417 }
418 
setBluetoothCoexistenceMode(int mode)419 int WifiController::setBluetoothCoexistenceMode(int mode) {
420     pthread_mutex_lock(&mLock);
421     int rc = mSupplicant->setBluetoothCoexistenceMode(mode);
422     if (!rc)
423         mBluetoothCoexMode = mode;
424     pthread_mutex_unlock(&mLock);
425     return rc;
426 }
427 
onAssociatingEvent(SupplicantAssociatingEvent * evt)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"),
432          evt->getFreq());
433 }
434 
onAssociatedEvent(SupplicantAssociatedEvent * evt)435 void WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) {
436     LOGD("onAssociatedEvent(%s)", evt->getBssid());
437 }
438 
onConnectedEvent(SupplicantConnectedEvent * evt)439 void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
440     LOGD("onConnectedEvent(%s, %d)", evt->getBssid(), evt->getReassociated());
441     SupplicantStatus *ss = mSupplicant->getStatus();
442     WifiNetwork *wn;
443 
444     if (ss->getWpaState() != SupplicantState::COMPLETED) {
445         char tmp[32];
446 
447         LOGW("onConnected() with SupplicantState = %s!",
448              SupplicantState::toString(ss->getWpaState(), tmp,
449              sizeof(tmp)));
450         return;
451     }
452 
453     if (ss->getId() == -1) {
454         LOGW("onConnected() with id = -1!");
455         return;
456     }
457 
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));
462         return;
463     }
464 
465     delete ss;
466     mHandlers->onInterfaceConnected(this);
467 }
468 
onScanResultsEvent(SupplicantScanResultsEvent * evt)469 void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
470     char *reply;
471 
472     if (!(reply = (char *) malloc(4096))) {
473         LOGE("Out of memory");
474         return;
475     }
476 
477     mNumScanResultsSinceLastStateChange++;
478     if (mNumScanResultsSinceLastStateChange >= 3)
479         mIsSupplicantSearching = false;
480 
481     size_t len = 4096;
482 
483     if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
484         LOGW("onScanResultsEvent: Error getting scan results (%s)",
485              strerror(errno));
486         free(reply);
487         return;
488     }
489 
490     pthread_mutex_lock(&mLatestScanResultsLock);
491     if (!mLatestScanResults->empty()) {
492         ScanResultCollection::iterator i;
493 
494         for (i = mLatestScanResults->begin();
495              i !=mLatestScanResults->end(); ++i) {
496             delete *i;
497         }
498         mLatestScanResults->clear();
499     }
500 
501     char *linep;
502     char *linep_next = NULL;
503 
504     if (!strtok_r(reply, "\n", &linep_next)) {
505         free(reply);
506         pthread_mutex_unlock(&mLatestScanResultsLock);
507         return;
508     }
509 
510     while((linep = strtok_r(NULL, "\n", &linep_next)))
511         mLatestScanResults->push_back(new ScanResult(linep));
512 
513     // Switch handling of scan results back to normal mode
514     mSupplicant->setApScanMode(1);
515 
516     char *tmp;
517     asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size());
518     NetworkManager::Instance()->getBroadcaster()->
519                                 sendBroadcast(ResponseCode::ScanResultsReady,
520                                               tmp, false);
521     free(tmp);
522     pthread_mutex_unlock(&mLatestScanResultsLock);
523     free(reply);
524 }
525 
onStateChangeEvent(SupplicantStateChangeEvent * evt)526 void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) {
527     char tmp[32];
528     char tmp2[32];
529 
530     if (evt->getState() == mSupplicantState)
531         return;
532 
533     LOGD("onStateChangeEvent(%s -> %s)",
534          SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)),
535          SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2)));
536 
537     if (evt->getState() != SupplicantState::SCANNING) {
538         mIsSupplicantSearching = true;
539         mNumScanResultsSinceLastStateChange = 0;
540     }
541 
542     char *tmp3;
543     asprintf(&tmp3,
544              "Supplicant state changed from %d (%s) -> %d (%s)",
545              mSupplicantState, tmp, evt->getState(), tmp2);
546 
547     mSupplicantState = evt->getState();
548 
549     if (mSupplicantState == SupplicantState::COMPLETED) {
550         mStatusPoller->start();
551     } else if (mStatusPoller->isStarted()) {
552         mStatusPoller->stop();
553     }
554 
555     NetworkManager::Instance()->getBroadcaster()->
556                                 sendBroadcast(ResponseCode::SupplicantStateChange,
557                                               tmp3, false);
558     free(tmp3);
559 }
560 
onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent * evt)561 void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
562     LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid());
563 }
564 
onDisconnectedEvent(SupplicantDisconnectedEvent * evt)565 void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
566     mCurrentlyConnectedNetworkId = -1;
567     mHandlers->onInterfaceDisconnected(this);
568 }
569 
570 #if 0
571 void WifiController::onTerminatingEvent(SupplicantEvent *evt) {
572     LOGD("onTerminatingEvent(%s)", evt->getEvent());
573 }
574 
575 void WifiController::onPasswordChangedEvent(SupplicantEvent *evt) {
576     LOGD("onPasswordChangedEvent(%s)", evt->getEvent());
577 }
578 
579 void WifiController::onEapNotificationEvent(SupplicantEvent *evt) {
580     LOGD("onEapNotificationEvent(%s)", evt->getEvent());
581 }
582 
583 void WifiController::onEapStartedEvent(SupplicantEvent *evt) {
584     LOGD("onEapStartedEvent(%s)", evt->getEvent());
585 }
586 
587 void WifiController::onEapMethodEvent(SupplicantEvent *evt) {
588     LOGD("onEapMethodEvent(%s)", evt->getEvent());
589 }
590 
591 void WifiController::onEapSuccessEvent(SupplicantEvent *evt) {
592     LOGD("onEapSuccessEvent(%s)", evt->getEvent());
593 }
594 
595 void WifiController::onEapFailureEvent(SupplicantEvent *evt) {
596     LOGD("onEapFailureEvent(%s)", evt->getEvent());
597 }
598 
599 void WifiController::onLinkSpeedEvent(SupplicantEvent *evt) {
600     LOGD("onLinkSpeedEvent(%s)", evt->getEvent());
601 }
602 
603 void WifiController::onDriverStateEvent(SupplicantEvent *evt) {
604     LOGD("onDriverStateEvent(%s)", evt->getEvent());
605 }
606 #endif
607 
onStatusPollInterval()608 void WifiController::onStatusPollInterval() {
609     pthread_mutex_lock(&mLock);
610     int rssi;
611     if (mSupplicant->getRssi(&rssi)) {
612         LOGE("Failed to get rssi (%s)", strerror(errno));
613         pthread_mutex_unlock(&mLock);
614         return;
615     }
616 
617     if (abs(mLastRssi - rssi) > mRssiEventThreshold) {
618         char *tmp3;
619         asprintf(&tmp3, "RSSI changed from %d -> %d",
620                  mLastRssi, rssi);
621         mLastRssi = rssi;
622         NetworkManager::Instance()->getBroadcaster()->
623                                sendBroadcast(ResponseCode::RssiChange,
624                                              tmp3, false);
625         free(tmp3);
626     }
627 
628     int linkspeed = mSupplicant->getLinkSpeed();
629     if (linkspeed != mLastLinkSpeed) {
630         char *tmp3;
631         asprintf(&tmp3, "Link speed changed from %d -> %d",
632                  mLastLinkSpeed, linkspeed);
633         mLastLinkSpeed = linkspeed;
634         NetworkManager::Instance()->getBroadcaster()->
635                                sendBroadcast(ResponseCode::LinkSpeedChange,
636                                              tmp3, false);
637         free(tmp3);
638 
639     }
640     pthread_mutex_unlock(&mLock);
641 }
642 
verifyNotSuspended()643 int WifiController::verifyNotSuspended() {
644     if (mSuspended) {
645         errno = ESHUTDOWN;
646         return -1;
647     }
648     return 0;
649 }
650 
651 /*
652  * Property inner classes
653  */
654 
WifiIntegerProperty(WifiController * c,const char * name,bool ro,int elements)655 WifiController::WifiIntegerProperty::WifiIntegerProperty(WifiController *c,
656                                                          const char *name,
657                                                          bool ro,
658                                                          int elements) :
659                 IntegerProperty(name, ro, elements) {
660     mWc = c;
661 }
662 
WifiStringProperty(WifiController * c,const char * name,bool ro,int elements)663 WifiController::WifiStringProperty::WifiStringProperty(WifiController *c,
664                                                        const char *name,
665                                                        bool ro, int elements) :
666                 StringProperty(name, ro, elements) {
667     mWc = c;
668 }
669 
WifiEnabledProperty(WifiController * c)670 WifiController::WifiEnabledProperty::WifiEnabledProperty(WifiController *c) :
671                 WifiIntegerProperty(c, "Enabled", false, 1) {
672 }
673 
get(int idx,int * buffer)674 int WifiController::WifiEnabledProperty::get(int idx, int *buffer) {
675     *buffer = mWc->mEnabled;
676     return 0;
677 }
set(int idx,int value)678 int WifiController::WifiEnabledProperty::set(int idx, int value) {
679     int rc = (value ? mWc->enable() : mWc->disable());
680     if (!rc)
681         mWc->mEnabled = value;
682     return rc;
683 }
684 
WifiScanOnlyProperty(WifiController * c)685 WifiController::WifiScanOnlyProperty::WifiScanOnlyProperty(WifiController *c) :
686                 WifiIntegerProperty(c, "ScanOnly", false, 1) {
687 }
get(int idx,int * buffer)688 int WifiController::WifiScanOnlyProperty::get(int idx, int *buffer) {
689     *buffer = mWc->mScanOnly;
690     return 0;
691 }
set(int idx,int value)692 int WifiController::WifiScanOnlyProperty::set(int idx, int value) {
693     return mWc->setScanOnly(value == 1);
694 }
695 
WifiAllowedChannelsProperty(WifiController * c)696 WifiController::WifiAllowedChannelsProperty::WifiAllowedChannelsProperty(WifiController *c) :
697                 WifiIntegerProperty(c, "AllowedChannels", false, 1) {
698 }
get(int idx,int * buffer)699 int WifiController::WifiAllowedChannelsProperty::get(int idx, int *buffer) {
700     *buffer = mWc->mNumAllowedChannels;
701     return 0;
702 }
set(int idx,int value)703 int WifiController::WifiAllowedChannelsProperty::set(int idx, int value) {
704     // XXX: IMPL
705     errno = ENOSYS;
706     return -1;
707 }
708 
WifiSupplicantStateProperty(WifiController * c)709 WifiController::WifiSupplicantStateProperty::WifiSupplicantStateProperty(WifiController *c) :
710                 WifiStringProperty(c, "SupplicantState", true, 1) {
711 }
get(int idx,char * buffer,size_t max)712 int WifiController::WifiSupplicantStateProperty::get(int idx, char *buffer, size_t max) {
713     if (!SupplicantState::toString(mWc->mSupplicantState, buffer, max))
714         return -1;
715     return 0;
716 }
717 
WifiActiveScanProperty(WifiController * c)718 WifiController::WifiActiveScanProperty::WifiActiveScanProperty(WifiController *c) :
719                 WifiIntegerProperty(c, "ActiveScan", false, 1) {
720 }
get(int idx,int * buffer)721 int WifiController::WifiActiveScanProperty::get(int idx, int *buffer) {
722     *buffer = mWc->mActiveScan;
723     return 0;
724 }
set(int idx,int value)725 int WifiController::WifiActiveScanProperty::set(int idx, int value) {
726     return mWc->setActiveScan(value);
727 }
728 
WifiInterfaceProperty(WifiController * c)729 WifiController::WifiInterfaceProperty::WifiInterfaceProperty(WifiController *c) :
730                 WifiStringProperty(c, "Interface", true, 1) {
731 }
get(int idx,char * buffer,size_t max)732 int WifiController::WifiInterfaceProperty::get(int idx, char *buffer, size_t max) {
733     strncpy(buffer, (mWc->getBoundInterface() ? mWc->getBoundInterface() : "none"), max);
734     return 0;
735 }
736 
WifiSearchingProperty(WifiController * c)737 WifiController::WifiSearchingProperty::WifiSearchingProperty(WifiController *c) :
738                 WifiIntegerProperty(c, "Searching", true, 1) {
739 }
get(int idx,int * buffer)740 int WifiController::WifiSearchingProperty::get(int idx, int *buffer) {
741     *buffer = mWc->mIsSupplicantSearching;
742     return 0;
743 }
744 
WifiPacketFilterProperty(WifiController * c)745 WifiController::WifiPacketFilterProperty::WifiPacketFilterProperty(WifiController *c) :
746                 WifiIntegerProperty(c, "PacketFilter", false, 1) {
747 }
get(int idx,int * buffer)748 int WifiController::WifiPacketFilterProperty::get(int idx, int *buffer) {
749     *buffer = mWc->mPacketFilter;
750     return 0;
751 }
set(int idx,int value)752 int WifiController::WifiPacketFilterProperty::set(int idx, int value) {
753     return mWc->setPacketFilter(value);
754 }
755 
WifiBluetoothCoexScanProperty(WifiController * c)756 WifiController::WifiBluetoothCoexScanProperty::WifiBluetoothCoexScanProperty(WifiController *c) :
757                 WifiIntegerProperty(c, "BluetoothCoexScan", false, 1) {
758 }
get(int idx,int * buffer)759 int WifiController::WifiBluetoothCoexScanProperty::get(int idx, int *buffer) {
760     *buffer = mWc->mBluetoothCoexScan;
761     return 0;
762 }
set(int idx,int value)763 int WifiController::WifiBluetoothCoexScanProperty::set(int idx, int value) {
764     return mWc->setBluetoothCoexistenceScan(value == 1);
765 }
766 
WifiBluetoothCoexModeProperty(WifiController * c)767 WifiController::WifiBluetoothCoexModeProperty::WifiBluetoothCoexModeProperty(WifiController *c) :
768                 WifiIntegerProperty(c, "BluetoothCoexMode", false, 1) {
769 }
get(int idx,int * buffer)770 int WifiController::WifiBluetoothCoexModeProperty::get(int idx, int *buffer) {
771     *buffer = mWc->mBluetoothCoexMode;
772     return 0;
773 }
set(int idx,int value)774 int WifiController::WifiBluetoothCoexModeProperty::set(int idx, int value) {
775     return mWc->setBluetoothCoexistenceMode(value);
776 }
777 
WifiCurrentNetworkProperty(WifiController * c)778 WifiController::WifiCurrentNetworkProperty::WifiCurrentNetworkProperty(WifiController *c) :
779                 WifiIntegerProperty(c, "CurrentlyConnectedNetworkId", true, 1) {
780 }
get(int idx,int * buffer)781 int WifiController::WifiCurrentNetworkProperty::get(int idx, int *buffer) {
782     *buffer = mWc->mCurrentlyConnectedNetworkId;
783     return 0;
784 }
785 
WifiSuspendedProperty(WifiController * c)786 WifiController::WifiSuspendedProperty::WifiSuspendedProperty(WifiController *c) :
787                 WifiIntegerProperty(c, "Suspended", false, 1) {
788 }
get(int idx,int * buffer)789 int WifiController::WifiSuspendedProperty::get(int idx, int *buffer) {
790     *buffer = mWc->getSuspended();
791     return 0;
792 }
set(int idx,int value)793 int WifiController::WifiSuspendedProperty::set(int idx, int value) {
794     return mWc->setSuspend(value == 1);
795 }
796 
WifiNetCountProperty(WifiController * c)797 WifiController::WifiNetCountProperty::WifiNetCountProperty(WifiController *c) :
798                 WifiIntegerProperty(c, "NetCount", true, 1) {
799 }
get(int idx,int * buffer)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);
804     return 0;
805 }
806 
WifiTriggerScanProperty(WifiController * c)807 WifiController::WifiTriggerScanProperty::WifiTriggerScanProperty(WifiController *c) :
808                 WifiIntegerProperty(c, "TriggerScan", false, 1) {
809 }
get(int idx,int * buffer)810 int WifiController::WifiTriggerScanProperty::get(int idx, int *buffer) {
811     // XXX: Need action type
812     *buffer = 0;
813     return 0;
814 }
815 
set(int idx,int value)816 int WifiController::WifiTriggerScanProperty::set(int idx, int value) {
817     return mWc->triggerScan();
818 }
819 
820