diff options
author | San Mehat <san@google.com> | 2009-05-12 17:26:28 -0700 |
---|---|---|
committer | San Mehat <san@google.com> | 2009-05-13 09:10:01 -0700 |
commit | 82a2116e6b67db910bba22c4874e6ca5efd3eec0 (patch) | |
tree | 0f08c363327859f3da5128b24743e0974edf5f55 /nexus | |
parent | df6c1b91e3813886070f35929583c30cfaead918 (diff) | |
download | system_core-82a2116e6b67db910bba22c4874e6ca5efd3eec0.zip system_core-82a2116e6b67db910bba22c4874e6ca5efd3eec0.tar.gz system_core-82a2116e6b67db910bba22c4874e6ca5efd3eec0.tar.bz2 |
nexus: Initial support for manipulating wifi networks + change wifi scan notification msgs
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'nexus')
-rw-r--r-- | nexus/Android.mk | 1 | ||||
-rw-r--r-- | nexus/CommandListener.cpp | 138 | ||||
-rw-r--r-- | nexus/CommandListener.h | 35 | ||||
-rw-r--r-- | nexus/ErrorCode.h | 4 | ||||
-rw-r--r-- | nexus/Supplicant.cpp | 35 | ||||
-rw-r--r-- | nexus/Supplicant.h | 8 | ||||
-rw-r--r-- | nexus/WifiController.cpp | 15 | ||||
-rw-r--r-- | nexus/WifiController.h | 12 | ||||
-rw-r--r-- | nexus/WifiNetwork.cpp | 109 | ||||
-rw-r--r-- | nexus/WifiNetwork.h | 174 |
10 files changed, 516 insertions, 15 deletions
diff --git a/nexus/Android.mk b/nexus/Android.mk index 7cf4a1f..42176cf 100644 --- a/nexus/Android.mk +++ b/nexus/Android.mk @@ -20,6 +20,7 @@ LOCAL_SRC_FILES:= \ VpnController.cpp \ ScanResult.cpp \ WifiScanner.cpp \ + WifiNetwork.cpp \ LOCAL_MODULE:= nexus diff --git a/nexus/CommandListener.cpp b/nexus/CommandListener.cpp index 5967550..d9ee971 100644 --- a/nexus/CommandListener.cpp +++ b/nexus/CommandListener.cpp @@ -33,6 +33,11 @@ CommandListener::CommandListener() : registerCmd(new WifiDisableCmd()); registerCmd(new WifiScanCmd()); registerCmd(new WifiScanResultsCmd()); + registerCmd(new WifiListNetworksCmd()); + registerCmd(new WifiAddNetworkCmd()); + registerCmd(new WifiRemoveNetworkCmd()); + registerCmd(new WifiSetVarCmd()); + registerCmd(new WifiGetVarCmd()); registerCmd(new VpnEnableCmd()); registerCmd(new VpnDisableCmd()); @@ -70,13 +75,46 @@ int CommandListener::WifiDisableCmd::runCommand(SocketClient *cli, char *data) { return 0; } +CommandListener::WifiAddNetworkCmd::WifiAddNetworkCmd() : + NexusCommand("wifi_add_network") { +} + +int CommandListener::WifiAddNetworkCmd::runCommand(SocketClient *cli, char *data) { + NetworkManager *nm = NetworkManager::Instance(); + WifiController *wc = (WifiController *) nm->findController("WIFI"); + int networkId; + + if ((networkId = wc->addNetwork()) < 0) + cli->sendMsg(ErrorCode::OperationFailed, "Failed to add network", true); + else { + char tmp[128]; + sprintf(tmp, "Added network id %d.", networkId); + cli->sendMsg(ErrorCode::CommandOkay, tmp, false); + } + return 0; +} + +CommandListener::WifiRemoveNetworkCmd::WifiRemoveNetworkCmd() : + NexusCommand("wifi_remove_network") { +} + +int CommandListener::WifiRemoveNetworkCmd::runCommand(SocketClient *cli, char *data) { + NetworkManager *nm = NetworkManager::Instance(); + WifiController *wc = (WifiController *) nm->findController("WIFI"); + + if (wc->removeNetwork(atoi(data))) + cli->sendMsg(ErrorCode::OperationFailed, "Failed to remove network", true); + else { + cli->sendMsg(ErrorCode::CommandOkay, "Network removed.", false); + } + return 0; +} + CommandListener::WifiScanCmd::WifiScanCmd() : NexusCommand("wifi_scan") { } int CommandListener::WifiScanCmd::runCommand(SocketClient *cli, char *data) { - LOGD("WifiScanCmd(%s)", data); - WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI"); if (wc->setScanMode(atoi(data))) @@ -93,7 +131,6 @@ CommandListener::WifiScanResultsCmd::WifiScanResultsCmd() : int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, char *data) { NetworkManager *nm = NetworkManager::Instance(); - WifiController *wc = (WifiController *) nm->findController("WIFI"); ScanResultCollection *src = wc->createScanResults(); @@ -104,7 +141,7 @@ int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, char *dat sprintf(buffer, "%s:%u:%d:%s:%s", (*it)->getBssid(), (*it)->getFreq(), (*it)->getLevel(), (*it)->getFlags(), (*it)->getSsid()); - cli->sendMsg(125, buffer, false); + cli->sendMsg(ErrorCode::WifiScanResult, buffer, false); delete (*it); it = src->erase(it); } @@ -114,6 +151,99 @@ int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, char *dat return 0; } +CommandListener::WifiListNetworksCmd::WifiListNetworksCmd() : + NexusCommand("wifi_list_networks") { +} + +int CommandListener::WifiListNetworksCmd::runCommand(SocketClient *cli, char *data) { + NetworkManager *nm = NetworkManager::Instance(); + WifiController *wc = (WifiController *) nm->findController("WIFI"); + + WifiNetworkCollection *src = wc->createNetworkList(); + WifiNetworkCollection::iterator it; + char buffer[256]; + + for(it = src->begin(); it != src->end(); ++it) { + sprintf(buffer, "%d:%s", (*it)->getNetworkId(), (*it)->getSsid()); + cli->sendMsg(ErrorCode::WifiNetworkList, buffer, false); + delete (*it); + it = src->erase(it); + } + + delete src; + cli->sendMsg(ErrorCode::CommandOkay, "Network listing complete.", false); + return 0; +} + +CommandListener::WifiSetVarCmd::WifiSetVarCmd() : + NexusCommand("wifi_setvar") { +} + +int CommandListener::WifiSetVarCmd::runCommand(SocketClient *cli, char *data) { + WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI"); + + char *bword; + char *last; + char varname[32]; + char val[250]; + int networkId; + + if (!(bword = strtok_r(data, ":", &last))) + goto out_inval; + + networkId = atoi(bword); + + if (!(bword = strtok_r(NULL, ":", &last))) + goto out_inval; + + strncpy(varname, bword, sizeof(varname)); + + if (!(bword = strtok_r(NULL, ":", &last))) + goto out_inval; + + strncpy(val, bword, sizeof(val)); + + LOGD("Network id %d, varname '%s', value '%s'", networkId, varname, val); + + return 0; + +out_inval: + errno = EINVAL; + cli->sendMsg(ErrorCode::CommandParameterError, "Failed to set variable.", true); + return 0; +} + +CommandListener::WifiGetVarCmd::WifiGetVarCmd() : + NexusCommand("wifi_getvar") { +} + +int CommandListener::WifiGetVarCmd::runCommand(SocketClient *cli, char *data) { + WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI"); + + char *bword; + char *last; + char varname[32]; + int networkId; + + if (!(bword = strtok_r(data, ":", &last))) + goto out_inval; + + networkId = atoi(bword); + + if (!(bword = strtok_r(NULL, ":", &last))) + goto out_inval; + + strncpy(varname, bword, sizeof(varname)); + + LOGD("networkId = %d, varname '%s'", networkId, varname); + + return 0; +out_inval: + errno = EINVAL; + cli->sendMsg(ErrorCode::CommandParameterError, "Failed to get variable.", true); + return 0; +} + /* ------------ * Vpn Commands * ------------ */ diff --git a/nexus/CommandListener.h b/nexus/CommandListener.h index 064eab8..7bc89e3 100644 --- a/nexus/CommandListener.h +++ b/nexus/CommandListener.h @@ -53,6 +53,41 @@ private: int runCommand(SocketClient *c, char *data); }; + class WifiAddNetworkCmd : public NexusCommand { + public: + WifiAddNetworkCmd(); + virtual ~WifiAddNetworkCmd() {} + int runCommand(SocketClient *c, char *data); + }; + + class WifiRemoveNetworkCmd : public NexusCommand { + public: + WifiRemoveNetworkCmd(); + virtual ~WifiRemoveNetworkCmd() {} + int runCommand(SocketClient *c, char *data); + }; + + class WifiListNetworksCmd : public NexusCommand { + public: + WifiListNetworksCmd(); + virtual ~WifiListNetworksCmd() {} + int runCommand(SocketClient *c, char *data); + }; + + class WifiSetVarCmd : public NexusCommand { + public: + WifiSetVarCmd(); + virtual ~WifiSetVarCmd() {} + int runCommand(SocketClient *c, char *data); + }; + + class WifiGetVarCmd : public NexusCommand { + public: + WifiGetVarCmd(); + virtual ~WifiGetVarCmd() {} + int runCommand(SocketClient *c, char *data); + }; + class VpnEnableCmd : public NexusCommand { public: VpnEnableCmd(); diff --git a/nexus/ErrorCode.h b/nexus/ErrorCode.h index dd2ea3b..8ca6cae 100644 --- a/nexus/ErrorCode.h +++ b/nexus/ErrorCode.h @@ -23,6 +23,9 @@ public: // before proceeding with a new command. static const int ActionInitiated = 100; + static const int WifiScanResult = 125; + static const int WifiNetworkList = 126; + // 200 series - Requested action has been successfully completed static const int CommandOkay = 200; @@ -33,6 +36,7 @@ public: // 500 series - The command was not accepted and the requested // action did not take place. static const int CommandSyntaxError = 500; + static const int CommandParameterError = 501; // 600 series - Unsolicited broadcasts static const int UnsolicitedInformational = 600; diff --git a/nexus/Supplicant.cpp b/nexus/Supplicant.cpp index 9443598..22964bb 100644 --- a/nexus/Supplicant.cpp +++ b/nexus/Supplicant.cpp @@ -229,7 +229,7 @@ int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len) return -1; } -// LOGD("sendCommand(): -> '%s'", cmd); + LOGD("sendCommand(): -> '%s'", cmd); int rc; if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) { @@ -245,7 +245,7 @@ int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len) !strncmp(cmd, "SCAN_RESULTS", 12)) reply[*reply_len] = '\0'; -// LOGD("sendCommand(): <- '%s'", reply); + LOGD("sendCommand(): <- '%s'", reply); return 0; } @@ -355,7 +355,7 @@ int Supplicant::onScanResultsEvent(SupplicantEvent *evt) { mLatestScanResults->push_back(new ScanResult(linep)); char tmp[128]; - sprintf(tmp, "%d scan results ready", mLatestScanResults->size()); + sprintf(tmp, "Scan results ready (%d)", mLatestScanResults->size()); NetworkManager::Instance()->getBroadcaster()-> sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false); pthread_mutex_unlock(&mLatestScanResultsLock); @@ -412,6 +412,35 @@ ScanResultCollection *Supplicant::createLatestScanResults() { return d; } +WifiNetworkCollection *Supplicant::createNetworkList() { + WifiNetworkCollection *d = new WifiNetworkCollection(); + return d; +} + +int Supplicant::addNetwork() { + char reply[32]; + size_t len = sizeof(reply) -1; + + memset(reply, 0, sizeof(reply)); + if (sendCommand("ADD_NETWORK", reply, &len)) + return -1; + + return atoi(reply); +} + +int Supplicant::removeNetwork(int networkId) { + char req[64]; + + sprintf(req, "REMOVE_NETWORK %d", networkId); + char reply[32]; + size_t len = sizeof(reply) -1; + memset(reply, 0, sizeof(reply)); + + if (sendCommand(req, reply, &len)) + return -1; + return 0; +} + int Supplicant::setupConfig() { char buf[2048]; int srcfd, destfd; diff --git a/nexus/Supplicant.h b/nexus/Supplicant.h index 579bfd6..4a7ec3a 100644 --- a/nexus/Supplicant.h +++ b/nexus/Supplicant.h @@ -23,6 +23,7 @@ class SupplicantEvent; #include <pthread.h> #include "ScanResult.h" +#include "WifiNetwork.h" class Supplicant { private: @@ -41,10 +42,13 @@ public: int start(); int stop(); bool isStarted(); - int triggerScan(bool active); + int triggerScan(bool active); ScanResultCollection *createLatestScanResults(); - WifiNetworkCollection *createWifiNetworkList(); + + int addNetwork(); + int removeNetwork(int networkId); + WifiNetworkCollection *createNetworkList(); int getState() { return mState; } diff --git a/nexus/WifiController.cpp b/nexus/WifiController.cpp index f67761a..126db69 100644 --- a/nexus/WifiController.cpp +++ b/nexus/WifiController.cpp @@ -23,7 +23,7 @@ #include "WifiController.h" #include "WifiScanner.h" #include "NetworkManager.h" -#include "ErrorCode.h"; +#include "ErrorCode.h" WifiController::WifiController(char *modpath, char *modname, char *modargs) : Controller("WIFI") { @@ -151,6 +151,19 @@ int WifiController::setScanMode(uint32_t mode) { return rc; } +int WifiController::addNetwork() { + return mSupplicant->addNetwork(); +} + +int WifiController::removeNetwork(int networkId) { + return mSupplicant->removeNetwork(networkId); +} + ScanResultCollection *WifiController::createScanResults() { return mSupplicant->createLatestScanResults(); } + +// XXX: This should be a const list +WifiNetworkCollection *WifiController::createNetworkList() { + return mSupplicant->createNetworkList(); +} diff --git a/nexus/WifiController.h b/nexus/WifiController.h index ba26cb8..b9c981c 100644 --- a/nexus/WifiController.h +++ b/nexus/WifiController.h @@ -25,6 +25,7 @@ class Supplicant; class WifiScanner; #include "ScanResult.h" +#include "WifiNetwork.h" class WifiController : public Controller { public: @@ -56,9 +57,13 @@ public: int enable(); int disable(); - ScanResultCollection *createScanResults(); + int addNetwork(); + int removeNetwork(int networkId); + WifiNetworkCollection *createNetworkList(); - int getType(); + int getScanMode() { return mCurrentScanMode; } + int setScanMode(uint32_t mode); + ScanResultCollection *createScanResults(); char *getModulePath() { return mModulePath; } char *getModuleName() { return mModuleName; } @@ -66,9 +71,6 @@ public: Supplicant *getSupplicant() { return mSupplicant; } - int getScanMode() { return mCurrentScanMode; } - int setScanMode(uint32_t mode); - protected: virtual int powerUp() = 0; virtual int powerDown() = 0; diff --git a/nexus/WifiNetwork.cpp b/nexus/WifiNetwork.cpp new file mode 100644 index 0000000..ef013c0 --- /dev/null +++ b/nexus/WifiNetwork.cpp @@ -0,0 +1,109 @@ +/* + * 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 <errno.h> +#include <string.h> +#include <sys/types.h> + +#include "WifiNetwork.h" +#include "Supplicant.h" + +WifiNetwork::WifiNetwork(Supplicant *suppl) { + mSuppl = suppl; + mNetid = -1; + mSsid = NULL; + mBssid = NULL; + mPsk = NULL; + memset(mWepKeys, 0, sizeof(mWepKeys)); + mDefaultKeyIndex = -1; + mPriority = -1; + mHiddenSsid = NULL; + mAllowedKeyManagement = 0; + mAllowedProtocols = 0; + mAllowedAuthAlgorithms = 0; + mAllowedPairwiseCiphers = 0; + mAllowedGroupCiphers = 0; +} + +WifiNetwork::~WifiNetwork() { + if (mSsid) + free(mSsid); + if (mBssid) + free(mBssid); + if (mPsk) + free(mPsk); + for (int i = 0; i < 4; i++) { + if (mWepKeys[i]) + free(mWepKeys[i]); + } + if (mHiddenSsid) + free(mHiddenSsid); +} + +int WifiNetwork::setSsid(char *ssid) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setBssid(char *bssid) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setPsk(char *psk) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setWepKey(int idx, char *key) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setDefaultKeyIndex(int idx) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setPriority(int idx) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setHiddenSsid(char *ssid) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setAllowedKeyManagement(uint32_t mask) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setAllowedProtocols(uint32_t mask) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setAllowedPairwiseCiphers(uint32_t mask) { + errno = ENOSYS; + return -1; +} + +int WifiNetwork::setAllowedGroupCiphers(uint32_t mask) { + errno = ENOSYS; + return -1; +} diff --git a/nexus/WifiNetwork.h b/nexus/WifiNetwork.h new file mode 100644 index 0000000..1354730 --- /dev/null +++ b/nexus/WifiNetwork.h @@ -0,0 +1,174 @@ +/* + * 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. + */ + +#ifndef _WIFI_NETWORK_H +#define _WIFI_NETWORK_H + +#include <sys/types.h> + +#include "../../../frameworks/base/include/utils/List.h" + +class KeyManagementMask { +public: + static const uint32_t NONE = 0; + static const uint32_t WPA_PSK = 0x01; + static const uint32_t WPA_EAP = 0x02; + static const uint32_t IEEE8021X = 0x04; + static const uint32_t ALL = WPA_PSK | WPA_EAP | IEEE8021X; +}; + +class SecurityProtocolMask { +public: + static const uint32_t WPA = 0x01; + static const uint32_t RSN = 0x02; +}; + +class AuthenticationAlgorithmMask { +public: + static const uint32_t OPEN = 0x01; + static const uint32_t SHARED = 0x02; + static const uint32_t LEAP = 0x04; +}; + +class PairwiseCipherMask { +public: + static const uint32_t NONE = 0x00; + static const uint32_t TKIP = 0x01; + static const uint32_t CCMP = 0x02; +}; + +class GroupCipherMask { +public: + static const uint32_t WEP40 = 0x01; + static const uint32_t WEP104 = 0x02; + static const uint32_t TKIP = 0x04; + static const uint32_t CCMP = 0x08; +}; + +class Supplicant; + +class WifiNetwork { + Supplicant *mSuppl; + + /* + * Unique network id - normally provided by supplicant + */ + int mNetid; + + /* + * The networks' SSID. Can either be an ASCII string, + * which must be enclosed in double quotation marks + * (ie: "MyNetwork"), or a string of hex digits which + * are not enclosed in quotes (ie: 01ab7893) + */ + char *mSsid; + + /* + * When set, this entry should only be used + * when associating with the AP having the specified + * BSSID. The value is a string in the format of an + * Ethernet MAC address + */ + char *mBssid; + + /* + * Pre-shared key for use with WPA-PSK + */ + char *mPsk; + + /* + * Up to four WEP keys. Either in ASCII string enclosed in + * double quotes, or a string of hex digits + */ + char *mWepKeys[4]; + + /* + * Default WEP key index, ranging from 0 -> NUM_WEP_KEYS -1 + */ + int mDefaultKeyIndex; + + /* + * Priority determines the preference given to a network by + * supplicant when choosing an access point with which + * to associate + */ + int mPriority; + + /* + * This is a network that does not broadcast it's SSID, so an + * SSID-specific probe request must be used for scans. + */ + char *mHiddenSsid; + + /* + * The set of key management protocols supported by this configuration. + */ + uint32_t mAllowedKeyManagement; + + /* + * The set of security protocols supported by this configuration. + */ + uint32_t mAllowedProtocols; + + /* + * The set of authentication protocols supported by this configuration. + */ + uint32_t mAllowedAuthAlgorithms; + + /* + * The set of pairwise ciphers for WPA supported by this configuration. + */ + uint32_t mAllowedPairwiseCiphers; + + /* + * The set of group ciphers for WPA supported by this configuration. + */ + uint32_t mAllowedGroupCiphers; + +public: + WifiNetwork(Supplicant *suppl); + virtual ~WifiNetwork(); + + int getNetworkId() { return mNetid; } + const char *getSsid() { return mSsid; } + const char *getBssid() { return mBssid; } + const char *getPsk() { return mPsk; } + const char *getWepKey(int idx) { return mWepKeys[idx]; } + int getDefaultKeyIndex() { return mDefaultKeyIndex; } + int getPriority() { return mPriority; } + const char *getHiddenSsid() { return mHiddenSsid; } + uint32_t getAllowedKeyManagement() { return mAllowedKeyManagement; } + uint32_t getAllowedProtocols() { return mAllowedProtocols; } + uint32_t getAllowedAuthAlgorithms() { return mAllowedAuthAlgorithms; } + uint32_t getAllowedPairwiseCiphers() { return mAllowedPairwiseCiphers; } + uint32_t getAllowedGroupCiphers() { return mAllowedGroupCiphers; } + + int setSsid(char *ssid); + int setBssid(char *bssid); + int setPsk(char *psk); + int setWepKey(int idx, char *key); + int setDefaultKeyIndex(int idx); + int setPriority(int pri); + int setHiddenSsid(char *ssid); + int setAllowedKeyManagement(uint32_t mask); + int setAllowedProtocols(uint32_t mask); + int setAllowedPairwiseCiphers(uint32_t mask); + int setAllowedGroupCiphers(uint32_t mask); +}; + +typedef android::List<WifiNetwork *> WifiNetworkCollection; + +#endif |