1dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat/*
2dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * Copyright (C) 2008 The Android Open Source Project
3dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat *
4dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * you may not use this file except in compliance with the License.
6dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * You may obtain a copy of the License at
7dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat *
8dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat *      http://www.apache.org/licenses/LICENSE-2.0
9dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat *
10dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * Unless required by applicable law or agreed to in writing, software
11dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * See the License for the specific language governing permissions and
14dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * limitations under the License.
15dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat */
164876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehat
174876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehat#include <stdlib.h>
18dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include <string.h>
19dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include <errno.h>
20dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
21dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#define LOG_TAG "WifiController"
22dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include <cutils/log.h>
23dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
24dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include "Supplicant.h"
25dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include "WifiController.h"
261441e769b2767e212a3d905bee2fd3535b484ff2San Mehat#include "NetworkManager.h"
27c4a895b7094461c98101924cf096680bfb7856f1San Mehat#include "ResponseCode.h"
283c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat#include "WifiNetwork.h"
293aff2d1de59972684bf2ab798351be5544158239San Mehat#include "ISupplicantEventHandler.h"
303aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantState.h"
313aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantStatus.h"
323aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantAssociatingEvent.h"
333aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantAssociatedEvent.h"
343aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantConnectedEvent.h"
353aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantScanResultsEvent.h"
363aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantStateChangeEvent.h"
373aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantConnectionTimeoutEvent.h"
383aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantDisconnectedEvent.h"
39c4a895b7094461c98101924cf096680bfb7856f1San Mehat#include "WifiStatusPoller.h"
403aff2d1de59972684bf2ab798351be5544158239San Mehat
413aff2d1de59972684bf2ab798351be5544158239San MehatWifiController::WifiController(PropertyManager *mPropMngr,
423aff2d1de59972684bf2ab798351be5544158239San Mehat                               IControllerHandler *handlers,
433aff2d1de59972684bf2ab798351be5544158239San Mehat                               char *modpath, char *modname, char *modargs) :
44c4a895b7094461c98101924cf096680bfb7856f1San Mehat                Controller("wifi", mPropMngr, handlers) {
45dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    strncpy(mModulePath, modpath, sizeof(mModulePath));
46dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    strncpy(mModuleName, modname, sizeof(mModuleName));
47dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
48dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
493aff2d1de59972684bf2ab798351be5544158239San Mehat    mLatestScanResults = new ScanResultCollection();
503aff2d1de59972684bf2ab798351be5544158239San Mehat    pthread_mutex_init(&mLatestScanResultsLock, NULL);
513aff2d1de59972684bf2ab798351be5544158239San Mehat
52c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_init(&mLock, NULL);
534876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehat
54c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mSupplicant = new Supplicant(this, this);
55c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mActiveScan = false;
563c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    mEnabled = false;
57c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mScanOnly = false;
58c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPacketFilter = false;
59c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mBluetoothCoexScan = false;
60c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mBluetoothCoexMode = 0;
61c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mCurrentlyConnectedNetworkId = -1;
62c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mStatusPoller = new WifiStatusPoller(this);
63c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mRssiEventThreshold = 5;
64c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mLastLinkSpeed = 0;
653c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat
663aff2d1de59972684bf2ab798351be5544158239San Mehat    mSupplicantState = SupplicantState::UNKNOWN;
67c4a895b7094461c98101924cf096680bfb7856f1San Mehat
68c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mStaticProperties.propEnabled = new WifiEnabledProperty(this);
69c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mStaticProperties.propScanOnly = new WifiScanOnlyProperty(this);
70c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mStaticProperties.propAllowedChannels = new WifiAllowedChannelsProperty(this);
71c4a895b7094461c98101924cf096680bfb7856f1San Mehat
72c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mStaticProperties.propRssiEventThreshold =
73c4a895b7094461c98101924cf096680bfb7856f1San Mehat            new IntegerPropertyHelper("RssiEventThreshold", false, &mRssiEventThreshold);
74c4a895b7094461c98101924cf096680bfb7856f1San Mehat
75c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propSupplicantState = new WifiSupplicantStateProperty(this);
76c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propActiveScan = new WifiActiveScanProperty(this);
77c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propInterface = new WifiInterfaceProperty(this);
78c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propSearching = new WifiSearchingProperty(this);
79c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propPacketFilter = new WifiPacketFilterProperty(this);
80c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propBluetoothCoexScan = new WifiBluetoothCoexScanProperty(this);
81c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propBluetoothCoexMode = new WifiBluetoothCoexModeProperty(this);
82c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propCurrentNetwork = new WifiCurrentNetworkProperty(this);
83c4a895b7094461c98101924cf096680bfb7856f1San Mehat
84c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propRssi = new IntegerPropertyHelper("Rssi", true, &mLastRssi);
85c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propLinkSpeed = new IntegerPropertyHelper("LinkSpeed", true, &mLastLinkSpeed);
86c4a895b7094461c98101924cf096680bfb7856f1San Mehat
87c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propSuspended = new WifiSuspendedProperty(this);
88c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propNetCount = new WifiNetCountProperty(this);
89c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mDynamicProperties.propTriggerScan = new WifiTriggerScanProperty(this);
90dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat}
91dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
92dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatint WifiController::start() {
93c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mStaticProperties.propEnabled);
94c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mStaticProperties.propScanOnly);
95c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mStaticProperties.propAllowedChannels);
96c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mStaticProperties.propRssiEventThreshold);
97dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    return 0;
98dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat}
99dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
100dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatint WifiController::stop() {
101c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mStaticProperties.propEnabled);
102c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mStaticProperties.propScanOnly);
103c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mStaticProperties.propAllowedChannels);
104c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mStaticProperties.propRssiEventThreshold);
1053aff2d1de59972684bf2ab798351be5544158239San Mehat    return 0;
106dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat}
107dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
108dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatint WifiController::enable() {
1090f48658d2052560141448dc8f90adbbb0879bc0dSan Mehat
1101441e769b2767e212a3d905bee2fd3535b484ff2San Mehat    if (!isPoweredUp()) {
1110f48658d2052560141448dc8f90adbbb0879bc0dSan Mehat        LOGI("Powering up");
1123aff2d1de59972684bf2ab798351be5544158239San Mehat        sendStatusBroadcast("Powering up WiFi hardware");
1131441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        if (powerUp()) {
1141441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            LOGE("Powerup failed (%s)", strerror(errno));
1151441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            return -1;
1161441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        }
117dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    }
1181441e769b2767e212a3d905bee2fd3535b484ff2San Mehat
119dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
1200f48658d2052560141448dc8f90adbbb0879bc0dSan Mehat        LOGI("Loading driver");
1213aff2d1de59972684bf2ab798351be5544158239San Mehat        sendStatusBroadcast("Loading WiFi driver");
122dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat        if (loadKernelModule(mModulePath, mModuleArgs)) {
123dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat            LOGE("Kernel module load failed (%s)", strerror(errno));
124dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat            goto out_powerdown;
125dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat        }
126dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    }
127dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
1281441e769b2767e212a3d905bee2fd3535b484ff2San Mehat    if (!isFirmwareLoaded()) {
1290f48658d2052560141448dc8f90adbbb0879bc0dSan Mehat        LOGI("Loading firmware");
1303aff2d1de59972684bf2ab798351be5544158239San Mehat        sendStatusBroadcast("Loading WiFI firmware");
1311441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        if (loadFirmware()) {
1321441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            LOGE("Firmware load failed (%s)", strerror(errno));
1331441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            goto out_powerdown;
1341441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        }
135dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    }
136dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
1371441e769b2767e212a3d905bee2fd3535b484ff2San Mehat    if (!mSupplicant->isStarted()) {
1380f48658d2052560141448dc8f90adbbb0879bc0dSan Mehat        LOGI("Starting WPA Supplicant");
1393aff2d1de59972684bf2ab798351be5544158239San Mehat        sendStatusBroadcast("Starting WPA Supplicant");
1401441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        if (mSupplicant->start()) {
1411441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            LOGE("Supplicant start failed (%s)", strerror(errno));
1421441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            goto out_unloadmodule;
1431441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        }
144dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    }
145dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
1463c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    if (Controller::bindInterface(mSupplicant->getInterfaceName())) {
1473c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat        LOGE("Error binding interface (%s)", strerror(errno));
1483c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat        goto out_unloadmodule;
1493c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    }
1503c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat
1513c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    if (mSupplicant->refreshNetworkList())
1523c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat        LOGW("Error getting list of networks (%s)", strerror(errno));
1533c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat
154c4a895b7094461c98101924cf096680bfb7856f1San Mehat    LOGW("TODO: Set # of allowed regulatory channels!");
155c4a895b7094461c98101924cf096680bfb7856f1San Mehat
156c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propSupplicantState);
157c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propActiveScan);
158c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propInterface);
159c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propSearching);
160c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propPacketFilter);
161c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
162c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
163c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propCurrentNetwork);
164c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propRssi);
165c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propLinkSpeed);
166c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propSuspended);
167c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propNetCount);
168c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->attachProperty("wifi", mDynamicProperties.propTriggerScan);
1693c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat
1700f48658d2052560141448dc8f90adbbb0879bc0dSan Mehat    LOGI("Enabled successfully");
171dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    return 0;
172dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
173dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatout_unloadmodule:
174dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
175dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat        if (unloadKernelModule(mModuleName)) {
176dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat            LOGE("Unable to unload module after failure!");
177dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat        }
178dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    }
179dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
180dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatout_powerdown:
181dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    if (powerDown()) {
182dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat        LOGE("Unable to powerdown after failure!");
183dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    }
184dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    return -1;
185dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat}
186dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
187c4a895b7094461c98101924cf096680bfb7856f1San Mehatbool WifiController::getSuspended() {
188c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
189c4a895b7094461c98101924cf096680bfb7856f1San Mehat    bool r = mSuspended;
190c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
191c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return r;
192c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
193c4a895b7094461c98101924cf096680bfb7856f1San Mehat
194c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::setSuspend(bool suspend) {
195c4a895b7094461c98101924cf096680bfb7856f1San Mehat
196c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
197c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (suspend == mSuspended) {
198c4a895b7094461c98101924cf096680bfb7856f1San Mehat        LOGW("Suspended state already = %d", suspend);
199c4a895b7094461c98101924cf096680bfb7856f1San Mehat        pthread_mutex_unlock(&mLock);
200c4a895b7094461c98101924cf096680bfb7856f1San Mehat        return 0;
201c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
202c4a895b7094461c98101924cf096680bfb7856f1San Mehat
203c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (suspend) {
204c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mHandlers->onControllerSuspending(this);
205c4a895b7094461c98101924cf096680bfb7856f1San Mehat
206c4a895b7094461c98101924cf096680bfb7856f1San Mehat        char tmp[80];
207c4a895b7094461c98101924cf096680bfb7856f1San Mehat        LOGD("Suspending from supplicant state %s",
208c4a895b7094461c98101924cf096680bfb7856f1San Mehat             SupplicantState::toString(mSupplicantState,
209c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                       tmp,
210c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                       sizeof(tmp)));
211c4a895b7094461c98101924cf096680bfb7856f1San Mehat
212c4a895b7094461c98101924cf096680bfb7856f1San Mehat        if (mSupplicantState != SupplicantState::IDLE) {
213c4a895b7094461c98101924cf096680bfb7856f1San Mehat            LOGD("Forcing Supplicant disconnect");
214c4a895b7094461c98101924cf096680bfb7856f1San Mehat            if (mSupplicant->disconnect()) {
215c4a895b7094461c98101924cf096680bfb7856f1San Mehat                LOGW("Error disconnecting (%s)", strerror(errno));
216c4a895b7094461c98101924cf096680bfb7856f1San Mehat            }
217c4a895b7094461c98101924cf096680bfb7856f1San Mehat        }
218c4a895b7094461c98101924cf096680bfb7856f1San Mehat
219c4a895b7094461c98101924cf096680bfb7856f1San Mehat        LOGD("Stopping Supplicant driver");
220c4a895b7094461c98101924cf096680bfb7856f1San Mehat        if (mSupplicant->stopDriver()) {
221c4a895b7094461c98101924cf096680bfb7856f1San Mehat            LOGE("Error stopping driver (%s)", strerror(errno));
222c4a895b7094461c98101924cf096680bfb7856f1San Mehat            pthread_mutex_unlock(&mLock);
223c4a895b7094461c98101924cf096680bfb7856f1San Mehat            return -1;
224c4a895b7094461c98101924cf096680bfb7856f1San Mehat        }
225c4a895b7094461c98101924cf096680bfb7856f1San Mehat    } else {
226c4a895b7094461c98101924cf096680bfb7856f1San Mehat        LOGD("Resuming");
227c4a895b7094461c98101924cf096680bfb7856f1San Mehat
228c4a895b7094461c98101924cf096680bfb7856f1San Mehat        if (mSupplicant->startDriver()) {
229c4a895b7094461c98101924cf096680bfb7856f1San Mehat            LOGE("Error resuming driver (%s)", strerror(errno));
230c4a895b7094461c98101924cf096680bfb7856f1San Mehat            pthread_mutex_unlock(&mLock);
231c4a895b7094461c98101924cf096680bfb7856f1San Mehat            return -1;
232c4a895b7094461c98101924cf096680bfb7856f1San Mehat        }
233c4a895b7094461c98101924cf096680bfb7856f1San Mehat        // XXX: set regulatory max channels
234c4a895b7094461c98101924cf096680bfb7856f1San Mehat        if (mScanOnly)
235c4a895b7094461c98101924cf096680bfb7856f1San Mehat            mSupplicant->triggerScan();
236c4a895b7094461c98101924cf096680bfb7856f1San Mehat        else
237c4a895b7094461c98101924cf096680bfb7856f1San Mehat            mSupplicant->reconnect();
238c4a895b7094461c98101924cf096680bfb7856f1San Mehat
239c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mHandlers->onControllerResumed(this);
240c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
241c4a895b7094461c98101924cf096680bfb7856f1San Mehat
242c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mSuspended = suspend;
243c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
244c4a895b7094461c98101924cf096680bfb7856f1San Mehat    LOGD("Suspend / Resume completed");
245c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
246c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
247c4a895b7094461c98101924cf096680bfb7856f1San Mehat
2484876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehatvoid WifiController::sendStatusBroadcast(const char *msg) {
2498d3fc3fde308fbda1b04759b26bb4fc29d41339fSan Mehat    NetworkManager::Instance()->
2508d3fc3fde308fbda1b04759b26bb4fc29d41339fSan Mehat                    getBroadcaster()->
251c4a895b7094461c98101924cf096680bfb7856f1San Mehat                    sendBroadcast(ResponseCode::UnsolicitedInformational, msg, false);
2521441e769b2767e212a3d905bee2fd3535b484ff2San Mehat}
2531441e769b2767e212a3d905bee2fd3535b484ff2San Mehat
254dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatint WifiController::disable() {
255dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
256c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propSupplicantState);
257c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propActiveScan);
258c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propInterface);
259c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propSearching);
260c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propPacketFilter);
261c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
262c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
263c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propCurrentNetwork);
264c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propRssi);
265c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propLinkSpeed);
266c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propSuspended);
267c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mPropMngr->detachProperty("wifi", mDynamicProperties.propNetCount);
2683aff2d1de59972684bf2ab798351be5544158239San Mehat
2691441e769b2767e212a3d905bee2fd3535b484ff2San Mehat    if (mSupplicant->isStarted()) {
2703aff2d1de59972684bf2ab798351be5544158239San Mehat        sendStatusBroadcast("Stopping WPA Supplicant");
2711441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        if (mSupplicant->stop()) {
2721441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            LOGE("Supplicant stop failed (%s)", strerror(errno));
2731441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            return -1;
2741441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        }
2753c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    } else
2761441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        LOGW("disable(): Supplicant not running?");
277dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
278dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
2793aff2d1de59972684bf2ab798351be5544158239San Mehat        sendStatusBroadcast("Unloading WiFi driver");
280dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat        if (unloadKernelModule(mModuleName)) {
281dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat            LOGE("Unable to unload module (%s)", strerror(errno));
282dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat            return -1;
283dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat        }
284dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    }
285dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
2861441e769b2767e212a3d905bee2fd3535b484ff2San Mehat    if (isPoweredUp()) {
2873aff2d1de59972684bf2ab798351be5544158239San Mehat        sendStatusBroadcast("Powering down WiFi hardware");
2881441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        if (powerDown()) {
2891441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            LOGE("Powerdown failed (%s)", strerror(errno));
2901441e769b2767e212a3d905bee2fd3535b484ff2San Mehat            return -1;
2911441e769b2767e212a3d905bee2fd3535b484ff2San Mehat        }
292dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    }
293dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    return 0;
294dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat}
295dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
296dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatint WifiController::loadFirmware() {
297dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    return 0;
298dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat}
299dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
300c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::triggerScan() {
301c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
302c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (verifyNotSuspended()) {
303c4a895b7094461c98101924cf096680bfb7856f1San Mehat        pthread_mutex_unlock(&mLock);
304c4a895b7094461c98101924cf096680bfb7856f1San Mehat        return -1;
305c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
306dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
307c4a895b7094461c98101924cf096680bfb7856f1San Mehat    switch (mSupplicantState) {
308c4a895b7094461c98101924cf096680bfb7856f1San Mehat        case SupplicantState::DISCONNECTED:
309c4a895b7094461c98101924cf096680bfb7856f1San Mehat        case SupplicantState::INACTIVE:
310c4a895b7094461c98101924cf096680bfb7856f1San Mehat        case SupplicantState::SCANNING:
311c4a895b7094461c98101924cf096680bfb7856f1San Mehat        case SupplicantState::IDLE:
312c4a895b7094461c98101924cf096680bfb7856f1San Mehat            break;
313c4a895b7094461c98101924cf096680bfb7856f1San Mehat        default:
314c4a895b7094461c98101924cf096680bfb7856f1San Mehat            // Switch to scan only mode
315c4a895b7094461c98101924cf096680bfb7856f1San Mehat            mSupplicant->setApScanMode(2);
316c4a895b7094461c98101924cf096680bfb7856f1San Mehat            break;
317c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
318dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
319c4a895b7094461c98101924cf096680bfb7856f1San Mehat    int rc = mSupplicant->triggerScan();
320c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
321c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return rc;
322c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
323e67651c89d0cbb759219412d49cbc5680c17df06San Mehat
324c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::setActiveScan(bool active) {
325c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
326c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (mActiveScan == active) {
327c4a895b7094461c98101924cf096680bfb7856f1San Mehat        pthread_mutex_unlock(&mLock);
328c4a895b7094461c98101924cf096680bfb7856f1San Mehat        return 0;
329c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
330c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mActiveScan = active;
331c4a895b7094461c98101924cf096680bfb7856f1San Mehat
332c4a895b7094461c98101924cf096680bfb7856f1San Mehat    int rc = mSupplicant->setScanMode(active);
333c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
334dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat    return rc;
335dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat}
336dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat
3373c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San MehatWifiNetwork *WifiController::createNetwork() {
338c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
3393c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    WifiNetwork *wn = mSupplicant->createNetwork();
340c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
3413c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    return wn;
34282a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat}
34382a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat
34482a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehatint WifiController::removeNetwork(int networkId) {
345c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
3463c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    WifiNetwork *wn = mSupplicant->lookupNetwork(networkId);
3473c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat
348c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (!wn) {
349c4a895b7094461c98101924cf096680bfb7856f1San Mehat        pthread_mutex_unlock(&mLock);
3503c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat        return -1;
351c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
352c4a895b7094461c98101924cf096680bfb7856f1San Mehat    int rc = mSupplicant->removeNetwork(wn);
353c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
354c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return rc;
35582a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat}
35682a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat
3571441e769b2767e212a3d905bee2fd3535b484ff2San MehatScanResultCollection *WifiController::createScanResults() {
3583aff2d1de59972684bf2ab798351be5544158239San Mehat    ScanResultCollection *d = new ScanResultCollection();
3593aff2d1de59972684bf2ab798351be5544158239San Mehat    ScanResultCollection::iterator i;
3603aff2d1de59972684bf2ab798351be5544158239San Mehat
3613aff2d1de59972684bf2ab798351be5544158239San Mehat    pthread_mutex_lock(&mLatestScanResultsLock);
3623aff2d1de59972684bf2ab798351be5544158239San Mehat    for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i)
3633aff2d1de59972684bf2ab798351be5544158239San Mehat        d->push_back((*i)->clone());
3643aff2d1de59972684bf2ab798351be5544158239San Mehat
3653aff2d1de59972684bf2ab798351be5544158239San Mehat    pthread_mutex_unlock(&mLatestScanResultsLock);
3663aff2d1de59972684bf2ab798351be5544158239San Mehat    return d;
367dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat}
36882a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat
36982a2116e6b67db910bba22c4874e6ca5efd3eec0San MehatWifiNetworkCollection *WifiController::createNetworkList() {
37082a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat    return mSupplicant->createNetworkList();
37182a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat}
3724876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehat
373c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::setPacketFilter(bool enable) {
3743c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    int rc;
3753c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat
376c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
377c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (enable)
378c4a895b7094461c98101924cf096680bfb7856f1San Mehat        rc = mSupplicant->enablePacketFilter();
379c4a895b7094461c98101924cf096680bfb7856f1San Mehat    else
380c4a895b7094461c98101924cf096680bfb7856f1San Mehat        rc = mSupplicant->disablePacketFilter();
3813c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat
382c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (!rc)
383c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mPacketFilter = enable;
384c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
3853c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    return rc;
3864876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehat}
3874876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehat
388c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::setBluetoothCoexistenceScan(bool enable) {
389c4a895b7094461c98101924cf096680bfb7856f1San Mehat    int rc;
390c4a895b7094461c98101924cf096680bfb7856f1San Mehat
391c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
3923c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat
393c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (enable)
394c4a895b7094461c98101924cf096680bfb7856f1San Mehat        rc = mSupplicant->enableBluetoothCoexistenceScan();
3953c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat    else
396c4a895b7094461c98101924cf096680bfb7856f1San Mehat        rc = mSupplicant->disableBluetoothCoexistenceScan();
397c4a895b7094461c98101924cf096680bfb7856f1San Mehat
398c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (!rc)
399c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mBluetoothCoexScan = enable;
400c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
401c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return rc;
402c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
4034876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehat
404c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::setScanOnly(bool scanOnly) {
405c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
406c4a895b7094461c98101924cf096680bfb7856f1San Mehat    int rc = mSupplicant->setApScanMode((scanOnly ? 2 : 1));
407c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (!rc)
408c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mScanOnly = scanOnly;
409c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (!mSuspended) {
410c4a895b7094461c98101924cf096680bfb7856f1San Mehat        if (scanOnly)
411c4a895b7094461c98101924cf096680bfb7856f1San Mehat            mSupplicant->disconnect();
412c4a895b7094461c98101924cf096680bfb7856f1San Mehat        else
413c4a895b7094461c98101924cf096680bfb7856f1San Mehat            mSupplicant->reconnect();
414c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
415c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
416c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return rc;
417c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
418c4a895b7094461c98101924cf096680bfb7856f1San Mehat
419c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::setBluetoothCoexistenceMode(int mode) {
420c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
421c4a895b7094461c98101924cf096680bfb7856f1San Mehat    int rc = mSupplicant->setBluetoothCoexistenceMode(mode);
422c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (!rc)
423c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mBluetoothCoexMode = mode;
424c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
425c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return rc;
4264876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehat}
4274876567cb9c6a69ce21fd2b1c5bcce5a6f274276San Mehat
4283aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) {
4293aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onAssociatingEvent(%s, %s, %d)",
4303aff2d1de59972684bf2ab798351be5544158239San Mehat         (evt->getBssid() ? evt->getBssid() : "n/a"),
4313aff2d1de59972684bf2ab798351be5544158239San Mehat         (evt->getSsid() ? evt->getSsid() : "n/a"),
4323aff2d1de59972684bf2ab798351be5544158239San Mehat         evt->getFreq());
4333aff2d1de59972684bf2ab798351be5544158239San Mehat}
4343aff2d1de59972684bf2ab798351be5544158239San Mehat
4353aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) {
4363aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onAssociatedEvent(%s)", evt->getBssid());
4373aff2d1de59972684bf2ab798351be5544158239San Mehat}
4383aff2d1de59972684bf2ab798351be5544158239San Mehat
4393aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
4403aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onConnectedEvent(%s, %d)", evt->getBssid(), evt->getReassociated());
441d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat    SupplicantStatus *ss = mSupplicant->getStatus();
442d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat    WifiNetwork *wn;
4433aff2d1de59972684bf2ab798351be5544158239San Mehat
444d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat    if (ss->getWpaState() != SupplicantState::COMPLETED) {
445d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat        char tmp[32];
4463aff2d1de59972684bf2ab798351be5544158239San Mehat
447d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat        LOGW("onConnected() with SupplicantState = %s!",
448d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat             SupplicantState::toString(ss->getWpaState(), tmp,
449d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat             sizeof(tmp)));
450d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat        return;
451d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat    }
4523aff2d1de59972684bf2ab798351be5544158239San Mehat
453d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat    if (ss->getId() == -1) {
454d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat        LOGW("onConnected() with id = -1!");
455d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat        return;
456d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat    }
457d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat
458c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mCurrentlyConnectedNetworkId = ss->getId();
459d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat    if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) {
460d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat        LOGW("Error looking up connected network id %d (%s)",
461d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat             ss->getId(), strerror(errno));
462d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat        return;
4633aff2d1de59972684bf2ab798351be5544158239San Mehat    }
464d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat
465d6c6796670a5e566977b13d542020fb8cc88e6cfSan Mehat    delete ss;
466c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mHandlers->onInterfaceConnected(this);
4673aff2d1de59972684bf2ab798351be5544158239San Mehat}
4683aff2d1de59972684bf2ab798351be5544158239San Mehat
4693aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
4703aff2d1de59972684bf2ab798351be5544158239San Mehat    char *reply;
4713aff2d1de59972684bf2ab798351be5544158239San Mehat
4723aff2d1de59972684bf2ab798351be5544158239San Mehat    if (!(reply = (char *) malloc(4096))) {
4733aff2d1de59972684bf2ab798351be5544158239San Mehat        LOGE("Out of memory");
4743aff2d1de59972684bf2ab798351be5544158239San Mehat        return;
4753aff2d1de59972684bf2ab798351be5544158239San Mehat    }
4763aff2d1de59972684bf2ab798351be5544158239San Mehat
477c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mNumScanResultsSinceLastStateChange++;
478c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (mNumScanResultsSinceLastStateChange >= 3)
479c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mIsSupplicantSearching = false;
480c4a895b7094461c98101924cf096680bfb7856f1San Mehat
4813aff2d1de59972684bf2ab798351be5544158239San Mehat    size_t len = 4096;
4823aff2d1de59972684bf2ab798351be5544158239San Mehat
4833aff2d1de59972684bf2ab798351be5544158239San Mehat    if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
4843aff2d1de59972684bf2ab798351be5544158239San Mehat        LOGW("onScanResultsEvent: Error getting scan results (%s)",
4853aff2d1de59972684bf2ab798351be5544158239San Mehat             strerror(errno));
4863aff2d1de59972684bf2ab798351be5544158239San Mehat        free(reply);
4873aff2d1de59972684bf2ab798351be5544158239San Mehat        return;
4883aff2d1de59972684bf2ab798351be5544158239San Mehat    }
4893aff2d1de59972684bf2ab798351be5544158239San Mehat
4903aff2d1de59972684bf2ab798351be5544158239San Mehat    pthread_mutex_lock(&mLatestScanResultsLock);
4913aff2d1de59972684bf2ab798351be5544158239San Mehat    if (!mLatestScanResults->empty()) {
4923aff2d1de59972684bf2ab798351be5544158239San Mehat        ScanResultCollection::iterator i;
4933aff2d1de59972684bf2ab798351be5544158239San Mehat
4943aff2d1de59972684bf2ab798351be5544158239San Mehat        for (i = mLatestScanResults->begin();
4953aff2d1de59972684bf2ab798351be5544158239San Mehat             i !=mLatestScanResults->end(); ++i) {
4963aff2d1de59972684bf2ab798351be5544158239San Mehat            delete *i;
4973aff2d1de59972684bf2ab798351be5544158239San Mehat        }
4983aff2d1de59972684bf2ab798351be5544158239San Mehat        mLatestScanResults->clear();
4993aff2d1de59972684bf2ab798351be5544158239San Mehat    }
5003aff2d1de59972684bf2ab798351be5544158239San Mehat
5013aff2d1de59972684bf2ab798351be5544158239San Mehat    char *linep;
5023aff2d1de59972684bf2ab798351be5544158239San Mehat    char *linep_next = NULL;
5033aff2d1de59972684bf2ab798351be5544158239San Mehat
5043aff2d1de59972684bf2ab798351be5544158239San Mehat    if (!strtok_r(reply, "\n", &linep_next)) {
5053aff2d1de59972684bf2ab798351be5544158239San Mehat        free(reply);
5063aff2d1de59972684bf2ab798351be5544158239San Mehat        pthread_mutex_unlock(&mLatestScanResultsLock);
5073aff2d1de59972684bf2ab798351be5544158239San Mehat        return;
5083aff2d1de59972684bf2ab798351be5544158239San Mehat    }
5093aff2d1de59972684bf2ab798351be5544158239San Mehat
5103aff2d1de59972684bf2ab798351be5544158239San Mehat    while((linep = strtok_r(NULL, "\n", &linep_next)))
5113aff2d1de59972684bf2ab798351be5544158239San Mehat        mLatestScanResults->push_back(new ScanResult(linep));
5123aff2d1de59972684bf2ab798351be5544158239San Mehat
513c4a895b7094461c98101924cf096680bfb7856f1San Mehat    // Switch handling of scan results back to normal mode
514c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mSupplicant->setApScanMode(1);
515c4a895b7094461c98101924cf096680bfb7856f1San Mehat
5163aff2d1de59972684bf2ab798351be5544158239San Mehat    char *tmp;
5173aff2d1de59972684bf2ab798351be5544158239San Mehat    asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size());
5183aff2d1de59972684bf2ab798351be5544158239San Mehat    NetworkManager::Instance()->getBroadcaster()->
519c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                sendBroadcast(ResponseCode::ScanResultsReady,
520c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                              tmp, false);
5213aff2d1de59972684bf2ab798351be5544158239San Mehat    free(tmp);
5223aff2d1de59972684bf2ab798351be5544158239San Mehat    pthread_mutex_unlock(&mLatestScanResultsLock);
5233aff2d1de59972684bf2ab798351be5544158239San Mehat    free(reply);
5243aff2d1de59972684bf2ab798351be5544158239San Mehat}
5253aff2d1de59972684bf2ab798351be5544158239San Mehat
5263aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) {
5273aff2d1de59972684bf2ab798351be5544158239San Mehat    char tmp[32];
5283aff2d1de59972684bf2ab798351be5544158239San Mehat    char tmp2[32];
5293aff2d1de59972684bf2ab798351be5544158239San Mehat
530c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (evt->getState() == mSupplicantState)
531c4a895b7094461c98101924cf096680bfb7856f1San Mehat        return;
532c4a895b7094461c98101924cf096680bfb7856f1San Mehat
5333aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onStateChangeEvent(%s -> %s)",
5343aff2d1de59972684bf2ab798351be5544158239San Mehat         SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)),
5353aff2d1de59972684bf2ab798351be5544158239San Mehat         SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2)));
5363aff2d1de59972684bf2ab798351be5544158239San Mehat
537c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (evt->getState() != SupplicantState::SCANNING) {
538c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mIsSupplicantSearching = true;
539c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mNumScanResultsSinceLastStateChange = 0;
540c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
541c4a895b7094461c98101924cf096680bfb7856f1San Mehat
542c4a895b7094461c98101924cf096680bfb7856f1San Mehat    char *tmp3;
543c4a895b7094461c98101924cf096680bfb7856f1San Mehat    asprintf(&tmp3,
544c4a895b7094461c98101924cf096680bfb7856f1San Mehat             "Supplicant state changed from %d (%s) -> %d (%s)",
545c4a895b7094461c98101924cf096680bfb7856f1San Mehat             mSupplicantState, tmp, evt->getState(), tmp2);
546c4a895b7094461c98101924cf096680bfb7856f1San Mehat
5473aff2d1de59972684bf2ab798351be5544158239San Mehat    mSupplicantState = evt->getState();
548c4a895b7094461c98101924cf096680bfb7856f1San Mehat
549c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (mSupplicantState == SupplicantState::COMPLETED) {
550c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mStatusPoller->start();
551c4a895b7094461c98101924cf096680bfb7856f1San Mehat    } else if (mStatusPoller->isStarted()) {
552c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mStatusPoller->stop();
553c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
554c4a895b7094461c98101924cf096680bfb7856f1San Mehat
555c4a895b7094461c98101924cf096680bfb7856f1San Mehat    NetworkManager::Instance()->getBroadcaster()->
556c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                sendBroadcast(ResponseCode::SupplicantStateChange,
557c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                              tmp3, false);
558c4a895b7094461c98101924cf096680bfb7856f1San Mehat    free(tmp3);
5593aff2d1de59972684bf2ab798351be5544158239San Mehat}
5603aff2d1de59972684bf2ab798351be5544158239San Mehat
5613aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
5623aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid());
5633aff2d1de59972684bf2ab798351be5544158239San Mehat}
5643aff2d1de59972684bf2ab798351be5544158239San Mehat
5653aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
566c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mCurrentlyConnectedNetworkId = -1;
567c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mHandlers->onInterfaceDisconnected(this);
5683aff2d1de59972684bf2ab798351be5544158239San Mehat}
5693aff2d1de59972684bf2ab798351be5544158239San Mehat
5703aff2d1de59972684bf2ab798351be5544158239San Mehat#if 0
5713aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onTerminatingEvent(SupplicantEvent *evt) {
5723aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onTerminatingEvent(%s)", evt->getEvent());
5733aff2d1de59972684bf2ab798351be5544158239San Mehat}
5743aff2d1de59972684bf2ab798351be5544158239San Mehat
5753aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onPasswordChangedEvent(SupplicantEvent *evt) {
5763aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onPasswordChangedEvent(%s)", evt->getEvent());
5773aff2d1de59972684bf2ab798351be5544158239San Mehat}
5783aff2d1de59972684bf2ab798351be5544158239San Mehat
5793aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onEapNotificationEvent(SupplicantEvent *evt) {
5803aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onEapNotificationEvent(%s)", evt->getEvent());
5813aff2d1de59972684bf2ab798351be5544158239San Mehat}
5823aff2d1de59972684bf2ab798351be5544158239San Mehat
5833aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onEapStartedEvent(SupplicantEvent *evt) {
5843aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onEapStartedEvent(%s)", evt->getEvent());
5853aff2d1de59972684bf2ab798351be5544158239San Mehat}
5863aff2d1de59972684bf2ab798351be5544158239San Mehat
5873aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onEapMethodEvent(SupplicantEvent *evt) {
5883aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onEapMethodEvent(%s)", evt->getEvent());
5893aff2d1de59972684bf2ab798351be5544158239San Mehat}
5903aff2d1de59972684bf2ab798351be5544158239San Mehat
5913aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onEapSuccessEvent(SupplicantEvent *evt) {
5923aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onEapSuccessEvent(%s)", evt->getEvent());
5933aff2d1de59972684bf2ab798351be5544158239San Mehat}
5943aff2d1de59972684bf2ab798351be5544158239San Mehat
5953aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onEapFailureEvent(SupplicantEvent *evt) {
5963aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onEapFailureEvent(%s)", evt->getEvent());
5973aff2d1de59972684bf2ab798351be5544158239San Mehat}
5983aff2d1de59972684bf2ab798351be5544158239San Mehat
5993aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onLinkSpeedEvent(SupplicantEvent *evt) {
6003aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onLinkSpeedEvent(%s)", evt->getEvent());
6013aff2d1de59972684bf2ab798351be5544158239San Mehat}
6023aff2d1de59972684bf2ab798351be5544158239San Mehat
6033aff2d1de59972684bf2ab798351be5544158239San Mehatvoid WifiController::onDriverStateEvent(SupplicantEvent *evt) {
6043aff2d1de59972684bf2ab798351be5544158239San Mehat    LOGD("onDriverStateEvent(%s)", evt->getEvent());
6053aff2d1de59972684bf2ab798351be5544158239San Mehat}
6063aff2d1de59972684bf2ab798351be5544158239San Mehat#endif
607c4a895b7094461c98101924cf096680bfb7856f1San Mehat
608c4a895b7094461c98101924cf096680bfb7856f1San Mehatvoid WifiController::onStatusPollInterval() {
609c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mLock);
610c4a895b7094461c98101924cf096680bfb7856f1San Mehat    int rssi;
611c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (mSupplicant->getRssi(&rssi)) {
612c4a895b7094461c98101924cf096680bfb7856f1San Mehat        LOGE("Failed to get rssi (%s)", strerror(errno));
613c4a895b7094461c98101924cf096680bfb7856f1San Mehat        pthread_mutex_unlock(&mLock);
614c4a895b7094461c98101924cf096680bfb7856f1San Mehat        return;
615c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
616c4a895b7094461c98101924cf096680bfb7856f1San Mehat
617c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (abs(mLastRssi - rssi) > mRssiEventThreshold) {
618c4a895b7094461c98101924cf096680bfb7856f1San Mehat        char *tmp3;
619c4a895b7094461c98101924cf096680bfb7856f1San Mehat        asprintf(&tmp3, "RSSI changed from %d -> %d",
620c4a895b7094461c98101924cf096680bfb7856f1San Mehat                 mLastRssi, rssi);
621c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mLastRssi = rssi;
622c4a895b7094461c98101924cf096680bfb7856f1San Mehat        NetworkManager::Instance()->getBroadcaster()->
623c4a895b7094461c98101924cf096680bfb7856f1San Mehat                               sendBroadcast(ResponseCode::RssiChange,
624c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                             tmp3, false);
625c4a895b7094461c98101924cf096680bfb7856f1San Mehat        free(tmp3);
626c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
627c4a895b7094461c98101924cf096680bfb7856f1San Mehat
628c4a895b7094461c98101924cf096680bfb7856f1San Mehat    int linkspeed = mSupplicant->getLinkSpeed();
629c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (linkspeed != mLastLinkSpeed) {
630c4a895b7094461c98101924cf096680bfb7856f1San Mehat        char *tmp3;
631c4a895b7094461c98101924cf096680bfb7856f1San Mehat        asprintf(&tmp3, "Link speed changed from %d -> %d",
632c4a895b7094461c98101924cf096680bfb7856f1San Mehat                 mLastLinkSpeed, linkspeed);
633c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mLastLinkSpeed = linkspeed;
634c4a895b7094461c98101924cf096680bfb7856f1San Mehat        NetworkManager::Instance()->getBroadcaster()->
635c4a895b7094461c98101924cf096680bfb7856f1San Mehat                               sendBroadcast(ResponseCode::LinkSpeedChange,
636c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                             tmp3, false);
637c4a895b7094461c98101924cf096680bfb7856f1San Mehat        free(tmp3);
638c4a895b7094461c98101924cf096680bfb7856f1San Mehat
639c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
640c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mLock);
641c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
642c4a895b7094461c98101924cf096680bfb7856f1San Mehat
643c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::verifyNotSuspended() {
644c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (mSuspended) {
645c4a895b7094461c98101924cf096680bfb7856f1San Mehat        errno = ESHUTDOWN;
646c4a895b7094461c98101924cf096680bfb7856f1San Mehat        return -1;
647c4a895b7094461c98101924cf096680bfb7856f1San Mehat    }
648c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
649c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
650c4a895b7094461c98101924cf096680bfb7856f1San Mehat
651c4a895b7094461c98101924cf096680bfb7856f1San Mehat/*
652c4a895b7094461c98101924cf096680bfb7856f1San Mehat * Property inner classes
653c4a895b7094461c98101924cf096680bfb7856f1San Mehat */
654c4a895b7094461c98101924cf096680bfb7856f1San Mehat
655c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiIntegerProperty::WifiIntegerProperty(WifiController *c,
656c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                                         const char *name,
657c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                                         bool ro,
658c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                                         int elements) :
659c4a895b7094461c98101924cf096680bfb7856f1San Mehat                IntegerProperty(name, ro, elements) {
660c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mWc = c;
661c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
662c4a895b7094461c98101924cf096680bfb7856f1San Mehat
663c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiStringProperty::WifiStringProperty(WifiController *c,
664c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                                       const char *name,
665c4a895b7094461c98101924cf096680bfb7856f1San Mehat                                                       bool ro, int elements) :
666c4a895b7094461c98101924cf096680bfb7856f1San Mehat                StringProperty(name, ro, elements) {
667c4a895b7094461c98101924cf096680bfb7856f1San Mehat    mWc = c;
668c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
669c4a895b7094461c98101924cf096680bfb7856f1San Mehat
670c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiEnabledProperty::WifiEnabledProperty(WifiController *c) :
671c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "Enabled", false, 1) {
672c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
673c4a895b7094461c98101924cf096680bfb7856f1San Mehat
674c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiEnabledProperty::get(int idx, int *buffer) {
675c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mEnabled;
676c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
677c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
678c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiEnabledProperty::set(int idx, int value) {
679c4a895b7094461c98101924cf096680bfb7856f1San Mehat    int rc = (value ? mWc->enable() : mWc->disable());
680c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (!rc)
681c4a895b7094461c98101924cf096680bfb7856f1San Mehat        mWc->mEnabled = value;
682c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return rc;
683c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
684c4a895b7094461c98101924cf096680bfb7856f1San Mehat
685c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiScanOnlyProperty::WifiScanOnlyProperty(WifiController *c) :
686c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "ScanOnly", false, 1) {
687c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
688c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiScanOnlyProperty::get(int idx, int *buffer) {
689c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mScanOnly;
690c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
691c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
692c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiScanOnlyProperty::set(int idx, int value) {
693c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return mWc->setScanOnly(value == 1);
694c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
695c4a895b7094461c98101924cf096680bfb7856f1San Mehat
696c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiAllowedChannelsProperty::WifiAllowedChannelsProperty(WifiController *c) :
697c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "AllowedChannels", false, 1) {
698c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
699c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiAllowedChannelsProperty::get(int idx, int *buffer) {
700c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mNumAllowedChannels;
701c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
702c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
703c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiAllowedChannelsProperty::set(int idx, int value) {
704c4a895b7094461c98101924cf096680bfb7856f1San Mehat    // XXX: IMPL
705c4a895b7094461c98101924cf096680bfb7856f1San Mehat    errno = ENOSYS;
706c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return -1;
707c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
708c4a895b7094461c98101924cf096680bfb7856f1San Mehat
709c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiSupplicantStateProperty::WifiSupplicantStateProperty(WifiController *c) :
710c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiStringProperty(c, "SupplicantState", true, 1) {
711c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
712c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiSupplicantStateProperty::get(int idx, char *buffer, size_t max) {
713c4a895b7094461c98101924cf096680bfb7856f1San Mehat    if (!SupplicantState::toString(mWc->mSupplicantState, buffer, max))
714c4a895b7094461c98101924cf096680bfb7856f1San Mehat        return -1;
715c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
716c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
717c4a895b7094461c98101924cf096680bfb7856f1San Mehat
718c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiActiveScanProperty::WifiActiveScanProperty(WifiController *c) :
719c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "ActiveScan", false, 1) {
720c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
721c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiActiveScanProperty::get(int idx, int *buffer) {
722c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mActiveScan;
723c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
724c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
725c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiActiveScanProperty::set(int idx, int value) {
726c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return mWc->setActiveScan(value);
727c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
728c4a895b7094461c98101924cf096680bfb7856f1San Mehat
729c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiInterfaceProperty::WifiInterfaceProperty(WifiController *c) :
730c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiStringProperty(c, "Interface", true, 1) {
731c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
732c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiInterfaceProperty::get(int idx, char *buffer, size_t max) {
733c4a895b7094461c98101924cf096680bfb7856f1San Mehat    strncpy(buffer, (mWc->getBoundInterface() ? mWc->getBoundInterface() : "none"), max);
734c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
735c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
736c4a895b7094461c98101924cf096680bfb7856f1San Mehat
737c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiSearchingProperty::WifiSearchingProperty(WifiController *c) :
738c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "Searching", true, 1) {
739c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
740c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiSearchingProperty::get(int idx, int *buffer) {
741c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mIsSupplicantSearching;
742c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
743c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
744c4a895b7094461c98101924cf096680bfb7856f1San Mehat
745c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiPacketFilterProperty::WifiPacketFilterProperty(WifiController *c) :
746c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "PacketFilter", false, 1) {
747c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
748c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiPacketFilterProperty::get(int idx, int *buffer) {
749c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mPacketFilter;
750c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
751c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
752c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiPacketFilterProperty::set(int idx, int value) {
753c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return mWc->setPacketFilter(value);
754c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
755c4a895b7094461c98101924cf096680bfb7856f1San Mehat
756c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiBluetoothCoexScanProperty::WifiBluetoothCoexScanProperty(WifiController *c) :
757c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "BluetoothCoexScan", false, 1) {
758c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
759c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiBluetoothCoexScanProperty::get(int idx, int *buffer) {
760c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mBluetoothCoexScan;
761c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
762c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
763c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiBluetoothCoexScanProperty::set(int idx, int value) {
764c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return mWc->setBluetoothCoexistenceScan(value == 1);
765c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
766c4a895b7094461c98101924cf096680bfb7856f1San Mehat
767c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiBluetoothCoexModeProperty::WifiBluetoothCoexModeProperty(WifiController *c) :
768c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "BluetoothCoexMode", false, 1) {
769c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
770c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiBluetoothCoexModeProperty::get(int idx, int *buffer) {
771c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mBluetoothCoexMode;
772c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
773c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
774c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiBluetoothCoexModeProperty::set(int idx, int value) {
775c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return mWc->setBluetoothCoexistenceMode(value);
776c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
777c4a895b7094461c98101924cf096680bfb7856f1San Mehat
778c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiCurrentNetworkProperty::WifiCurrentNetworkProperty(WifiController *c) :
779c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "CurrentlyConnectedNetworkId", true, 1) {
780c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
781c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiCurrentNetworkProperty::get(int idx, int *buffer) {
782c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mCurrentlyConnectedNetworkId;
783c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
784c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
785c4a895b7094461c98101924cf096680bfb7856f1San Mehat
786c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiSuspendedProperty::WifiSuspendedProperty(WifiController *c) :
787c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "Suspended", false, 1) {
788c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
789c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiSuspendedProperty::get(int idx, int *buffer) {
790c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->getSuspended();
791c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
792c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
793c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiSuspendedProperty::set(int idx, int value) {
794c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return mWc->setSuspend(value == 1);
795c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
796c4a895b7094461c98101924cf096680bfb7856f1San Mehat
797c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiNetCountProperty::WifiNetCountProperty(WifiController *c) :
798c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "NetCount", true, 1) {
799c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
800c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiNetCountProperty::get(int idx, int *buffer) {
801c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_lock(&mWc->mLock);
802c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = mWc->mSupplicant->getNetworkCount();
803c4a895b7094461c98101924cf096680bfb7856f1San Mehat    pthread_mutex_unlock(&mWc->mLock);
804c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
805c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
806c4a895b7094461c98101924cf096680bfb7856f1San Mehat
807c4a895b7094461c98101924cf096680bfb7856f1San MehatWifiController::WifiTriggerScanProperty::WifiTriggerScanProperty(WifiController *c) :
808c4a895b7094461c98101924cf096680bfb7856f1San Mehat                WifiIntegerProperty(c, "TriggerScan", false, 1) {
809c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
810c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiTriggerScanProperty::get(int idx, int *buffer) {
811c4a895b7094461c98101924cf096680bfb7856f1San Mehat    // XXX: Need action type
812c4a895b7094461c98101924cf096680bfb7856f1San Mehat    *buffer = 0;
813c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return 0;
814c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
815c4a895b7094461c98101924cf096680bfb7856f1San Mehat
816c4a895b7094461c98101924cf096680bfb7856f1San Mehatint WifiController::WifiTriggerScanProperty::set(int idx, int value) {
817c4a895b7094461c98101924cf096680bfb7856f1San Mehat    return mWc->triggerScan();
818c4a895b7094461c98101924cf096680bfb7856f1San Mehat}
819c4a895b7094461c98101924cf096680bfb7856f1San Mehat
820