diff options
author | San Mehat <san@google.com> | 2009-05-22 15:36:13 -0700 |
---|---|---|
committer | San Mehat <san@google.com> | 2009-05-29 15:26:21 -0700 |
commit | 3c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5 (patch) | |
tree | e73708dde1e774c8e6a0539a91a228acd68000a2 /nexus/WifiNetwork.cpp | |
parent | 192331d9060763b92f7989124bedbd136689d735 (diff) | |
download | system_core-3c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5.zip system_core-3c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5.tar.gz system_core-3c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5.tar.bz2 |
nexus: Refactor some of the create/remove network path and add code for
retrieving network lists from supplicant
nexus: Rework properties
nexus: Implement wifi network enable/disable and add some error checking
nexus: Add some TODOs
nexus: Whitespace cleanup
nexus: Add bindings between controllers and network interfaces
nexus: Add properties for InterfaceConfig
nexus: Fix a few conversion bugs in InterfaceConfig
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'nexus/WifiNetwork.cpp')
-rw-r--r-- | nexus/WifiNetwork.cpp | 533 |
1 files changed, 505 insertions, 28 deletions
diff --git a/nexus/WifiNetwork.cpp b/nexus/WifiNetwork.cpp index ef013c0..1f53a20 100644 --- a/nexus/WifiNetwork.cpp +++ b/nexus/WifiNetwork.cpp @@ -16,14 +16,93 @@ #include <errno.h> #include <string.h> +#include <stdlib.h> #include <sys/types.h> +#define LOG_TAG "WifiNetwork" +#include <cutils/log.h> + +#include "NetworkManager.h" #include "WifiNetwork.h" #include "Supplicant.h" +#include "WifiController.h" +#include "InterfaceConfig.h" + +const char *WifiNetwork::PropertyNames[] = { "ssid", "bssid", "psk", "wepkey.1", + "wepkey.2", "wepkey.3", "wepkey.4", + "defkeyidx", "pri", "hiddenssid", + "AllowedKeyManagement", + "AllowedProtocols", + "AllowedAuthAlgorithms", + "AllowedPairwiseCiphers", + "AllowedGroupCiphers", + "enabled", '\0' }; +WifiNetwork::WifiNetwork() { + // This is private to restrict copy constructors +} + +WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data) { + mController = c; + mSuppl = suppl; + + char *tmp = strdup(data); + char *next = tmp; + char *id; + char *ssid; + char *bssid; + char *flags; + + if (!(id = strsep(&next, "\t"))) + LOGE("Failed to extract network id"); + if (!(ssid = strsep(&next, "\t"))) + LOGE("Failed to extract ssid"); + if (!(bssid = strsep(&next, "\t"))) + LOGE("Failed to extract bssid"); + if (!(flags = strsep(&next, "\t"))) + LOGE("Failed to extract flags"); + + // LOGD("id '%s', ssid '%s', bssid '%s', flags '%s'", id, ssid, bssid, + // flags ? flags :"null"); + + if (id) + mNetid = atoi(id); + if (ssid) + mSsid = strdup(ssid); + if (bssid) + mBssid = strdup(bssid); + + mPsk = NULL; + memset(mWepKeys, 0, sizeof(mWepKeys)); + mDefaultKeyIndex = -1; + mPriority = -1; + mHiddenSsid = NULL; + mAllowedKeyManagement = 0; + mAllowedProtocols = 0; + mAllowedAuthAlgorithms = 0; + mAllowedPairwiseCiphers = 0; + mAllowedGroupCiphers = 0; + mEnabled = true; + + if (flags && flags[0] != '\0') { + if (!strcmp(flags, "[DISABLED]")) + mEnabled = false; + else + LOGW("Unsupported flags '%s'", flags); + } -WifiNetwork::WifiNetwork(Supplicant *suppl) { + char *tmp2; + asprintf(&tmp2, "wifi.net.%d", mNetid); + mIfaceCfg = new InterfaceConfig(tmp2); + free(tmp2); + + registerProperties(); + free(tmp); +} + +WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, int networkId) { + mController = c; mSuppl = suppl; - mNetid = -1; + mNetid = networkId; mSsid = NULL; mBssid = NULL; mPsk = NULL; @@ -36,9 +115,45 @@ WifiNetwork::WifiNetwork(Supplicant *suppl) { mAllowedAuthAlgorithms = 0; mAllowedPairwiseCiphers = 0; mAllowedGroupCiphers = 0; + mEnabled = false; + + char *tmp2; + asprintf(&tmp2, "wifi.net.%d", mNetid); + mIfaceCfg = new InterfaceConfig(tmp2); + free(tmp2); + + registerProperties(); +} + +WifiNetwork *WifiNetwork::clone() { + WifiNetwork *r = new WifiNetwork(); + + r->mSuppl = mSuppl; + r->mNetid = mNetid; + + if (mSsid) + r->mSsid = strdup(mSsid); + if (mBssid) + r->mBssid = strdup(mBssid); + if (mPsk) + r->mPsk = strdup(mPsk); + + r->mController = mController; + memcpy(r->mWepKeys, mWepKeys, sizeof(mWepKeys)); + r->mDefaultKeyIndex = mDefaultKeyIndex; + r->mPriority = mPriority; + if (mHiddenSsid) + r->mHiddenSsid = strdup(mHiddenSsid); + r->mAllowedKeyManagement = mAllowedKeyManagement; + r->mAllowedProtocols = mAllowedProtocols; + r->mAllowedAuthAlgorithms = mAllowedAuthAlgorithms; + r->mAllowedPairwiseCiphers = mAllowedPairwiseCiphers; + r->mAllowedGroupCiphers = mAllowedGroupCiphers; + return r; } WifiNetwork::~WifiNetwork() { + unregisterProperties(); if (mSsid) free(mSsid); if (mBssid) @@ -49,61 +164,423 @@ WifiNetwork::~WifiNetwork() { if (mWepKeys[i]) free(mWepKeys[i]); } + if (mHiddenSsid) free(mHiddenSsid); + if (mIfaceCfg) + delete(mIfaceCfg); } -int WifiNetwork::setSsid(char *ssid) { - errno = ENOSYS; +int WifiNetwork::refresh() { + char buffer[255]; + size_t len; + + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, "psk", buffer, len)) + mPsk = strdup(buffer); + + for (int i = 0; i < 4; i++) { + char *name; + + asprintf(&name, "wep_key%d", i); + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, name, buffer, len)) + mWepKeys[i] = strdup(buffer); + free(name); + } + + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, "wep_tx_keyidx", buffer, len)) + mDefaultKeyIndex = atoi(buffer); + + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, "priority", buffer, len)) + mPriority = atoi(buffer); + + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, "scan_ssid", buffer, len)) + mHiddenSsid = strdup(buffer); + + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, "key_mgmt", buffer, len)) { + // TODO + } + + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, "proto", buffer, len)) { + // TODO + } + + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, "auth_alg", buffer, len)) { + // TODO + } + + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, "pairwise", buffer, len)) { + // TODO + } + + len = sizeof(buffer); + if (mSuppl->getNetworkVar(mNetid, "group", buffer, len)) { + // TODO + } + + return 0; +out_err: + LOGE("Refresh failed (%s)",strerror(errno)); return -1; } -int WifiNetwork::setBssid(char *bssid) { - errno = ENOSYS; +int WifiNetwork::set(const char *name, const char *value) { + char *n_tmp = strdup(name + strlen("wifi.net.")); + char *n_next = n_tmp; + char *n_local; + char *n_rest; + int rc = 0; + + if (!strsep(&n_next, ".")) // skip net id + goto out_inval; + + if (!(n_local = strsep(&n_next, "."))) + goto out_inval; + + n_rest = n_next; + +// LOGD("set(): var '%s'(%s / %s) = %s", name, n_local, n_rest, value); + if (!strcasecmp(n_local, "enabled")) + rc = setEnabled(atoi(value)); + else if (!strcmp(n_local, "ssid")) + rc = setSsid(value); + else if (!strcasecmp(n_local, "bssid")) + rc = setBssid(value); + else if (!strcasecmp(n_local, "psk")) + rc = setPsk(value); + else if (!strcasecmp(n_local, "wepkey")) + rc = setWepKey(atoi(n_rest) -1, value); + else if (!strcasecmp(n_local, "defkeyidx")) + rc = setDefaultKeyIndex(atoi(value)); + else if (!strcasecmp(n_local, "pri")) + rc = setPriority(atoi(value)); + else if (!strcasecmp(n_local, "hiddenssid")) + rc = setHiddenSsid(value); + else if (!strcasecmp(n_local, "AllowedKeyManagement")) { + uint32_t mask = 0; + bool none = false; + char *v_tmp = strdup(value); + char *v_next = v_tmp; + char *v_token; + + while((v_token = strsep(&v_next, " "))) { + if (!strcasecmp(v_token, "NONE")) { + mask = 0; + none = true; + } else if (!none) { + if (!strcasecmp(v_token, "WPA_PSK")) + mask |= KeyManagementMask::WPA_PSK; + else if (!strcasecmp(v_token, "WPA_EAP")) + mask |= KeyManagementMask::WPA_EAP; + else if (!strcasecmp(v_token, "IEEE8021X")) + mask |= KeyManagementMask::IEEE8021X; + else { + errno = EINVAL; + rc = -1; + free(v_tmp); + goto out; + } + } else { + errno = EINVAL; + rc = -1; + free(v_tmp); + goto out; + } + } + free(v_tmp); + } else if (!strcasecmp(n_local, "AllowedProtocols")) { + // TODO + } else if (!strcasecmp(n_local, "AllowedPairwiseCiphers")) { + // TODO + } else if (!strcasecmp(n_local, "AllowedAuthAlgorithms")) { + // TODO + } else if (!strcasecmp(n_local, "AllowedGroupCiphers")) { + // TODO + } else { + errno = ENOENT; + free(n_tmp); + return -1; + } + +out: + free(n_tmp); + return rc; + +out_inval: + errno = EINVAL; + free(n_tmp); return -1; } -int WifiNetwork::setPsk(char *psk) { - errno = ENOSYS; - return -1; +const char *WifiNetwork::get(const char *name, char *buffer, size_t maxsize) { + char *n_tmp = strdup(name + strlen("wifi.net.")); + char *n_next = n_tmp; + char *n_local; + char fc[64]; + char rc[128]; + + if (!strsep(&n_next, ".")) // skip net id + goto out_inval; + + if (!(n_local = strsep(&n_next, "."))) + goto out_inval; + + + strncpy(fc, n_local, sizeof(fc)); + rc[0] = '\0'; + if (n_next) + strncpy(rc, n_next, sizeof(rc)); + + free(n_tmp); + + if (!strcasecmp(fc, "enabled")) + snprintf(buffer, maxsize, "%d", getEnabled()); + else if (!strcasecmp(fc, "ssid")) { + strncpy(buffer, + getSsid() ? getSsid() : "none", + maxsize); + } else if (!strcasecmp(fc, "bssid")) { + strncpy(buffer, + getBssid() ? getBssid() : "none", + maxsize); + } else if (!strcasecmp(fc, "psk")) { + strncpy(buffer, + getPsk() ? getPsk() : "none", + maxsize); + } else if (!strcasecmp(fc, "wepkey")) { + strncpy(buffer, + getWepKey(atoi(rc)-1) ? getWepKey(atoi(rc)-1) : "none", + maxsize); + } else if (!strcasecmp(fc, "defkeyidx")) + snprintf(buffer, maxsize, "%d", getDefaultKeyIndex()); + else if (!strcasecmp(fc, "pri")) + snprintf(buffer, maxsize, "%d", getPriority()); + else if (!strcasecmp(fc, "hiddenssid")) { + strncpy(buffer, + getHiddenSsid() ? getHiddenSsid() : "none", + maxsize); + } else { + strncpy(buffer, "(internal error)", maxsize); + errno = ENOENT; + return NULL; + } + + return buffer; + +out_inval: + errno = EINVAL; + free(n_tmp); + return NULL; } -int WifiNetwork::setWepKey(int idx, char *key) { - errno = ENOSYS; - return -1; +int WifiNetwork::setSsid(const char *ssid) { + if (mSuppl->setNetworkVar(mNetid, "ssid", ssid)) + return -1; + if (mSsid) + free(mSsid); + mSsid = strdup(ssid); + return 0; +} + +int WifiNetwork::setBssid(const char *bssid) { + if (mSuppl->setNetworkVar(mNetid, "bssid", bssid)) + return -1; + if (mBssid) + free(mBssid); + mBssid = strdup(bssid); + return 0; +} + +int WifiNetwork::setPsk(const char *psk) { + if (mSuppl->setNetworkVar(mNetid, "psk", psk)) + return -1; + + if (mPsk) + free(mPsk); + mPsk = strdup(psk); + return 0; +} + +int WifiNetwork::setWepKey(int idx, const char *key) { + char *name; + + asprintf(&name, "wep_key%d", idx); + int rc = mSuppl->setNetworkVar(mNetid, name, key); + free(name); + + if (rc) + return -1; + + if (mWepKeys[idx]) + free(mWepKeys[idx]); + mWepKeys[idx] = strdup(key); + return 0; } int WifiNetwork::setDefaultKeyIndex(int idx) { - errno = ENOSYS; - return -1; + char val[16]; + sprintf(val, "%d", idx); + if (mSuppl->setNetworkVar(mNetid, "wep_tx_keyidx", val)) + return -1; + + mDefaultKeyIndex = idx; + return 0; } -int WifiNetwork::setPriority(int idx) { - errno = ENOSYS; - return -1; +int WifiNetwork::setPriority(int priority) { + char val[16]; + sprintf(val, "%d", priority); + if (mSuppl->setNetworkVar(mNetid, "priority", val)) + return -1; + + mPriority = priority; + return 0; } -int WifiNetwork::setHiddenSsid(char *ssid) { - errno = ENOSYS; - return -1; +int WifiNetwork::setHiddenSsid(const char *ssid) { + if (mSuppl->setNetworkVar(mNetid, "scan_ssid", ssid)) + return -1; + + if (mHiddenSsid) + free(mHiddenSsid); + mHiddenSsid = strdup(ssid); + return 0; } int WifiNetwork::setAllowedKeyManagement(uint32_t mask) { - errno = ENOSYS; - return -1; + char accum[255]; + + if (mask == KeyManagementMask::NONE) + strcpy(accum, "NONE"); + else { + if (mask & KeyManagementMask::WPA_PSK) + strcat(accum, "WPA_PSK "); + if (mask & KeyManagementMask::WPA_EAP) + strcat(accum, "WPA_EAP "); + if (mask & KeyManagementMask::IEEE8021X) + strcat(accum, "IEEE8021X "); + } + + if (mSuppl->setNetworkVar(mNetid, "key_mgmt", accum)) + return -1; + mAllowedKeyManagement = mask; + return 0; } int WifiNetwork::setAllowedProtocols(uint32_t mask) { - errno = ENOSYS; - return -1; + char accum[255]; + + accum[0] = '\0'; + + if (mask & SecurityProtocolMask::WPA) + strcpy(accum, "WPA "); + + if (mask & SecurityProtocolMask::RSN) + strcat(accum, "RSN"); + + if (mSuppl->setNetworkVar(mNetid, "proto", accum)) + return -1; + mAllowedProtocols = mask; + return 0; +} + +int WifiNetwork::setAllowedAuthAlgorithms(uint32_t mask) { + char accum[255]; + + accum[0] = '\0'; + + if (mask & AuthenticationAlgorithmMask::OPEN) + strcpy(accum, "OPEN "); + + if (mask & AuthenticationAlgorithmMask::SHARED) + strcat(accum, "SHARED "); + + if (mask & AuthenticationAlgorithmMask::LEAP) + strcat(accum, "LEAP "); + + if (mSuppl->setNetworkVar(mNetid, "auth_alg", accum)) + return -1; + + mAllowedAuthAlgorithms = mask; + return 0; } int WifiNetwork::setAllowedPairwiseCiphers(uint32_t mask) { - errno = ENOSYS; - return -1; + char accum[255]; + + if (mask == PairwiseCiphersMask::NONE) + strcpy(accum, "NONE"); + else { + if (mask & PairwiseCiphersMask::TKIP) + strcat(accum, "TKIP "); + if (mask & PairwiseCiphersMask::CCMP) + strcat(accum, "CCMP "); + } + + if (mSuppl->setNetworkVar(mNetid, "pairwise", accum)) + return -1; + + mAllowedPairwiseCiphers = mask; + return 0; } int WifiNetwork::setAllowedGroupCiphers(uint32_t mask) { - errno = ENOSYS; - return -1; + char accum[255]; + + if (mask & GroupCiphersMask::WEP40) + strcat(accum, "WEP40 "); + if (mask & GroupCiphersMask::WEP104) + strcat(accum, "WEP104 "); + if (mask & GroupCiphersMask::TKIP) + strcat(accum, "TKIP "); + if (mask & GroupCiphersMask::CCMP) + strcat(accum, "CCMP "); + + if (mSuppl->setNetworkVar(mNetid, "group", accum)) + return -1; + mAllowedGroupCiphers = mask; + return 0; +} + +int WifiNetwork::setEnabled(bool enabled) { + if (mSuppl->enableNetwork(mNetid, enabled)) + return -1; + + mEnabled = enabled; + return 0; +} + +int WifiNetwork::registerProperties() { + for (const char **p = WifiNetwork::PropertyNames; *p != '\0'; p++) { + char *tmp; + asprintf(&tmp, "wifi.net.%d.%s", mNetid, *p); + + if (NetworkManager::Instance()->getPropMngr()->registerProperty(tmp, + this)) { + free(tmp); + return -1; + } + free(tmp); + } + return 0; +} + +int WifiNetwork::unregisterProperties() { + for (const char **p = WifiNetwork::PropertyNames; *p != '\0'; p++) { + char *tmp; + asprintf(&tmp, "wifi.net.%d.%s", mNetid, *p); + + if (NetworkManager::Instance()->getPropMngr()->unregisterProperty(tmp)) + LOGW("Unable to remove property '%s' (%s)", tmp, strerror(errno)); + free(tmp); + } + return 0; } |