/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define LOG_TAG "WifiController"
#include <cutils/log.h>

#include "Supplicant.h"
#include "WifiController.h"
#include "NetworkManager.h"
#include "ResponseCode.h"
#include "WifiNetwork.h"
#include "ISupplicantEventHandler.h"
#include "SupplicantState.h"
#include "SupplicantStatus.h"
#include "SupplicantAssociatingEvent.h"
#include "SupplicantAssociatedEvent.h"
#include "SupplicantConnectedEvent.h"
#include "SupplicantScanResultsEvent.h"
#include "SupplicantStateChangeEvent.h"
#include "SupplicantConnectionTimeoutEvent.h"
#include "SupplicantDisconnectedEvent.h"
#include "WifiStatusPoller.h"

WifiController::WifiController(PropertyManager *mPropMngr,
                               IControllerHandler *handlers,
                               char *modpath, char *modname, char *modargs) :
                Controller("wifi", mPropMngr, handlers) {
    strncpy(mModulePath, modpath, sizeof(mModulePath));
    strncpy(mModuleName, modname, sizeof(mModuleName));
    strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));

    mLatestScanResults = new ScanResultCollection();
    pthread_mutex_init(&mLatestScanResultsLock, NULL);

    pthread_mutex_init(&mLock, NULL);

    mSupplicant = new Supplicant(this, this);
    mActiveScan = false;
    mEnabled = false;
    mScanOnly = false;
    mPacketFilter = false;
    mBluetoothCoexScan = false;
    mBluetoothCoexMode = 0;
    mCurrentlyConnectedNetworkId = -1;
    mStatusPoller = new WifiStatusPoller(this);
    mRssiEventThreshold = 5;
    mLastLinkSpeed = 0;

    mSupplicantState = SupplicantState::UNKNOWN;

    mStaticProperties.propEnabled = new WifiEnabledProperty(this);
    mStaticProperties.propScanOnly = new WifiScanOnlyProperty(this);
    mStaticProperties.propAllowedChannels = new WifiAllowedChannelsProperty(this);

    mStaticProperties.propRssiEventThreshold =
            new IntegerPropertyHelper("RssiEventThreshold", false, &mRssiEventThreshold);

    mDynamicProperties.propSupplicantState = new WifiSupplicantStateProperty(this);
    mDynamicProperties.propActiveScan = new WifiActiveScanProperty(this);
    mDynamicProperties.propInterface = new WifiInterfaceProperty(this);
    mDynamicProperties.propSearching = new WifiSearchingProperty(this);
    mDynamicProperties.propPacketFilter = new WifiPacketFilterProperty(this);
    mDynamicProperties.propBluetoothCoexScan = new WifiBluetoothCoexScanProperty(this);
    mDynamicProperties.propBluetoothCoexMode = new WifiBluetoothCoexModeProperty(this);
    mDynamicProperties.propCurrentNetwork = new WifiCurrentNetworkProperty(this);

    mDynamicProperties.propRssi = new IntegerPropertyHelper("Rssi", true, &mLastRssi);
    mDynamicProperties.propLinkSpeed = new IntegerPropertyHelper("LinkSpeed", true, &mLastLinkSpeed);

    mDynamicProperties.propSuspended = new WifiSuspendedProperty(this);
    mDynamicProperties.propNetCount = new WifiNetCountProperty(this);
    mDynamicProperties.propTriggerScan = new WifiTriggerScanProperty(this);
}

int WifiController::start() {
    mPropMngr->attachProperty("wifi", mStaticProperties.propEnabled);
    mPropMngr->attachProperty("wifi", mStaticProperties.propScanOnly);
    mPropMngr->attachProperty("wifi", mStaticProperties.propAllowedChannels);
    mPropMngr->attachProperty("wifi", mStaticProperties.propRssiEventThreshold);
    return 0;
}

int WifiController::stop() {
    mPropMngr->detachProperty("wifi", mStaticProperties.propEnabled);
    mPropMngr->detachProperty("wifi", mStaticProperties.propScanOnly);
    mPropMngr->detachProperty("wifi", mStaticProperties.propAllowedChannels);
    mPropMngr->detachProperty("wifi", mStaticProperties.propRssiEventThreshold);
    return 0;
}

