/*
 * 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()) {
        LOGI("Powering up");
        sendStatusBroadcast("Powering up WiFi hardware");
        if (powerUp()) {
            LOGE("Powerup failed (%s)", strerror(errno));
            return -1;
        }
    }

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

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

    if (!mSupplicant->isStarted()) {
        LOGI("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())
        LOGW("Error getting list of networks (%s)", strerror(errno));

    LOGW("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);

    LOGI("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) {
        LOGW("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()) {
                LOGW("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
        LOGW("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];

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

    if (ss->getId() == -1) {
        LOGW("onConnected() with id = -1!");
        return;
    }
    
    mCurrentlyConnectedNetworkId = ss->getId();
    if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) {
        LOGW("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)) {
        LOGW("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();
}

