/*
 * 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()) {
            LOGE("Powerup failed (%s)", strerror(errno));
            return -1;
        }
    }

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

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

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

    if (Controller::bindInterface(mSupplicant->getInterfaceName())) {
        LOGE("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)) {
            LOGE("Unable to unload module after failure!");
        }
    }

out_powerdown:
    if (powerDown()) {
        LOGE("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()) {
            LOGE("Error stopping driver (%s)", strerror(errno));
            pthread_mutex_unlock(&mLock);
            return -1;
        }
    } else {
        ALOGD("Resuming");

        if (mSupplicant->startDriver()) {
            LOGE("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()) {
            LOGE("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)) {
            LOGE("Unable to unload module (%s)", strerror(errno));
            return -1;
        }
    }

    if (isPoweredUp()) {
        sendStatusBroadcast("Powering down WiFi hardware");
        if (powerDown()) {
            LOGE("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))) {
        LOGE("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)) {
        LOGE("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();
}