int WifiController::enable() {

    if (!isPoweredUp()) {
        ALOGI("Powering up");
        sendStatusBroadcast("Powering up WiFi hardware");
        if (powerUp()) {
            ALOGE("Powerup failed (%s)", strerror(errno));
            return -1;
        }
    }

    if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
        ALOGI("Loading driver");
        sendStatusBroadcast("Loading WiFi driver");
        if (loadKernelModule(mModulePath, mModuleArgs)) {
            ALOGE("Kernel module load failed (%s)", strerror(errno));
            goto out_powerdown;
        }
    }

    if (!isFirmwareLoaded()) {
        ALOGI("Loading firmware");
        sendStatusBroadcast("Loading WiFI firmware");
        if (loadFirmware()) {
            ALOGE("Firmware load failed (%s)", strerror(errno));
            goto out_powerdown;
        }
    }

    if (!mSupplicant->isStarted()) {
        ALOGI("Starting WPA Supplicant");
        sendStatusBroadcast("Starting WPA Supplicant");
        if (mSupplicant->start()) {
            ALOGE("Supplicant start failed (%s)", strerror(errno));
            goto out_unloadmodule;
        }
    }

    if (Controller::bindInterface(mSupplicant->getInterfaceName())) {
        ALOGE("Error binding interface (%s)", strerror(errno));
        goto out_unloadmodule;
    }

    if (mSupplicant->refreshNetworkList())
        ALOGW("Error getting list of networks (%s)", strerror(errno));

    ALOGW("TODO: Set # of allowed regulatory channels!");

    mPropMngr->attachProperty("wifi", mDynamicProperties.propSupplicantState);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propActiveScan);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propInterface);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propSearching);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propPacketFilter);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propCurrentNetwork);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propRssi);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propLinkSpeed);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propSuspended);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propNetCount);
    mPropMngr->attachProperty("wifi", mDynamicProperties.propTriggerScan);

    ALOGI("Enabled successfully");
    return 0;

out_unloadmodule:
    if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
        if (unloadKernelModule(mModuleName)) {
            ALOGE("Unable to unload module after failure!");
        }
    }

out_powerdown:
    if (powerDown()) {
        ALOGE("Unable to powerdown after failure!");
    }
    return -1;
}

bool WifiController::getSuspended() {
    pthread_mutex_lock(&mLock);
    bool r = mSuspended;
    pthread_mutex_unlock(&mLock);
    return r;
}

int WifiController::setSuspend(bool suspend) {

    pthread_mutex_lock(&mLock);
    if (suspend == mSuspended) {
        ALOGW("Suspended state already = %d", suspend);
        pthread_mutex_unlock(&mLock);
        return 0;
    }

    if (suspend) {
        mHandlers->onControllerSuspending(this);

        char tmp[80];
        ALOGD("Suspending from supplicant state %s",
             SupplicantState::toString(mSupplicantState,
                                       tmp,
                                       sizeof(tmp)));

        if (mSupplicantState != SupplicantState::IDLE) {
            ALOGD("Forcing Supplicant disconnect");
            if (mSupplicant->disconnect()) {
                ALOGW("Error disconnecting (%s)", strerror(errno));
            }
        }

        ALOGD("Stopping Supplicant driver");
        if (mSupplicant->stopDriver()) {
            ALOGE("Error stopping driver (%s)", strerror(errno));
            pthread_mutex_unlock(&mLock);
            return -1;
        }
    } else {
        ALOGD("Resuming");

        if (mSupplicant->startDriver()) {
            ALOGE("Error resuming driver (%s)", strerror(errno));
            pthread_mutex_unlock(&mLock);
            return -1;
        }
        // XXX: set regulatory max channels 
        if (mScanOnly)
            mSupplicant->triggerScan();
        else
            mSupplicant->reconnect();

        mHandlers->onControllerResumed(this);
    }

    mSuspended = suspend;
    pthread_mutex_unlock(&mLock);
    ALOGD("Suspend / Resume completed");
    return 0;
}

void WifiController::sendStatusBroadcast(const char *msg) {
    NetworkManager::Instance()->
                    getBroadcaster()->
                    sendBroadcast(ResponseCode::UnsolicitedInformational, msg, false);
}

