OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / system / core / nexus / WifiController.cpp
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
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
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
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
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
187 bool WifiController::getSuspended() {
188     pthread_mutex_lock(&mLock);
189     bool r = mSuspended;
190     pthread_mutex_unlock(&mLock);
191     return r;
192 }
193
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
248 void WifiController::sendStatusBroadcast(const char *msg) {
249     NetworkManager::Instance()->
250                     getBroadcaster()->
251                     sendBroadcast(ResponseCode::UnsolicitedInformational, msg, false);
252 }
253
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
296 int WifiController::loadFirmware() {
297     return 0;
298 }
299
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
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
337 WifiNetwork *WifiController::createNetwork() {
338     pthread_mutex_lock(&mLock);
339     WifiNetwork *wn = mSupplicant->createNetwork();
340     pthread_mutex_unlock(&mLock);
341     return wn;
342 }
343
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
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
369 WifiNetworkCollection *WifiController::createNetworkList() {
370     return mSupplicant->createNetworkList();
371 }
372
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
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
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
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
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
435 void WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) {
436     LOGD("onAssociatedEvent(%s)", evt->getBssid());
437 }
438
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
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
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
561 void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
562     LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid());
563 }
564
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
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
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
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
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
670 WifiController::WifiEnabledProperty::WifiEnabledProperty(WifiController *c) :
671                 WifiIntegerProperty(c, "Enabled", false, 1) {
672 }
673
674 int WifiController::WifiEnabledProperty::get(int idx, int *buffer) {
675     *buffer = mWc->mEnabled;
676     return 0;
677 }
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
685 WifiController::WifiScanOnlyProperty::WifiScanOnlyProperty(WifiController *c) :
686                 WifiIntegerProperty(c, "ScanOnly", false, 1) {
687 }
688 int WifiController::WifiScanOnlyProperty::get(int idx, int *buffer) {
689     *buffer = mWc->mScanOnly;
690     return 0;
691 }
692 int WifiController::WifiScanOnlyProperty::set(int idx, int value) {
693     return mWc->setScanOnly(value == 1);
694 }
695
696 WifiController::WifiAllowedChannelsProperty::WifiAllowedChannelsProperty(WifiController *c) :
697                 WifiIntegerProperty(c, "AllowedChannels", false, 1) {
698 }
699 int WifiController::WifiAllowedChannelsProperty::get(int idx, int *buffer) {
700     *buffer = mWc->mNumAllowedChannels;
701     return 0;
702 }
703 int WifiController::WifiAllowedChannelsProperty::set(int idx, int value) {
704     // XXX: IMPL
705     errno = ENOSYS;
706     return -1;
707 }
708
709 WifiController::WifiSupplicantStateProperty::WifiSupplicantStateProperty(WifiController *c) :
710                 WifiStringProperty(c, "SupplicantState", true, 1) {
711 }
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
718 WifiController::WifiActiveScanProperty::WifiActiveScanProperty(WifiController *c) :
719                 WifiIntegerProperty(c, "ActiveScan", false, 1) {
720 }
721 int WifiController::WifiActiveScanProperty::get(int idx, int *buffer) {
722     *buffer = mWc->mActiveScan;
723     return 0;
724 }
725 int WifiController::WifiActiveScanProperty::set(int idx, int value) {
726     return mWc->setActiveScan(value);
727 }
728
729 WifiController::WifiInterfaceProperty::WifiInterfaceProperty(WifiController *c) :
730                 WifiStringProperty(c, "Interface", true, 1) {
731 }
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
737 WifiController::WifiSearchingProperty::WifiSearchingProperty(WifiController *c) :
738                 WifiIntegerProperty(c, "Searching", true, 1) {
739 }
740 int WifiController::WifiSearchingProperty::get(int idx, int *buffer) {
741     *buffer = mWc->mIsSupplicantSearching;
742     return 0;
743 }
744
745 WifiController::WifiPacketFilterProperty::WifiPacketFilterProperty(WifiController *c) :
746                 WifiIntegerProperty(c, "PacketFilter", false, 1) {
747 }
748 int WifiController::WifiPacketFilterProperty::get(int idx, int *buffer) {
749     *buffer = mWc->mPacketFilter;
750     return 0;
751 }
752 int WifiController::WifiPacketFilterProperty::set(int idx, int value) {
753     return mWc->setPacketFilter(value);
754 }
755
756 WifiController::WifiBluetoothCoexScanProperty::WifiBluetoothCoexScanProperty(WifiController *c) :
757                 WifiIntegerProperty(c, "BluetoothCoexScan", false, 1) {
758 }
759 int WifiController::WifiBluetoothCoexScanProperty::get(int idx, int *buffer) {
760     *buffer = mWc->mBluetoothCoexScan;
761     return 0;
762 }
763 int WifiController::WifiBluetoothCoexScanProperty::set(int idx, int value) {
764     return mWc->setBluetoothCoexistenceScan(value == 1);
765 }
766
767 WifiController::WifiBluetoothCoexModeProperty::WifiBluetoothCoexModeProperty(WifiController *c) :
768                 WifiIntegerProperty(c, "BluetoothCoexMode", false, 1) {
769 }
770 int WifiController::WifiBluetoothCoexModeProperty::get(int idx, int *buffer) {
771     *buffer = mWc->mBluetoothCoexMode;
772     return 0;
773 }
774 int WifiController::WifiBluetoothCoexModeProperty::set(int idx, int value) {
775     return mWc->setBluetoothCoexistenceMode(value);
776 }
777
778 WifiController::WifiCurrentNetworkProperty::WifiCurrentNetworkProperty(WifiController *c) :
779                 WifiIntegerProperty(c, "CurrentlyConnectedNetworkId", true, 1) {
780 }
781 int WifiController::WifiCurrentNetworkProperty::get(int idx, int *buffer) {
782     *buffer = mWc->mCurrentlyConnectedNetworkId;
783     return 0;
784 }
785
786 WifiController::WifiSuspendedProperty::WifiSuspendedProperty(WifiController *c) :
787                 WifiIntegerProperty(c, "Suspended", false, 1) {
788 }
789 int WifiController::WifiSuspendedProperty::get(int idx, int *buffer) {
790     *buffer = mWc->getSuspended();
791     return 0;
792 }
793 int WifiController::WifiSuspendedProperty::set(int idx, int value) {
794     return mWc->setSuspend(value == 1);
795 }
796
797 WifiController::WifiNetCountProperty::WifiNetCountProperty(WifiController *c) :
798                 WifiIntegerProperty(c, "NetCount", true, 1) {
799 }
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
807 WifiController::WifiTriggerScanProperty::WifiTriggerScanProperty(WifiController *c) :
808                 WifiIntegerProperty(c, "TriggerScan", false, 1) {
809 }
810 int WifiController::WifiTriggerScanProperty::get(int idx, int *buffer) {
811     // XXX: Need action type
812     *buffer = 0;
813     return 0;
814 }
815
816 int WifiController::WifiTriggerScanProperty::set(int idx, int value) {
817     return mWc->triggerScan();
818 }
819