int WifiController::disable() {

    mPropMngr->detachProperty("wifi", mDynamicProperties.propSupplicantState);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propActiveScan);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propInterface);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propSearching);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propPacketFilter);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propCurrentNetwork);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propRssi);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propLinkSpeed);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propSuspended);
    mPropMngr->detachProperty("wifi", mDynamicProperties.propNetCount);

    if (mSupplicant->isStarted()) {
        sendStatusBroadcast("Stopping WPA Supplicant");
        if (mSupplicant->stop()) {
            ALOGE("Supplicant stop failed (%s)", strerror(errno));
            return -1;
        }
    } else
        ALOGW("disable(): Supplicant not running?");

    if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
        sendStatusBroadcast("Unloading WiFi driver");
        if (unloadKernelModule(mModuleName)) {
            ALOGE("Unable to unload module (%s)", strerror(errno));
            return -1;
        }
    }

    if (isPoweredUp()) {
        sendStatusBroadcast("Powering down WiFi hardware");
        if (powerDown()) {
            ALOGE("Powerdown failed (%s)", strerror(errno));
            return -1;
        }
    }
    return 0;
}

int WifiController::loadFirmware() {
    return 0;
}

int WifiController::triggerScan() {
    pthread_mutex_lock(&mLock);
    if (verifyNotSuspended()) {
        pthread_mutex_unlock(&mLock);
        return -1;
    }

    switch (mSupplicantState) {
        case SupplicantState::DISCONNECTED:
        case SupplicantState::INACTIVE:
        case SupplicantState::SCANNING:
        case SupplicantState::IDLE:
            break;
        default:
            // Switch to scan only mode
            mSupplicant->setApScanMode(2);
            break;
    }

    int rc = mSupplicant->triggerScan();
    pthread_mutex_unlock(&mLock);
    return rc;
}

int WifiController::setActiveScan(bool active) {
    pthread_mutex_lock(&mLock);
    if (mActiveScan == active) {
        pthread_mutex_unlock(&mLock);
        return 0;
    }
    mActiveScan = active;

    int rc = mSupplicant->setScanMode(active);
    pthread_mutex_unlock(&mLock);
    return rc;
}

WifiNetwork *WifiController::createNetwork() {
    pthread_mutex_lock(&mLock);
    WifiNetwork *wn = mSupplicant->createNetwork();
    pthread_mutex_unlock(&mLock);
    return wn;
}

int WifiController::removeNetwork(int networkId) {
    pthread_mutex_lock(&mLock);
    WifiNetwork *wn = mSupplicant->lookupNetwork(networkId);

    if (!wn) {
        pthread_mutex_unlock(&mLock);
        return -1;
    }
    int rc = mSupplicant->removeNetwork(wn);
    pthread_mutex_unlock(&mLock);
    return rc;
}

ScanResultCollection *WifiController::createScanResults() {
    ScanResultCollection *d = new ScanResultCollection();
    ScanResultCollection::iterator i;

    pthread_mutex_lock(&mLatestScanResultsLock);
    for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i)
        d->push_back((*i)->clone());

    pthread_mutex_unlock(&mLatestScanResultsLock);
    return d;
}

WifiNetworkCollection *WifiController::createNetworkList() {
    return mSupplicant->createNetworkList();
}

int WifiController::setPacketFilter(bool enable) {
    int rc;

    pthread_mutex_lock(&mLock);
    if (enable)
        rc = mSupplicant->enablePacketFilter();
    else
        rc = mSupplicant->disablePacketFilter();

    if (!rc)
        mPacketFilter = enable;
    pthread_mutex_unlock(&mLock);
    return rc;
}

int WifiController::setBluetoothCoexistenceScan(bool enable) {
    int rc;

    pthread_mutex_lock(&mLock);

    if (enable)
        rc = mSupplicant->enableBluetoothCoexistenceScan();
    else
        rc = mSupplicant->disableBluetoothCoexistenceScan();

    if (!rc)
        mBluetoothCoexScan = enable;
    pthread_mutex_unlock(&mLock);
    return rc;
}

int WifiController::setScanOnly(bool scanOnly) {
    pthread_mutex_lock(&mLock);
    int rc = mSupplicant->setApScanMode((scanOnly ? 2 : 1));
    if (!rc)
        mScanOnly = scanOnly;
    if (!mSuspended) {
        if (scanOnly)
            mSupplicant->disconnect();
        else
            mSupplicant->reconnect();
    }
    pthread_mutex_unlock(&mLock);
    return rc;
}

int WifiController::setBluetoothCoexistenceMode(int mode) {
    pthread_mutex_lock(&mLock);
    int rc = mSupplicant->setBluetoothCoexistenceMode(mode);
    if (!rc)
        mBluetoothCoexMode = mode;
    pthread_mutex_unlock(&mLock);
    return rc;
}

void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) {
    ALOGD("onAssociatingEvent(%s, %s, %d)",
         (evt->getBssid() ? evt->getBssid() : "n/a"),
         (evt->getSsid() ? evt->getSsid() : "n/a"),
         evt->getFreq());
}

void WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) {
    ALOGD("onAssociatedEvent(%s)", evt->getBssid());
}

void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
    ALOGD("onConnectedEvent(%s, %d)", evt->getBssid(), evt->getReassociated());
    SupplicantStatus *ss = mSupplicant->getStatus();
    WifiNetwork *wn;

    if (ss->getWpaState() != SupplicantState::COMPLETED) {
        char tmp[32];

        ALOGW("onConnected() with SupplicantState = %s!",
             SupplicantState::toString(ss->getWpaState(), tmp,
             sizeof(tmp)));
        return;
    }

    if (ss->getId() == -1) {
        ALOGW("onConnected() with id = -1!");
        return;
    }
    
    mCurrentlyConnectedNetworkId = ss->getId();
    if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) {
        ALOGW("Error looking up connected network id %d (%s)",
             ss->getId(), strerror(errno));
        return;
    }
  
    delete ss;
    mHandlers->onInterfaceConnected(this);
}

void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
    char *reply;

    if (!(reply = (char *) malloc(4096))) {
        ALOGE("Out of memory");
        return;
    }

    mNumScanResultsSinceLastStateChange++;
    if (mNumScanResultsSinceLastStateChange >= 3)
        mIsSupplicantSearching = false;

    size_t len = 4096;

    if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
        ALOGW("onScanResultsEvent: Error getting scan results (%s)",
             strerror(errno));
        free(reply);
        return;
    }

    pthread_mutex_lock(&mLatestScanResultsLock);
    if (!mLatestScanResults->empty()) {
        ScanResultCollection::iterator i;

        for (i = mLatestScanResults->begin();
             i !=mLatestScanResults->end(); ++i) {
            delete *i;
        }
        mLatestScanResults->clear();
    }

    char *linep;
    char *linep_next = NULL;

    if (!strtok_r(reply, "\n", &linep_next)) {
        free(reply);
        pthread_mutex_unlock(&mLatestScanResultsLock);
        return;
    }

    while((linep = strtok_r(NULL, "\n", &linep_next)))
        mLatestScanResults->push_back(new ScanResult(linep));

    // Switch handling of scan results back to normal mode
    mSupplicant->setApScanMode(1);

    char *tmp;
    asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size());
    NetworkManager::Instance()->getBroadcaster()->
                                sendBroadcast(ResponseCode::ScanResultsReady,
                                              tmp, false);
    free(tmp);
    pthread_mutex_unlock(&mLatestScanResultsLock);
    free(reply);
}

void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) {
    char tmp[32];
    char tmp2[32];
    
    if (evt->getState() == mSupplicantState)
        return;

    ALOGD("onStateChangeEvent(%s -> %s)",
         SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)),
         SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2)));

    if (evt->getState() != SupplicantState::SCANNING) {
        mIsSupplicantSearching = true;
        mNumScanResultsSinceLastStateChange = 0;
    }

    char *tmp3;
    asprintf(&tmp3,
             "Supplicant state changed from %d (%s) -> %d (%s)",
             mSupplicantState, tmp, evt->getState(), tmp2);

    mSupplicantState = evt->getState();

    if (mSupplicantState == SupplicantState::COMPLETED) {
        mStatusPoller->start();
    } else if (mStatusPoller->isStarted()) {
        mStatusPoller->stop();
    }

    NetworkManager::Instance()->getBroadcaster()->
                                sendBroadcast(ResponseCode::SupplicantStateChange,
                                              tmp3, false);
    free(tmp3);
}

void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
    ALOGD("onConnectionTimeoutEvent(%s)", evt->getBssid());
}

void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
    mCurrentlyConnectedNetworkId = -1;
    mHandlers->onInterfaceDisconnected(this);
}

#if 0
void WifiController::onTerminatingEvent(SupplicantEvent *evt) {
    ALOGD("onTerminatingEvent(%s)", evt->getEvent());
}

void WifiController::onPasswordChangedEvent(SupplicantEvent *evt) {
    ALOGD("onPasswordChangedEvent(%s)", evt->getEvent());
}

void WifiController::onEapNotificationEvent(SupplicantEvent *evt) {
    ALOGD("onEapNotificationEvent(%s)", evt->getEvent());
}

void WifiController::onEapStartedEvent(SupplicantEvent *evt) {
    ALOGD("onEapStartedEvent(%s)", evt->getEvent());
}

void WifiController::onEapMethodEvent(SupplicantEvent *evt) {
    ALOGD("onEapMethodEvent(%s)", evt->getEvent());
}

void WifiController::onEapSuccessEvent(SupplicantEvent *evt) {
    ALOGD("onEapSuccessEvent(%s)", evt->getEvent());
}

void WifiController::onEapFailureEvent(SupplicantEvent *evt) {
    ALOGD("onEapFailureEvent(%s)", evt->getEvent());
}

void WifiController::onLinkSpeedEvent(SupplicantEvent *evt) {
    ALOGD("onLinkSpeedEvent(%s)", evt->getEvent());
}

void WifiController::onDriverStateEvent(SupplicantEvent *evt) {
    ALOGD("onDriverStateEvent(%s)", evt->getEvent());
}
#endif

void WifiController::onStatusPollInterval() {
    pthread_mutex_lock(&mLock);
    int rssi;
    if (mSupplicant->getRssi(&rssi)) {
        ALOGE("Failed to get rssi (%s)", strerror(errno));
        pthread_mutex_unlock(&mLock);
        return;
    }

    if (abs(mLastRssi - rssi) > mRssiEventThreshold) {
        char *tmp3;
        asprintf(&tmp3, "RSSI changed from %d -> %d",
                 mLastRssi, rssi);
        mLastRssi = rssi;
        NetworkManager::Instance()->getBroadcaster()->
                               sendBroadcast(ResponseCode::RssiChange,
                                             tmp3, false);
        free(tmp3);
    }

    int linkspeed = mSupplicant->getLinkSpeed();
    if (linkspeed != mLastLinkSpeed) {
        char *tmp3;
        asprintf(&tmp3, "Link speed changed from %d -> %d",
                 mLastLinkSpeed, linkspeed);
        mLastLinkSpeed = linkspeed;
        NetworkManager::Instance()->getBroadcaster()->
                               sendBroadcast(ResponseCode::LinkSpeedChange,
                                             tmp3, false);
        free(tmp3);
        
    }
    pthread_mutex_unlock(&mLock);
}

int WifiController::verifyNotSuspended() {
    if (mSuspended) {
        errno = ESHUTDOWN;
        return -1;
    }
    return 0;
}

/*
 * Property inner classes
 */

WifiController::WifiIntegerProperty::WifiIntegerProperty(WifiController *c, 
                                                         const char *name,
                                                         bool ro,
                                                         int elements) :
                IntegerProperty(name, ro, elements) {
    mWc = c;
}

WifiController::WifiStringProperty::WifiStringProperty(WifiController *c, 
                                                       const char *name,
                                                       bool ro, int elements) :
                StringProperty(name, ro, elements) {
    mWc = c;
}

WifiController::WifiEnabledProperty::WifiEnabledProperty(WifiController *c) :
                WifiIntegerProperty(c, "Enabled", false, 1) {
}

int WifiController::WifiEnabledProperty::get(int idx, int *buffer) {
    *buffer = mWc->mEnabled;
    return 0;
}
int WifiController::WifiEnabledProperty::set(int idx, int value) {
    int rc = (value ? mWc->enable() : mWc->disable());
    if (!rc)
        mWc->mEnabled = value;
    return rc;
}

WifiController::WifiScanOnlyProperty::WifiScanOnlyProperty(WifiController *c) :
                WifiIntegerProperty(c, "ScanOnly", false, 1) {
}
int WifiController::WifiScanOnlyProperty::get(int idx, int *buffer) {
    *buffer = mWc->mScanOnly;
    return 0;
}
int WifiController::WifiScanOnlyProperty::set(int idx, int value) {
    return mWc->setScanOnly(value == 1);
}

WifiController::WifiAllowedChannelsProperty::WifiAllowedChannelsProperty(WifiController *c) :
                WifiIntegerProperty(c, "AllowedChannels", false, 1) {
}
int WifiController::WifiAllowedChannelsProperty::get(int idx, int *buffer) {
    *buffer = mWc->mNumAllowedChannels;
    return 0;
}
int WifiController::WifiAllowedChannelsProperty::set(int idx, int value) {
    // XXX: IMPL
    errno = ENOSYS;
    return -1;
}

WifiController::WifiSupplicantStateProperty::WifiSupplicantStateProperty(WifiController *c) :
                WifiStringProperty(c, "SupplicantState", true, 1) {
}
int WifiController::WifiSupplicantStateProperty::get(int idx, char *buffer, size_t max) {
    if (!SupplicantState::toString(mWc->mSupplicantState, buffer, max))
        return -1;
    return 0;
}

WifiController::WifiActiveScanProperty::WifiActiveScanProperty(WifiController *c) :
                WifiIntegerProperty(c, "ActiveScan", false, 1) {
}
int WifiController::WifiActiveScanProperty::get(int idx, int *buffer) {
    *buffer = mWc->mActiveScan;
    return 0;
}
int WifiController::WifiActiveScanProperty::set(int idx, int value) {
    return mWc->setActiveScan(value);
}

WifiController::WifiInterfaceProperty::WifiInterfaceProperty(WifiController *c) :
                WifiStringProperty(c, "Interface", true, 1) {
}
int WifiController::WifiInterfaceProperty::get(int idx, char *buffer, size_t max) {
    strncpy(buffer, (mWc->getBoundInterface() ? mWc->getBoundInterface() : "none"), max);
    return 0;
}

WifiController::WifiSearchingProperty::WifiSearchingProperty(WifiController *c) :
                WifiIntegerProperty(c, "Searching", true, 1) {
}
int WifiController::WifiSearchingProperty::get(int idx, int *buffer) {
    *buffer = mWc->mIsSupplicantSearching;
    return 0;
}

WifiController::WifiPacketFilterProperty::WifiPacketFilterProperty(WifiController *c) :
                WifiIntegerProperty(c, "PacketFilter", false, 1) {
}
int WifiController::WifiPacketFilterProperty::get(int idx, int *buffer) {
    *buffer = mWc->mPacketFilter;
    return 0;
}
int WifiController::WifiPacketFilterProperty::set(int idx, int value) {
    return mWc->setPacketFilter(value);
}

WifiController::WifiBluetoothCoexScanProperty::WifiBluetoothCoexScanProperty(WifiController *c) :
                WifiIntegerProperty(c, "BluetoothCoexScan", false, 1) {
}
int WifiController::WifiBluetoothCoexScanProperty::get(int idx, int *buffer) {
    *buffer = mWc->mBluetoothCoexScan;
    return 0;
}
int WifiController::WifiBluetoothCoexScanProperty::set(int idx, int value) {
    return mWc->setBluetoothCoexistenceScan(value == 1);
}

WifiController::WifiBluetoothCoexModeProperty::WifiBluetoothCoexModeProperty(WifiController *c) :
                WifiIntegerProperty(c, "BluetoothCoexMode", false, 1) {
}
int WifiController::WifiBluetoothCoexModeProperty::get(int idx, int *buffer) {
    *buffer = mWc->mBluetoothCoexMode;
    return 0;
}
int WifiController::WifiBluetoothCoexModeProperty::set(int idx, int value) {
    return mWc->setBluetoothCoexistenceMode(value);
}

WifiController::WifiCurrentNetworkProperty::WifiCurrentNetworkProperty(WifiController *c) :
                WifiIntegerProperty(c, "CurrentlyConnectedNetworkId", true, 1) {
}
int WifiController::WifiCurrentNetworkProperty::get(int idx, int *buffer) {
    *buffer = mWc->mCurrentlyConnectedNetworkId;
    return 0;
}

WifiController::WifiSuspendedProperty::WifiSuspendedProperty(WifiController *c) :
                WifiIntegerProperty(c, "Suspended", false, 1) {
}
int WifiController::WifiSuspendedProperty::get(int idx, int *buffer) {
    *buffer = mWc->getSuspended();
    return 0;
}
int WifiController::WifiSuspendedProperty::set(int idx, int value) {
    return mWc->setSuspend(value == 1);
}

WifiController::WifiNetCountProperty::WifiNetCountProperty(WifiController *c) :
                WifiIntegerProperty(c, "NetCount", true, 1) {
}
int WifiController::WifiNetCountProperty::get(int idx, int *buffer) {
    pthread_mutex_lock(&mWc->mLock);
    *buffer = mWc->mSupplicant->getNetworkCount();
    pthread_mutex_unlock(&mWc->mLock);
    return 0;
}

WifiController::WifiTriggerScanProperty::WifiTriggerScanProperty(WifiController *c) :
                WifiIntegerProperty(c, "TriggerScan", false, 1) {
}
int WifiController::WifiTriggerScanProperty::get(int idx, int *buffer) {
    // XXX: Need action type
    *buffer = 0;
    return 0;
}

int WifiController::WifiTriggerScanProperty::set(int idx, int value) {
    return mWc->triggerScan();
}

