diff options
author | San Mehat <san@google.com> | 2009-06-15 14:10:44 -0700 |
---|---|---|
committer | San Mehat <san@google.com> | 2009-06-15 14:20:02 -0700 |
commit | 3aff2d1de59972684bf2ab798351be5544158239 (patch) | |
tree | e16fdc00ec3615dc4257ef1b57b2d0f49437fdcf /nexus | |
parent | 669a7011e7e23c0594242465caa15b46b92aa340 (diff) | |
download | system_core-3aff2d1de59972684bf2ab798351be5544158239.zip system_core-3aff2d1de59972684bf2ab798351be5544158239.tar.gz system_core-3aff2d1de59972684bf2ab798351be5544158239.tar.bz2 |
Nexus: Clean up supplicant events, protocol, and continue plumbing
- Create SupplicantEvent classes for events
- New SupplicantEventFactory for creating events
- Extract Controller -> NetworkManager callbacks into IControllerHandler
- Move ScanResult handling from Supplicant -> WifiController
- Plumb more 'onConnected()' code
- Instead of re-creating NetworkList every-time, merge in
new entries
- Extract SupplicantListener -> Supplicant callbacks into
ISupplicantEventHandler
- Move SupplicantListener callback handling to WifiController
- Add unlocked version of lookupNetwork()
- Save supplicant config after setting a WifiNetwork variable
- Move property registration from WifiNetwork -> Supplicant
- Change wifi enable broadcast messages
- Add 3 new events: 'onAssociating', 'onAssociated', 'onConnectionTimeout'
- Add support for handling KeyManagement
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'nexus')
47 files changed, 1471 insertions, 501 deletions
diff --git a/nexus/Android.mk b/nexus/Android.mk index bd4e3d4..6172e62 100644 --- a/nexus/Android.mk +++ b/nexus/Android.mk @@ -5,26 +5,35 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_SRC_FILES:= \ - main.cpp \ - NetworkManager.cpp \ - CommandListener.cpp \ - Controller.cpp \ - WifiController.cpp \ - LoopController.cpp \ - NexusCommand.cpp \ - TiwlanWifiController.cpp \ - Supplicant.cpp \ - SupplicantEvent.cpp \ - SupplicantListener.cpp \ - VpnController.cpp \ - ScanResult.cpp \ - WifiScanner.cpp \ - WifiNetwork.cpp \ - OpenVpnController.cpp \ - InterfaceConfig.cpp \ - PropertyManager.cpp \ - SupplicantState.cpp +LOCAL_SRC_FILES:= \ + main.cpp \ + NetworkManager.cpp \ + CommandListener.cpp \ + Controller.cpp \ + WifiController.cpp \ + LoopController.cpp \ + NexusCommand.cpp \ + TiwlanWifiController.cpp \ + Supplicant.cpp \ + SupplicantEvent.cpp \ + SupplicantListener.cpp \ + VpnController.cpp \ + ScanResult.cpp \ + WifiScanner.cpp \ + WifiNetwork.cpp \ + OpenVpnController.cpp \ + InterfaceConfig.cpp \ + PropertyManager.cpp \ + SupplicantState.cpp \ + SupplicantEventFactory.cpp \ + SupplicantConnectedEvent.cpp \ + SupplicantAssociatingEvent.cpp \ + SupplicantAssociatedEvent.cpp \ + SupplicantStateChangeEvent.cpp \ + SupplicantScanResultsEvent.cpp \ + SupplicantConnectionTimeoutEvent.cpp \ + SupplicantDisconnectedEvent.cpp \ + SupplicantStatus.cpp LOCAL_MODULE:= nexus diff --git a/nexus/CommandListener.cpp b/nexus/CommandListener.cpp index e8de7f5..8eb378b 100644 --- a/nexus/CommandListener.cpp +++ b/nexus/CommandListener.cpp @@ -53,7 +53,8 @@ CommandListener::WifiCreateNetworkCmd::WifiCreateNetworkCmd() : NexusCommand("wifi_create_network") { } -int CommandListener::WifiCreateNetworkCmd::runCommand(SocketClient *cli, char *data) { +int CommandListener::WifiCreateNetworkCmd::runCommand(SocketClient *cli, + int argc, char **argv) { NetworkManager *nm = NetworkManager::Instance(); WifiController *wc = (WifiController *) nm->findController("WIFI"); WifiNetwork *wn; @@ -72,11 +73,12 @@ CommandListener::WifiRemoveNetworkCmd::WifiRemoveNetworkCmd() : NexusCommand("wifi_remove_network") { } -int CommandListener::WifiRemoveNetworkCmd::runCommand(SocketClient *cli, char *data) { +int CommandListener::WifiRemoveNetworkCmd::runCommand(SocketClient *cli, + int argc, char **argv) { NetworkManager *nm = NetworkManager::Instance(); WifiController *wc = (WifiController *) nm->findController("WIFI"); - if (wc->removeNetwork(atoi(data))) + if (wc->removeNetwork(atoi(argv[1]))) cli->sendMsg(ErrorCode::OperationFailed, "Failed to remove network", true); else { cli->sendMsg(ErrorCode::CommandOkay, "Network removed.", false); @@ -88,7 +90,8 @@ CommandListener::WifiScanResultsCmd::WifiScanResultsCmd() : NexusCommand("wifi_scan_results") { } -int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, char *data) { +int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, + int argc, char **argv) { NetworkManager *nm = NetworkManager::Instance(); WifiController *wc = (WifiController *) nm->findController("WIFI"); @@ -114,7 +117,8 @@ CommandListener::WifiListNetworksCmd::WifiListNetworksCmd() : NexusCommand("wifi_list_networks") { } -int CommandListener::WifiListNetworksCmd::runCommand(SocketClient *cli, char *data) { +int CommandListener::WifiListNetworksCmd::runCommand(SocketClient *cli, + int argc, char **argv) { NetworkManager *nm = NetworkManager::Instance(); WifiController *wc = (WifiController *) nm->findController("WIFI"); @@ -144,23 +148,19 @@ CommandListener::GetCmd::GetCmd() : NexusCommand("get") { } -int CommandListener::GetCmd::runCommand(SocketClient *cli, char *data) { - char *next = data; - char *propname; +int CommandListener::GetCmd::runCommand(SocketClient *cli, int argc, char **argv) { + char val[Property::ValueMaxSize]; - if (!(propname = strsep(&next, ":"))) - goto out_inval; - - char pb[Property::NameMaxSize + 6]; - snprintf(pb, sizeof(pb), "%s:", propname); - - if (!NetworkManager::Instance()->getPropMngr()->get(propname, - &pb[strlen(pb)], - sizeof(pb) - strlen(pb))) { + if (!NetworkManager::Instance()->getPropMngr()->get(argv[1], + val, + sizeof(val))) { goto out_inval; } - cli->sendMsg(ErrorCode::PropertyRead, pb, false); + char *tmp; + asprintf(&tmp, "%s %s", argv[1], val); + cli->sendMsg(ErrorCode::PropertyRead, tmp, false); + free(tmp); cli->sendMsg(ErrorCode::CommandOkay, "Property read.", false); return 0; @@ -174,23 +174,9 @@ CommandListener::SetCmd::SetCmd() : NexusCommand("set") { } -int CommandListener::SetCmd::runCommand(SocketClient *cli, char *data) { - char *bword; - char *last; - char propname[Property::NameMaxSize]; - char propval[Property::ValueMaxSize]; - - if (!(bword = strtok_r(data, ":", &last))) - goto out_inval; - - strncpy(propname, bword, sizeof(propname)); - - if (!(bword = strtok_r(NULL, ":", &last))) - goto out_inval; - - strncpy(propval, bword, sizeof(propval)); - - if (NetworkManager::Instance()->getPropMngr()->set(propname, propval)) +int CommandListener::SetCmd::runCommand(SocketClient *cli, int argc, + char **argv) { + if (NetworkManager::Instance()->getPropMngr()->set(argv[1], argv[2])) goto out_inval; cli->sendMsg(ErrorCode::CommandOkay, "Property set.", false); @@ -206,7 +192,7 @@ CommandListener::ListCmd::ListCmd() : NexusCommand("list") { } -int CommandListener::ListCmd::runCommand(SocketClient *cli, char *data) { +int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **argv) { android::List<char *> *pc; if (!(pc = NetworkManager::Instance()->getPropMngr()->createPropertyList())) { @@ -227,7 +213,7 @@ int CommandListener::ListCmd::runCommand(SocketClient *cli, char *data) { } char *buf; - if (asprintf(&buf, "%s:%s", (*it), p_v) < 0) { + if (asprintf(&buf, "%s %s", (*it), p_v) < 0) { LOGE("Failed to allocate memory"); free((*it)); continue; diff --git a/nexus/CommandListener.h b/nexus/CommandListener.h index b57c25f..30c6dc0 100644 --- a/nexus/CommandListener.h +++ b/nexus/CommandListener.h @@ -31,56 +31,56 @@ private: public: WifiScanCmd(); virtual ~WifiScanCmd() {} - int runCommand(SocketClient *c, char *data); + int runCommand(SocketClient *c, int argc, char ** argv); }; class WifiScanResultsCmd : public NexusCommand { public: WifiScanResultsCmd(); virtual ~WifiScanResultsCmd() {} - int runCommand(SocketClient *c, char *data); + int runCommand(SocketClient *c, int argc, char ** argv); }; class WifiCreateNetworkCmd : public NexusCommand { public: WifiCreateNetworkCmd(); virtual ~WifiCreateNetworkCmd() {} - int runCommand(SocketClient *c, char *data); + int runCommand(SocketClient *c, int argc, char ** argv); }; class WifiRemoveNetworkCmd : public NexusCommand { public: WifiRemoveNetworkCmd(); virtual ~WifiRemoveNetworkCmd() {} - int runCommand(SocketClient *c, char *data); + int runCommand(SocketClient *c, int argc, char ** argv); }; class WifiListNetworksCmd : public NexusCommand { public: WifiListNetworksCmd(); virtual ~WifiListNetworksCmd() {} - int runCommand(SocketClient *c, char *data); + int runCommand(SocketClient *c, int argc, char ** argv); }; class SetCmd : public NexusCommand { public: SetCmd(); virtual ~SetCmd() {} - int runCommand(SocketClient *c, char *data); + int runCommand(SocketClient *c, int argc, char ** argv); }; class GetCmd : public NexusCommand { public: GetCmd(); virtual ~GetCmd() {} - int runCommand(SocketClient *c, char *data); + int runCommand(SocketClient *c, int argc, char ** argv); }; class ListCmd : public NexusCommand { public: ListCmd(); virtual ~ListCmd() {} - int runCommand(SocketClient *c, char *data); + int runCommand(SocketClient *c, int argc, char ** argv); }; }; diff --git a/nexus/Controller.cpp b/nexus/Controller.cpp index 9d4ff3c..17fb519 100644 --- a/nexus/Controller.cpp +++ b/nexus/Controller.cpp @@ -34,9 +34,11 @@ extern "C" int init_module(void *, unsigned int, const char *); extern "C" int delete_module(const char *, unsigned int); -Controller::Controller(const char *name, PropertyManager *propMngr) { +Controller::Controller(const char *name, PropertyManager *propMngr, + IControllerHandler *handlers) { mPropMngr = propMngr; mName = strdup(name); + mHandlers = handlers; mBoundInterface = NULL; } diff --git a/nexus/Controller.h b/nexus/Controller.h index 9137f9a..af03d2e 100644 --- a/nexus/Controller.h +++ b/nexus/Controller.h @@ -23,12 +23,12 @@ #include <utils/List.h> class PropertyManager; +class IControllerHandler; #include "PropertyManager.h" #include "IPropertyProvider.h" class Controller : public IPropertyProvider { -private: /* * Name of this controller - WIFI/VPN/USBNET/BTNET/BTDUN/LOOP/etc */ @@ -42,9 +42,11 @@ private: protected: PropertyManager *mPropMngr; + IControllerHandler *mHandlers; public: - Controller(const char *name, PropertyManager *propMngr); + Controller(const char *name, PropertyManager *propMngr, + IControllerHandler *handlers); virtual ~Controller(); virtual int start(); diff --git a/nexus/IControllerHandler.h b/nexus/IControllerHandler.h new file mode 100644 index 0000000..92d015f --- /dev/null +++ b/nexus/IControllerHandler.h @@ -0,0 +1,30 @@ +/* + * 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 _ICONTROLLER_HANDLER_H +#define _ICONTROLLER_HANDLER_H + +class Controller; +class InterfaceConfig; + +class IControllerHandler { +public: + virtual void onInterfaceStarted(Controller *c, const InterfaceConfig *cfg) = 0; + virtual void onInterfaceStopping(Controller *c, const char *name) = 0; +}; + +#endif + diff --git a/nexus/ISupplicantEventHandler.h b/nexus/ISupplicantEventHandler.h index 7e1bd5a..b7fd17b 100644 --- a/nexus/ISupplicantEventHandler.h +++ b/nexus/ISupplicantEventHandler.h @@ -17,21 +17,34 @@ #ifndef _ISUPPLICANT_EVENT_HANDLER_H #define _ISUPPLICANT_EVENT_HANDLER_H +class SupplicantAssociatingEvent; +class SupplicantAssociatedEvent; +class SupplicantConnectedEvent; +class SupplicantScanResultsEvent; +class SupplicantStateChangeEvent; +class SupplicantConnectionTimeoutEvent; +class SupplicantDisconnectedEvent; + class ISupplicantEventHandler { public: - virtual int onConnectedEvent(SupplicantEvent *evt) = 0; - virtual int onDisconnectedEvent(SupplicantEvent *evt) = 0; - virtual int onTerminatingEvent(SupplicantEvent *evt) = 0; - virtual int onPasswordChangedEvent(SupplicantEvent *evt) = 0; - virtual int onEapNotificationEvent(SupplicantEvent *evt) = 0; - virtual int onEapStartedEvent(SupplicantEvent *evt) = 0; - virtual int onEapMethodEvent(SupplicantEvent *evt) = 0; - virtual int onEapSuccessEvent(SupplicantEvent *evt) = 0; - virtual int onEapFailureEvent(SupplicantEvent *evt) = 0; - virtual int onScanResultsEvent(SupplicantEvent *evt) = 0; - virtual int onStateChangeEvent(SupplicantEvent *evt) = 0; - virtual int onLinkSpeedEvent(SupplicantEvent *evt) = 0; - virtual int onDriverStateEvent(SupplicantEvent *evt) = 0; + virtual void onAssociatingEvent(SupplicantAssociatingEvent *evt) = 0; + virtual void onAssociatedEvent(SupplicantAssociatedEvent *evt) = 0; + virtual void onConnectedEvent(SupplicantConnectedEvent *evt) = 0; + virtual void onScanResultsEvent(SupplicantScanResultsEvent *evt) = 0; + virtual void onStateChangeEvent(SupplicantStateChangeEvent *evt) = 0; + virtual void onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) = 0; + virtual void onDisconnectedEvent(SupplicantDisconnectedEvent *evt) = 0; +#if 0 + virtual void onTerminatingEvent(SupplicantEvent *evt) = 0; + virtual void onPasswordChangedEvent(SupplicantEvent *evt) = 0; + virtual void onEapNotificationEvent(SupplicantEvent *evt) = 0; + virtual void onEapStartedEvent(SupplicantEvent *evt) = 0; + virtual void onEapMethodEvent(SupplicantEvent *evt) = 0; + virtual void onEapSuccessEvent(SupplicantEvent *evt) = 0; + virtual void onEapFailureEvent(SupplicantEvent *evt) = 0; + virtual void onLinkSpeedEvent(SupplicantEvent *evt) = 0; + virtual void onDriverStateEvent(SupplicantEvent *evt) = 0; +#endif }; #endif diff --git a/nexus/LoopController.cpp b/nexus/LoopController.cpp index a86202a..5cfb1fe 100644 --- a/nexus/LoopController.cpp +++ b/nexus/LoopController.cpp @@ -19,8 +19,9 @@ #include "LoopController.h" #include "PropertyManager.h" -LoopController::LoopController(PropertyManager *propmngr) : - Controller("LOOP", propmngr) { +LoopController::LoopController(PropertyManager *propmngr, + IControllerHandler *handlers) : + Controller("LOOP", propmngr, handlers) { } int LoopController::set(const char *name, const char *value) { diff --git a/nexus/LoopController.h b/nexus/LoopController.h index bb8314f..53d16f1 100644 --- a/nexus/LoopController.h +++ b/nexus/LoopController.h @@ -19,10 +19,11 @@ #include "Controller.h" +class ControllerHandler; class LoopController : public Controller { public: - LoopController(PropertyManager *propmngr); + LoopController(PropertyManager *propmngr, IControllerHandler *h); virtual ~LoopController() {} int set(const char *name, const char *value); diff --git a/nexus/NetworkManager.cpp b/nexus/NetworkManager.cpp index f4ae88f..2f13a40 100644 --- a/nexus/NetworkManager.cpp +++ b/nexus/NetworkManager.cpp @@ -89,23 +89,26 @@ Controller *NetworkManager::findController(const char *name) { return NULL; } -int NetworkManager::onInterfaceStart(Controller *c, const InterfaceConfig *cfg) { +void NetworkManager::onInterfaceStarted(Controller *c, const InterfaceConfig *cfg) { LOGD("Interface %s started by controller %s", c->getBoundInterface(), c->getName()); // Look up the interface if (0) { // already started? - errno = EADDRINUSE; - return -1; } - if (cfg->getUseDhcp()) { + if (cfg) { + if (cfg->getUseDhcp()) { + // Launch DHCP thread + } else { + // Static configuration + } } else { + LOGD("No InterfaceConfig for %s:%s - assuming self-managed", + c->getName(), c->getBoundInterface()); } - return 0; } -int NetworkManager::onInterfaceStop(Controller *c, const char *name) { +void NetworkManager::onInterfaceStopping(Controller *c, const char *name) { LOGD("Interface %s stopped by controller %s", name, c->getName()); - return 0; } diff --git a/nexus/NetworkManager.h b/nexus/NetworkManager.h index e75382d..edc80c9 100644 --- a/nexus/NetworkManager.h +++ b/nexus/NetworkManager.h @@ -20,12 +20,12 @@ #include <sysutils/SocketListener.h> #include "Controller.h" - #include "PropertyManager.h" +#include "IControllerHandler.h" class InterfaceConfig; -class NetworkManager { +class NetworkManager : public IControllerHandler { private: static NetworkManager *sInstance; @@ -55,16 +55,7 @@ private: NetworkManager(PropertyManager *propMngr); -public: - /* - * Called from a controller when an interface is available/ready for use. - * 'cfg' contains information on how this interface should be configured. - */ - int onInterfaceStart(Controller *c, const InterfaceConfig *cfg); - - /* - * Called from a controller when an interface should be shut down - */ - int onInterfaceStop(Controller *c, const char *name); + void onInterfaceStarted(Controller *c, const InterfaceConfig *cfg); + void onInterfaceStopping(Controller *c, const char *name); }; #endif diff --git a/nexus/OpenVpnController.cpp b/nexus/OpenVpnController.cpp index 4c144a4..f1ea510 100644 --- a/nexus/OpenVpnController.cpp +++ b/nexus/OpenVpnController.cpp @@ -30,8 +30,9 @@ #define DAEMON_PROP_NAME "vpn.openvpn.status" #define DAEMON_CONFIG_FILE "/data/misc/openvpn/openvpn.conf" -OpenVpnController::OpenVpnController(PropertyManager *propmngr) : - VpnController(propmngr) { +OpenVpnController::OpenVpnController(PropertyManager *propmngr, + IControllerHandler *handlers) : + VpnController(propmngr, handlers) { mServiceManager = new ServiceManager(); } @@ -40,11 +41,11 @@ OpenVpnController::~OpenVpnController() { } int OpenVpnController::start() { - return 0; + return VpnController::start(); } int OpenVpnController::stop() { - return 0; + return VpnController::stop(); } int OpenVpnController::enable() { diff --git a/nexus/OpenVpnController.h b/nexus/OpenVpnController.h index 323c44c..529aab5 100644 --- a/nexus/OpenVpnController.h +++ b/nexus/OpenVpnController.h @@ -21,13 +21,14 @@ #include "VpnController.h" class ServiceManager; +class IControllerHandler; class OpenVpnController : public VpnController { private: ServiceManager *mServiceManager; public: - OpenVpnController(PropertyManager *propmngr); + OpenVpnController(PropertyManager *propmngr, IControllerHandler *handlers); virtual ~OpenVpnController(); int start(); diff --git a/nexus/PropertyManager.cpp b/nexus/PropertyManager.cpp index 3366bab..6faf9b8 100644 --- a/nexus/PropertyManager.cpp +++ b/nexus/PropertyManager.cpp @@ -37,7 +37,8 @@ int PropertyManager::registerProperty(const char *name, IPropertyProvider *pp) { for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) { if (!strcmp(name, (*it)->getName())) { errno = EADDRINUSE; - LOGE("Failed to register property (%s)", strerror(errno)); + LOGE("Failed to register property %s (%s)", + name, strerror(errno)); pthread_mutex_unlock(&mLock); return -1; } diff --git a/nexus/Supplicant.cpp b/nexus/Supplicant.cpp index e69f2c0..9bb6bf2 100644 --- a/nexus/Supplicant.cpp +++ b/nexus/Supplicant.cpp @@ -29,13 +29,10 @@ #include "Supplicant.h" #include "SupplicantListener.h" -#include "SupplicantState.h" -#include "SupplicantEvent.h" -#include "ScanResult.h" -#include "PropertyManager.h" #include "NetworkManager.h" #include "ErrorCode.h" #include "WifiController.h" +#include "SupplicantStatus.h" #include "libwpa_client/wpa_ctrl.h" @@ -45,21 +42,16 @@ #define SUPP_CONFIG_TEMPLATE "/system/etc/wifi/wpa_supplicant.conf" #define SUPP_CONFIG_FILE "/data/misc/wifi/wpa_supplicant.conf" -Supplicant::Supplicant(WifiController *wc, PropertyManager *propmngr) { +Supplicant::Supplicant(WifiController *wc, ISupplicantEventHandler *handlers) { + mHandlers = handlers; mController = wc; - mPropMngr = propmngr; mInterfaceName = NULL; mCtrl = NULL; mMonitor = NULL; mListener = NULL; - mState = SupplicantState::UNKNOWN; - mServiceManager = new ServiceManager(); - mLatestScanResults = new ScanResultCollection(); - pthread_mutex_init(&mLatestScanResultsLock, NULL); - mNetworks = new WifiNetworkCollection(); pthread_mutex_init(&mNetworksLock, NULL); } @@ -92,14 +84,11 @@ int Supplicant::start() { return -1; } - mPropMngr->registerProperty("wifi.supplicant.state", this); return 0; } int Supplicant::stop() { - mPropMngr->unregisterProperty("wifi.supplicant.state"); - if (mListener->stopListener()) { LOGW("Unable to stop supplicant listener (%s)", strerror(errno)); return -1; @@ -125,6 +114,30 @@ bool Supplicant::isStarted() { return mServiceManager->isRunning(SUPPLICANT_SERVICE_NAME); } +SupplicantStatus *Supplicant::getStatus() { + char *reply; + size_t len = 4096; + + if (!(reply = (char *) malloc(len))) { + errno = ENOMEM; + return NULL; + } + + if (sendCommand("STATUS", reply, &len)) { + free(reply); + return NULL; + } + + SupplicantStatus *ss = SupplicantStatus::createStatus(reply, len); + + free (reply); + return ss; +} + +/* + * Retrieves the list of networks from Supplicant + * and merge them into our current list + */ int Supplicant::refreshNetworkList() { char *reply; size_t len = 4096; @@ -144,27 +157,59 @@ int Supplicant::refreshNetworkList() { if (!strtok_r(reply, "\n", &linep_next)) { LOGW("Malformatted network list\n"); - } else { - pthread_mutex_lock(&mNetworksLock); - if (!mNetworks->empty()) { - WifiNetworkCollection::iterator i; - - for (i = mNetworks->begin(); i !=mNetworks->end(); ++i) - delete *i; - mNetworks->clear(); - } + free(reply); + errno = EIO; + return -1; + } - while((linep = strtok_r(NULL, "\n", &linep_next))) { - WifiNetwork *wn = new WifiNetwork(mController, this, linep); - mNetworks->push_back(wn); - if (wn->refresh()) - LOGW("Unable to refresh network id %d", wn->getNetworkId()); + pthread_mutex_lock(&mNetworksLock); + + int num_added = 0; + int num_refreshed = 0; + int num_removed = 0; + while((linep = strtok_r(NULL, "\n", &linep_next))) { + // TODO: Move the decode into a static method so we + // don't create new_wn when we don't have to. + WifiNetwork *new_wn = new WifiNetwork(mController, this, linep); + WifiNetwork *merge_wn; + + if ((merge_wn = this->lookupNetwork_UNLOCKED(new_wn->getNetworkId()))) { + num_refreshed++; + if (merge_wn->refresh()) { + LOGW("Error refreshing network %d (%s)", + merge_wn->getNetworkId(), strerror(errno)); + } + delete new_wn; + } else { + num_added++; + new_wn->registerProperties(); + mNetworks->push_back(new_wn); + if (new_wn->refresh()) { + LOGW("Unable to refresh network id %d (%s)", + new_wn->getNetworkId(), strerror(errno)); + } } + } - LOGD("Loaded %d networks\n", mNetworks->size()); - pthread_mutex_unlock(&mNetworksLock); + if (!mNetworks->empty()) { + // TODO: Add support for detecting removed networks + WifiNetworkCollection::iterator i; + + for (i = mNetworks->begin(); i != mNetworks->end(); ++i) { + if (0) { + num_removed++; + (*i)->unregisterProperties(); + delete (*i); + i = mNetworks->erase(i); + } + } } + + LOGD("Networks added %d, refreshed %d, removed %d\n", + num_added, num_refreshed, num_removed); + pthread_mutex_unlock(&mNetworksLock); + free(reply); return 0; } @@ -192,7 +237,7 @@ int Supplicant::connectToSupplicant() { return -1; } - mListener = new SupplicantListener(this, mMonitor); + mListener = new SupplicantListener(mHandlers, mMonitor); if (mListener->startListener()) { LOGE("Error - unable to start supplicant listener"); @@ -245,165 +290,6 @@ int Supplicant::triggerScan(bool active) { return 0; } -int Supplicant::set(const char *name, const char *value) { - const char *n = name + strlen("wifi.supplicant."); - - errno = -EROFS; - return -1; -} - -const char *Supplicant::get(const char *name, char *buffer, size_t max) { - const char *n = name + strlen("wifi.supplicant."); - - if (!strcasecmp(n, "state")) - return SupplicantState::toString(mState, buffer, max); - errno = ENOENT; - return NULL; -} - -int Supplicant::onConnectedEvent(SupplicantEvent *evt) { - LOGD("onConnectedEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onDisconnectedEvent(SupplicantEvent *evt) { - LOGD("onDisconnectedEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onTerminatingEvent(SupplicantEvent *evt) { - LOGD("onTerminatingEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onPasswordChangedEvent(SupplicantEvent *evt) { - LOGD("onPasswordChangedEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onEapNotificationEvent(SupplicantEvent *evt) { - LOGD("onEapNotificationEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onEapStartedEvent(SupplicantEvent *evt) { - LOGD("onEapStartedEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onEapMethodEvent(SupplicantEvent *evt) { - LOGD("onEapMethodEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onEapSuccessEvent(SupplicantEvent *evt) { - LOGD("onEapSuccessEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onEapFailureEvent(SupplicantEvent *evt) { - LOGD("onEapFailureEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onScanResultsEvent(SupplicantEvent *evt) { - if (!strcmp(evt->getEvent(), "Ready")) { - char *reply; - - if (!(reply = (char *) malloc(4096))) { - errno = ENOMEM; - return -1; - } - - size_t len = 4096; - - if (sendCommand("SCAN_RESULTS", reply, &len)) { - LOGW("onScanResultsEvent(%s): Error getting scan results (%s)", - evt->getEvent(), strerror(errno)); - free(reply); - return -1; - } - - 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 0; - } - - while((linep = strtok_r(NULL, "\n", &linep_next))) - mLatestScanResults->push_back(new ScanResult(linep)); - - char tmp[128]; - sprintf(tmp, "Scan results ready (%d)", mLatestScanResults->size()); - NetworkManager::Instance()->getBroadcaster()-> - sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false); - pthread_mutex_unlock(&mLatestScanResultsLock); - free(reply); - } else { - LOGW("Unknown SCAN_RESULTS event (%s)", evt->getEvent()); - } - return 0; -} - -int Supplicant::onStateChangeEvent(SupplicantEvent *evt) { - char *bword, *last; - char *tmp = strdup(evt->getEvent()); - - if (!(bword = strtok_r(tmp, " ", &last))) { - LOGE("Malformatted state update (%s)", evt->getEvent()); - free(tmp); - return 0; - } - - if (!(bword = strtok_r(NULL, " ", &last))) { - LOGE("Malformatted state update (%s)", evt->getEvent()); - free(tmp); - return 0; - } - - mState = atoi(&bword[strlen("state=")]); - LOGD("State changed to %d", mState); - free(tmp); - return 0; -} - -int Supplicant::onLinkSpeedEvent(SupplicantEvent *evt) { - LOGD("onLinkSpeedEvent(%s)", evt->getEvent()); - return 0; -} - -int Supplicant::onDriverStateEvent(SupplicantEvent *evt) { - LOGD("onDriverStateEvent(%s)", evt->getEvent()); - return 0; -} - -// XXX: Use a cursor + smartptr instead -ScanResultCollection *Supplicant::createLatestScanResults() { - 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; -} - WifiNetwork *Supplicant::createNetwork() { char reply[255]; size_t len = sizeof(reply) -1; @@ -445,14 +331,18 @@ int Supplicant::removeNetwork(WifiNetwork *wn) { WifiNetwork *Supplicant::lookupNetwork(int networkId) { pthread_mutex_lock(&mNetworksLock); + WifiNetwork *wn = lookupNetwork_UNLOCKED(networkId); + pthread_mutex_unlock(&mNetworksLock); + return wn; +} + +WifiNetwork *Supplicant::lookupNetwork_UNLOCKED(int networkId) { WifiNetworkCollection::iterator it; for (it = mNetworks->begin(); it != mNetworks->end(); ++it) { if ((*it)->getNetworkId() == networkId) { - pthread_mutex_unlock(&mNetworksLock); return *it; } } - pthread_mutex_unlock(&mNetworksLock); errno = ENOENT; return NULL; } @@ -528,6 +418,12 @@ int Supplicant::setNetworkVar(int networkId, const char *var, const char *val) { return -1; } free(tmp); + + len = sizeof(reply) -1; + if (sendCommand("SAVE_CONFIG", reply, &len)) { + LOGE("Error saving config after %s = %s", var, val); + return -1; + } return 0; } diff --git a/nexus/Supplicant.h b/nexus/Supplicant.h index 42f2f79..3efbe4c 100644 --- a/nexus/Supplicant.h +++ b/nexus/Supplicant.h @@ -19,38 +19,31 @@ struct wpa_ctrl; class SupplicantListener; -class SupplicantEvent; class ServiceManager; -class PropertyManager; class Controller; class WifiController; +class SupplicantStatus; #include <pthread.h> -#include "ScanResult.h" #include "WifiNetwork.h" -#include "IPropertyProvider.h" #include "ISupplicantEventHandler.h" -class Supplicant : public IPropertyProvider, public ISupplicantEventHandler { +class Supplicant { private: struct wpa_ctrl *mCtrl; struct wpa_ctrl *mMonitor; SupplicantListener *mListener; - int mState; ServiceManager *mServiceManager; - PropertyManager *mPropMngr; WifiController *mController; char *mInterfaceName; - ScanResultCollection *mLatestScanResults; - pthread_mutex_t mLatestScanResultsLock; - - WifiNetworkCollection *mNetworks; - pthread_mutex_t mNetworksLock; + WifiNetworkCollection *mNetworks; + pthread_mutex_t mNetworksLock; + ISupplicantEventHandler *mHandlers; public: - Supplicant(WifiController *wc, PropertyManager *propmngr); + Supplicant(WifiController *wc, ISupplicantEventHandler *handlers); virtual ~Supplicant(); int start(); @@ -58,7 +51,6 @@ public: bool isStarted(); int triggerScan(bool active); - ScanResultCollection *createLatestScanResults(); WifiNetwork *createNetwork(); WifiNetwork *lookupNetwork(int networkId); @@ -71,33 +63,18 @@ public: size_t max); int enableNetwork(int networkId, bool enabled); - int getState() { return mState; } + SupplicantStatus *getStatus(); + Controller *getController() { return (Controller *) mController; } const char *getInterfaceName() { return mInterfaceName; } - int set(const char *name, const char *value); - const char *get(const char *name, char *buffer, size_t max); + int sendCommand(const char *cmd, char *reply, size_t *reply_len); private: int connectToSupplicant(); - int sendCommand(const char *cmd, char *reply, size_t *reply_len); int setupConfig(); int retrieveInterfaceName(); - - // ISupplicantEventHandler methods - virtual int onConnectedEvent(SupplicantEvent *evt); - virtual int onDisconnectedEvent(SupplicantEvent *evt); - virtual int onTerminatingEvent(SupplicantEvent *evt); - virtual int onPasswordChangedEvent(SupplicantEvent *evt); - virtual int onEapNotificationEvent(SupplicantEvent *evt); - virtual int onEapStartedEvent(SupplicantEvent *evt); - virtual int onEapMethodEvent(SupplicantEvent *evt); - virtual int onEapSuccessEvent(SupplicantEvent *evt); - virtual int onEapFailureEvent(SupplicantEvent *evt); - virtual int onScanResultsEvent(SupplicantEvent *evt); - virtual int onStateChangeEvent(SupplicantEvent *evt); - virtual int onLinkSpeedEvent(SupplicantEvent *evt); - virtual int onDriverStateEvent(SupplicantEvent *evt); + WifiNetwork *lookupNetwork_UNLOCKED(int networkId); }; #endif diff --git a/nexus/SupplicantAssociatedEvent.cpp b/nexus/SupplicantAssociatedEvent.cpp new file mode 100644 index 0000000..e40411e --- /dev/null +++ b/nexus/SupplicantAssociatedEvent.cpp @@ -0,0 +1,40 @@ +/* + * 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> + +#define LOG_TAG "SupplicantAssociatedEvent" +#include <cutils/log.h> + +#include "SupplicantAssociatedEvent.h" + +SupplicantAssociatedEvent::SupplicantAssociatedEvent(int level, char *event, + size_t len) : + SupplicantEvent(SupplicantEvent::EVENT_ASSOCIATED, + level) { + char *p = event; + + // "00:13:46:40:40:aa" + mBssid = (char *) malloc(18); + strncpy(mBssid, p, 17); + mBssid[17] = '\0'; +} + +SupplicantAssociatedEvent::~SupplicantAssociatedEvent() { + if (mBssid) + free(mBssid); +} + diff --git a/nexus/SupplicantAssociatedEvent.h b/nexus/SupplicantAssociatedEvent.h new file mode 100644 index 0000000..aa33c59 --- /dev/null +++ b/nexus/SupplicantAssociatedEvent.h @@ -0,0 +1,34 @@ +/* + * 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 _SupplicantAssociatedEvent_H +#define _SupplicantAssociatedEvent_H + +#include "SupplicantEvent.h" + +class SupplicantAssociatedEvent : public SupplicantEvent { + char *mBssid; + char *mSsid; + int mFreq; + +public: + SupplicantAssociatedEvent(int level, char *event, size_t len); + virtual ~SupplicantAssociatedEvent(); + + const char *getBssid() { return mBssid; } +}; + +#endif diff --git a/nexus/SupplicantAssociatingEvent.cpp b/nexus/SupplicantAssociatingEvent.cpp new file mode 100644 index 0000000..00a85b6 --- /dev/null +++ b/nexus/SupplicantAssociatingEvent.cpp @@ -0,0 +1,99 @@ +/* + * 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> + +#define LOG_TAG "SupplicantAssociatingEvent" +#include <cutils/log.h> + +#include "SupplicantAssociatingEvent.h" + +SupplicantAssociatingEvent::SupplicantAssociatingEvent(int level, char *event, + size_t len) : + SupplicantEvent(SupplicantEvent::EVENT_ASSOCIATING, + level) { + char *p = event; + + mBssid = NULL; + mSsid = NULL; + + // SSID 'default' + // OR + // "00:13:46:40:40:aa (SSID='default' freq=2437 MHz)" + + if (strncmp(event, "SSID", 4)) { + mBssid = (char *) malloc(18); + strncpy(mBssid, p, 17); + mBssid[17] = '\0'; + p += 25; + + // "00:13:46:40:40:aa (SSID='default' freq=2437 MHz)" + // ^ + // p + char *q = index(p, '\''); + if (!q) { + LOGE("Unable to decode SSID (p = {%s})\n", p); + return; + } + mSsid = (char *) malloc((q - p) +1); + strncpy(mSsid, p, q-p); + mSsid[q-p] = '\0'; + + p = q + 7; + + // "00:13:46:40:40:aa (SSID='default' freq=2437 MHz)" + // ^ + // p + if (!(q = index(p, ' '))) { + LOGE("Unable to decode frequency\n"); + return; + } + *q = '\0'; + mFreq = atoi(p); + } else { + p+= 6; + + // SSID 'default' + // ^ + // p + + char *q = index(p, '\''); + if (!q) { + LOGE("Unable to decode SSID (p = {%s})\n", p); + return; + } + mSsid = (char *) malloc((q - p) +1); + strncpy(mSsid, p, q-p); + mSsid[q-p] = '\0'; + } +} + +SupplicantAssociatingEvent::SupplicantAssociatingEvent(const char *bssid, + const char *ssid, + int freq) : + SupplicantEvent(SupplicantEvent::EVENT_ASSOCIATING, -1) { + mBssid = strdup(bssid); + mSsid= strdup(ssid); + mFreq = freq; +} + +SupplicantAssociatingEvent::~SupplicantAssociatingEvent() { + if (mBssid) + free(mBssid); + if (mSsid) + free(mSsid); +} + diff --git a/nexus/SupplicantAssociatingEvent.h b/nexus/SupplicantAssociatingEvent.h new file mode 100644 index 0000000..d3a4d5c --- /dev/null +++ b/nexus/SupplicantAssociatingEvent.h @@ -0,0 +1,37 @@ +/* + * 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 _SupplicantAssociatingEvent_H +#define _SupplicantAssociatingEvent_H + +#include "SupplicantEvent.h" + +class SupplicantAssociatingEvent : public SupplicantEvent { + char *mBssid; + char *mSsid; + int mFreq; + +public: + SupplicantAssociatingEvent(int level, char *event, size_t len); + SupplicantAssociatingEvent(const char *bssid, const char *ssid, int freq); + virtual ~SupplicantAssociatingEvent(); + + const char *getBssid() { return mBssid; } + const char *getSsid() { return mSsid; } + int getFreq() { return mFreq;} +}; + +#endif diff --git a/nexus/SupplicantConnectedEvent.cpp b/nexus/SupplicantConnectedEvent.cpp new file mode 100644 index 0000000..e58bab2 --- /dev/null +++ b/nexus/SupplicantConnectedEvent.cpp @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#define LOG_TAG "SupplicantConnectedEvent" +#include <cutils/log.h> + +#include "SupplicantConnectedEvent.h" + +SupplicantConnectedEvent::SupplicantConnectedEvent(int level, char *event, + size_t len) : + SupplicantEvent(SupplicantEvent::EVENT_CONNECTED, + level) { + char *p; + + // "- Connection to 00:13:46:40:40:aa completed (auth) [id=1 id_str=], 89" + + if ((p = index(event + 2, ' ')) && (++p = index(p, ' '))) { + mBssid = (char *) malloc(18); + strncpy(mBssid, ++p, 17); + mBssid[17] = '\0'; + + // "- Connection to 00:13:46:40:40:aa completed (auth) [id=1 id_str=], 89" + // ^ + // p + + if ((p = index(p, ' ')) && ((++p = index(p, ' ')))) { + if (!strncmp(++p, "(auth)", 6)) + mReassociated = false; + else + mReassociated = true; + } else + LOGE("Unable to decode re-assocation"); + } else + LOGE("Unable to decode event"); +} + +SupplicantConnectedEvent::SupplicantConnectedEvent(const char *bssid, + bool reassocated) : + SupplicantEvent(SupplicantEvent::EVENT_CONNECTED, -1) { + mBssid = strdup(bssid); + mReassociated = reassocated; +} + +SupplicantConnectedEvent::~SupplicantConnectedEvent() { + if (mBssid) + free(mBssid); +} + diff --git a/nexus/SupplicantConnectedEvent.h b/nexus/SupplicantConnectedEvent.h new file mode 100644 index 0000000..03e9842 --- /dev/null +++ b/nexus/SupplicantConnectedEvent.h @@ -0,0 +1,36 @@ +/* + * 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 _SupplicantConnectedEvent_H +#define _SupplicantConnectedEvent_H + +#include "SupplicantEvent.h" + +class SupplicantConnectedEvent : public SupplicantEvent { +private: + char *mBssid; + bool mReassociated; + +public: + SupplicantConnectedEvent(int level, char *event, size_t len); + SupplicantConnectedEvent(const char *bssid, bool reassicated); + virtual ~SupplicantConnectedEvent(); + + const char *getBssid() { return mBssid; } + bool getReassociated() { return mReassociated; } +}; + +#endif diff --git a/nexus/SupplicantConnectionTimeoutEvent.cpp b/nexus/SupplicantConnectionTimeoutEvent.cpp new file mode 100644 index 0000000..8b8a7d7 --- /dev/null +++ b/nexus/SupplicantConnectionTimeoutEvent.cpp @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#define LOG_TAG "SupplicantConnectionTimeoutEvent" +#include <cutils/log.h> + +#include "SupplicantConnectionTimeoutEvent.h" + +SupplicantConnectionTimeoutEvent::SupplicantConnectionTimeoutEvent(int level, char *event, + size_t len) : + SupplicantEvent(SupplicantEvent::EVENT_CONNECTIONTIMEOUT, + level) { + // 00:13:46:40:40:aa timed out.' + mBssid = (char *) malloc(18); + strncpy(mBssid, event, 17); + mBssid[17] = '\0'; +} + +SupplicantConnectionTimeoutEvent::~SupplicantConnectionTimeoutEvent() { + if (mBssid) + free(mBssid); +} + diff --git a/nexus/SupplicantConnectionTimeoutEvent.h b/nexus/SupplicantConnectionTimeoutEvent.h new file mode 100644 index 0000000..0d2606d --- /dev/null +++ b/nexus/SupplicantConnectionTimeoutEvent.h @@ -0,0 +1,34 @@ +/* + * 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 _SupplicantConnectionTimeoutEvent_H +#define _SupplicantConnectionTimeoutEvent_H + +#include "SupplicantEvent.h" + +class SupplicantConnectionTimeoutEvent : public SupplicantEvent { +private: + char *mBssid; + bool mReassociated; + +public: + SupplicantConnectionTimeoutEvent(int level, char *event, size_t len); + virtual ~SupplicantConnectionTimeoutEvent(); + + const char *getBssid() { return mBssid; } +}; + +#endif diff --git a/nexus/SupplicantDisconnectedEvent.cpp b/nexus/SupplicantDisconnectedEvent.cpp new file mode 100644 index 0000000..11e499d --- /dev/null +++ b/nexus/SupplicantDisconnectedEvent.cpp @@ -0,0 +1,33 @@ +/* + * 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. + */ + +#define LOG_TAG "SupplicantDisconnectedEvent" +#include <cutils/log.h> + +#include "SupplicantDisconnectedEvent.h" + +SupplicantDisconnectedEvent::SupplicantDisconnectedEvent(int level, char *event, + size_t len) : + SupplicantEvent(SupplicantEvent::EVENT_DISCONNECTED, + level) { +} + +SupplicantDisconnectedEvent::SupplicantDisconnectedEvent() : + SupplicantEvent(SupplicantEvent::EVENT_DISCONNECTED, -1) { +} + +SupplicantDisconnectedEvent::~SupplicantDisconnectedEvent() { +} diff --git a/nexus/SupplicantDisconnectedEvent.h b/nexus/SupplicantDisconnectedEvent.h new file mode 100644 index 0000000..c09ec62 --- /dev/null +++ b/nexus/SupplicantDisconnectedEvent.h @@ -0,0 +1,30 @@ +/* + * 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 _SupplicantDisconnectedEvent_H +#define _SupplicantDisconnectedEvent_H + +#include "SupplicantEvent.h" + +class SupplicantDisconnectedEvent : public SupplicantEvent { + +public: + SupplicantDisconnectedEvent(int level, char *event, size_t len); + SupplicantDisconnectedEvent(); + virtual ~SupplicantDisconnectedEvent(); +}; + +#endif diff --git a/nexus/SupplicantEvent.cpp b/nexus/SupplicantEvent.cpp index 2e6d665..faf7b45 100644 --- a/nexus/SupplicantEvent.cpp +++ b/nexus/SupplicantEvent.cpp @@ -23,74 +23,7 @@ #include "libwpa_client/wpa_ctrl.h" -SupplicantEvent::SupplicantEvent(char *event, size_t len) { - - if (event[0] == '<') { - char *match = strchr(event, '>'); - if (match) { - char tmp[16]; - - strncpy(tmp, &event[1], (match - event)); - mLevel = atoi(tmp); - event += (match - event) + 1; - } else - LOGW("Unclosed level brace in event"); - } else - LOGW("No level specified in event"); - - /* - * <N>CTRL-EVENT-XXX - * ^ - * +---- event - */ - - if (!strncmp(event, WPA_EVENT_CONNECTED, strlen(WPA_EVENT_CONNECTED))) - mType = SupplicantEvent::EVENT_CONNECTED; - else if (!strncmp(event, WPA_EVENT_DISCONNECTED, strlen(WPA_EVENT_DISCONNECTED))) - mType = SupplicantEvent::EVENT_DISCONNECTED; - else if (!strncmp(event, WPA_EVENT_TERMINATING, strlen(WPA_EVENT_TERMINATING))) - mType = SupplicantEvent::EVENT_TERMINATING; - else if (!strncmp(event, WPA_EVENT_PASSWORD_CHANGED, strlen(WPA_EVENT_PASSWORD_CHANGED))) - mType = SupplicantEvent::EVENT_PASSWORD_CHANGED; - else if (!strncmp(event, WPA_EVENT_EAP_NOTIFICATION, strlen(WPA_EVENT_EAP_NOTIFICATION))) - mType = SupplicantEvent::EVENT_EAP_NOTIFICATION; - else if (!strncmp(event, WPA_EVENT_EAP_STARTED, strlen(WPA_EVENT_EAP_STARTED))) - mType = SupplicantEvent::EVENT_EAP_STARTED; - else if (!strncmp(event, WPA_EVENT_EAP_METHOD, strlen(WPA_EVENT_EAP_METHOD))) - mType = SupplicantEvent::EVENT_EAP_METHOD; - else if (!strncmp(event, WPA_EVENT_EAP_SUCCESS, strlen(WPA_EVENT_EAP_SUCCESS))) - mType = SupplicantEvent::EVENT_EAP_SUCCESS; - else if (!strncmp(event, WPA_EVENT_EAP_FAILURE, strlen(WPA_EVENT_EAP_FAILURE))) - mType = SupplicantEvent::EVENT_EAP_FAILURE; - else if (!strncmp(event, WPA_EVENT_SCAN_RESULTS, strlen(WPA_EVENT_SCAN_RESULTS))) - mType = SupplicantEvent::EVENT_SCAN_RESULTS; - else if (!strncmp(event, WPA_EVENT_STATE_CHANGE, strlen(WPA_EVENT_STATE_CHANGE))) - mType = SupplicantEvent::EVENT_STATE_CHANGE; - else if (!strncmp(event, WPA_EVENT_LINK_SPEED, strlen(WPA_EVENT_LINK_SPEED))) - mType = SupplicantEvent::EVENT_LINK_SPEED; - else if (!strncmp(event, WPA_EVENT_DRIVER_STATE, strlen(WPA_EVENT_DRIVER_STATE))) - mType = SupplicantEvent::EVENT_DRIVER_STATE; - else { - LOGW("Unknown supplicant event '%s'", event); - mType = SupplicantEvent::EVENT_UNKNOWN; - } - - for (event; *event != ' '; event++); - event++; - - /* - * <N>CTRL-EVENT-XXX YYYY - * ^ - * +---- event - */ - - for (event; *event == ' '; event++); - - mEvent = strdup(event); - mLen = len; -} - -SupplicantEvent::~SupplicantEvent() { - if (mEvent) - free(mEvent); +SupplicantEvent::SupplicantEvent(int type, int level) { + mType = type; + mLevel = level; } diff --git a/nexus/SupplicantEvent.h b/nexus/SupplicantEvent.h index 2dc6722..9d7cbd9 100644 --- a/nexus/SupplicantEvent.h +++ b/nexus/SupplicantEvent.h @@ -22,33 +22,32 @@ class SupplicantEvent { private: int mType; - char *mEvent; - size_t mLen; int mLevel; public: - static const int EVENT_UNKNOWN = 0; - static const int EVENT_CONNECTED = 1; - static const int EVENT_DISCONNECTED = 2; - static const int EVENT_TERMINATING = 3; - static const int EVENT_PASSWORD_CHANGED = 4; - static const int EVENT_EAP_NOTIFICATION = 5; - static const int EVENT_EAP_STARTED = 6; - static const int EVENT_EAP_METHOD = 7; - static const int EVENT_EAP_SUCCESS = 8; - static const int EVENT_EAP_FAILURE = 9; - static const int EVENT_SCAN_RESULTS = 10; - static const int EVENT_STATE_CHANGE = 11; - static const int EVENT_LINK_SPEED = 12; - static const int EVENT_DRIVER_STATE = 13; + static const int EVENT_UNKNOWN = 0; + static const int EVENT_CONNECTED = 1; + static const int EVENT_DISCONNECTED = 2; + static const int EVENT_TERMINATING = 3; + static const int EVENT_PASSWORD_CHANGED = 4; + static const int EVENT_EAP_NOTIFICATION = 5; + static const int EVENT_EAP_STARTED = 6; + static const int EVENT_EAP_METHOD = 7; + static const int EVENT_EAP_SUCCESS = 8; + static const int EVENT_EAP_FAILURE = 9; + static const int EVENT_SCAN_RESULTS = 10; + static const int EVENT_STATE_CHANGE = 11; + static const int EVENT_LINK_SPEED = 12; + static const int EVENT_DRIVER_STATE = 13; + static const int EVENT_ASSOCIATING = 14; + static const int EVENT_ASSOCIATED = 15; + static const int EVENT_CONNECTIONTIMEOUT = 16; public: - SupplicantEvent(char *event, size_t len); - virtual ~SupplicantEvent(); + SupplicantEvent(int type, int level); + virtual ~SupplicantEvent() {} int getType() { return mType; } - const char *getEvent() { return mEvent; } - int getLen() { return mLen; } int getLevel() { return mLevel; } }; diff --git a/nexus/SupplicantEventFactory.cpp b/nexus/SupplicantEventFactory.cpp new file mode 100644 index 0000000..8695aca --- /dev/null +++ b/nexus/SupplicantEventFactory.cpp @@ -0,0 +1,119 @@ +/* + * 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> + +#define LOG_TAG "SupplicantEventFactory" +#include <cutils/log.h> + +#include "SupplicantEvent.h" +#include "SupplicantEventFactory.h" +#include "SupplicantAssociatingEvent.h" +#include "SupplicantAssociatedEvent.h" +#include "SupplicantConnectedEvent.h" +#include "SupplicantStateChangeEvent.h" +#include "SupplicantScanResultsEvent.h" +#include "SupplicantConnectionTimeoutEvent.h" +#include "SupplicantDisconnectedEvent.h" +#if 0 +#include "SupplicantTerminatingEvent.h" +#include "SupplicantPasswordChangedEvent.h" +#include "SupplicantEapNotificationEvent.h" +#include "SupplicantEapStartedEvent.h" +#include "SupplicantEapMethodEvent.h" +#include "SupplicantEapSuccessEvent.h" +#include "SupplicantEapFailureEvent.h" +#include "SupplicantLinkSpeedEvent.h" +#include "SupplicantDriverStateEvent.h" +#endif + +#include "libwpa_client/wpa_ctrl.h" + +SupplicantEventFactory::SupplicantEventFactory() { +} + +SupplicantEvent *SupplicantEventFactory::createEvent(char *event, size_t len) { + int level = 0; + + if (event[0] == '<') { + char *match = strchr(event, '>'); + if (match) { + char tmp[16]; + + strncpy(tmp, &event[1], (match - event)); + level = atoi(tmp); + event += (match - event) + 1; + } else + LOGW("Unclosed level brace in event"); + } else + LOGW("No level specified in event"); + + /* + * <N>CTRL-EVENT-XXX + * ^ + * +---- event + */ + + if (!strncmp(event, "Authentication with ", 20)) { + if (!strcmp(event + strlen(event) - strlen(" timed out."), + " timed out.")) { + return new SupplicantConnectionTimeoutEvent(level, + event + 20, + len); + } else + return NULL; + + } else if (!strncmp(event, "Associated with ", 16)) + return new SupplicantAssociatedEvent(level, event + 16, len); + else if (!strncmp(event, "Trying to associate with ", 25)) + return new SupplicantAssociatingEvent(level, event + 25, len); + else if (!strncmp(event, WPA_EVENT_CONNECTED, strlen(WPA_EVENT_CONNECTED))) { + return new SupplicantConnectedEvent(level, + event + strlen(WPA_EVENT_CONNECTED), + len); + } else if (!strncmp(event, WPA_EVENT_SCAN_RESULTS, strlen(WPA_EVENT_SCAN_RESULTS))) { + return new SupplicantScanResultsEvent(level, + event + strlen(WPA_EVENT_SCAN_RESULTS), + len); + } else if (!strncmp(event, WPA_EVENT_STATE_CHANGE, strlen(WPA_EVENT_STATE_CHANGE))) { + return new SupplicantStateChangeEvent(level, + event + strlen(WPA_EVENT_STATE_CHANGE), + len); + } + else if (!strncmp(event, WPA_EVENT_DISCONNECTED, strlen(WPA_EVENT_DISCONNECTED))) + return new SupplicantDisconnectedEvent(level, event, len); +#if 0 + else if (!strncmp(event, WPA_EVENT_TERMINATING, strlen(WPA_EVENT_TERMINATING))) + return new SupplicantTerminatingEvent(event, len); + else if (!strncmp(event, WPA_EVENT_PASSWORD_CHANGED, strlen(WPA_EVENT_PASSWORD_CHANGED))) + return new SupplicantPasswordChangedEvent(event, len); + else if (!strncmp(event, WPA_EVENT_EAP_NOTIFICATION, strlen(WPA_EVENT_EAP_NOTIFICATION))) + return new SupplicantEapNotificationEvent(event, len); + else if (!strncmp(event, WPA_EVENT_EAP_STARTED, strlen(WPA_EVENT_EAP_STARTED))) + return new SupplicantEapStartedEvent(event, len); + else if (!strncmp(event, WPA_EVENT_EAP_METHOD, strlen(WPA_EVENT_EAP_METHOD))) + return new SupplicantEapMethodEvent(event, len); + else if (!strncmp(event, WPA_EVENT_EAP_SUCCESS, strlen(WPA_EVENT_EAP_SUCCESS))) + return new SupplicantEapSuccessEvent(event, len); + else if (!strncmp(event, WPA_EVENT_EAP_FAILURE, strlen(WPA_EVENT_EAP_FAILURE))) + return new SupplicantEapFailureEvent(event, len); + else if (!strncmp(event, WPA_EVENT_LINK_SPEED, strlen(WPA_EVENT_LINK_SPEED))) + return new SupplicantLinkSpeedEvent(event, len); + else if (!strncmp(event, WPA_EVENT_DRIVER_STATE, strlen(WPA_EVENT_DRIVER_STATE))) + return new SupplicantDriverStateEvent(event, len); +#endif + return NULL; +} diff --git a/nexus/SupplicantEventFactory.h b/nexus/SupplicantEventFactory.h new file mode 100644 index 0000000..22e5707 --- /dev/null +++ b/nexus/SupplicantEventFactory.h @@ -0,0 +1,31 @@ + +/* + * 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 _SupplicantEventFactory_H +#define _SupplicantEventFactory_H + +class SupplicantEvent; + +class SupplicantEventFactory { +public: + SupplicantEventFactory(); + virtual ~SupplicantEventFactory() {} + + SupplicantEvent *createEvent(char *event, size_t len); +}; + +#endif diff --git a/nexus/SupplicantListener.cpp b/nexus/SupplicantListener.cpp index b94648b..b91fc02 100644 --- a/nexus/SupplicantListener.cpp +++ b/nexus/SupplicantListener.cpp @@ -24,14 +24,21 @@ #include "libwpa_client/wpa_ctrl.h" #include "SupplicantListener.h" -#include "SupplicantEvent.h" #include "ISupplicantEventHandler.h" +#include "SupplicantEventFactory.h" +#include "SupplicantEvent.h" +#include "SupplicantAssociatingEvent.h" +#include "SupplicantAssociatedEvent.h" +#include "SupplicantConnectedEvent.h" +#include "SupplicantScanResultsEvent.h" +#include "SupplicantStateChangeEvent.h" SupplicantListener::SupplicantListener(ISupplicantEventHandler *handlers, struct wpa_ctrl *monitor) : SocketListener(wpa_ctrl_get_fd(monitor), false) { mHandlers = handlers; mMonitor = monitor; + mFactory = new SupplicantEventFactory(); } bool SupplicantListener::onDataAvailable(SocketClient *cli) { @@ -53,44 +60,50 @@ bool SupplicantListener::onDataAvailable(SocketClient *cli) { return false; } - SupplicantEvent *evt = new SupplicantEvent(buf, nread); + SupplicantEvent *evt = mFactory->createEvent(buf, nread); + + if (!evt) { + LOGW("Dropping unknown supplicant event '%s'", buf); + return true; + } - // XXX: Make this a factory - // XXX: Instead of calling Supplicant directly - // extract an Interface and use that instead - if (evt->getType() == SupplicantEvent::EVENT_CONNECTED) - rc = mHandlers->onConnectedEvent(evt); + // Call the appropriate handler + if (evt->getType() == SupplicantEvent::EVENT_ASSOCIATING) + mHandlers->onAssociatingEvent((SupplicantAssociatingEvent *) evt); + else if (evt->getType() == SupplicantEvent::EVENT_ASSOCIATED) + mHandlers->onAssociatedEvent((SupplicantAssociatedEvent *) evt); + else if (evt->getType() == SupplicantEvent::EVENT_CONNECTED) + mHandlers->onConnectedEvent((SupplicantConnectedEvent *) evt); + else if (evt->getType() == SupplicantEvent::EVENT_SCAN_RESULTS) + mHandlers->onScanResultsEvent((SupplicantScanResultsEvent *) evt); + else if (evt->getType() == SupplicantEvent::EVENT_STATE_CHANGE) + mHandlers->onStateChangeEvent((SupplicantStateChangeEvent *) evt); + else if (evt->getType() == SupplicantEvent::EVENT_CONNECTIONTIMEOUT) + mHandlers->onConnectionTimeoutEvent((SupplicantConnectionTimeoutEvent *) evt); else if (evt->getType() == SupplicantEvent::EVENT_DISCONNECTED) - rc = mHandlers->onDisconnectedEvent(evt); + mHandlers->onDisconnectedEvent((SupplicantDisconnectedEvent *) evt); + else + LOGW("Whoops - no handler available for event '%s'\n", buf); +#if 0 else if (evt->getType() == SupplicantEvent::EVENT_TERMINATING) - rc = mHandlers->onTerminatingEvent(evt); + mHandlers->onTerminatingEvent(evt); else if (evt->getType() == SupplicantEvent::EVENT_PASSWORD_CHANGED) - rc = mHandlers->onPasswordChangedEvent(evt); + mHandlers->onPasswordChangedEvent(evt); else if (evt->getType() == SupplicantEvent::EVENT_EAP_NOTIFICATION) - rc = mHandlers->onEapNotificationEvent(evt); + mHandlers->onEapNotificationEvent(evt); else if (evt->getType() == SupplicantEvent::EVENT_EAP_STARTED) - rc = mHandlers->onEapStartedEvent(evt); + mHandlers->onEapStartedEvent(evt); else if (evt->getType() == SupplicantEvent::EVENT_EAP_SUCCESS) - rc = mHandlers->onEapSuccessEvent(evt); + mHandlers->onEapSuccessEvent(evt); else if (evt->getType() == SupplicantEvent::EVENT_EAP_FAILURE) - rc = mHandlers->onEapFailureEvent(evt); - else if (evt->getType() == SupplicantEvent::EVENT_SCAN_RESULTS) - rc = mHandlers->onScanResultsEvent(evt); - else if (evt->getType() == SupplicantEvent::EVENT_STATE_CHANGE) - rc = mHandlers->onStateChangeEvent(evt); + mHandlers->onEapFailureEvent(evt); else if (evt->getType() == SupplicantEvent::EVENT_LINK_SPEED) - rc = mHandlers->onLinkSpeedEvent(evt); + mHandlers->onLinkSpeedEvent(evt); else if (evt->getType() == SupplicantEvent::EVENT_DRIVER_STATE) - rc = mHandlers->onDriverStateEvent(evt); - else { - LOGW("Ignoring unknown event"); - } + mHandlers->onDriverStateEvent(evt); +#endif delete evt; - if (rc) { - LOGW("Handler %d (%s) error: %s", evt->getType(), evt->getEvent(), strerror(errno)); - return false; - } return true; } diff --git a/nexus/SupplicantListener.h b/nexus/SupplicantListener.h index 3d186ad..a1da773 100644 --- a/nexus/SupplicantListener.h +++ b/nexus/SupplicantListener.h @@ -23,12 +23,13 @@ struct wpa_ctrl; class Supplicant; class SocketClient; class ISupplicantEventHandler; +class SupplicantEventFactory; class SupplicantListener: public SocketListener { -private: struct wpa_ctrl *mMonitor; ISupplicantEventHandler *mHandlers; - + SupplicantEventFactory *mFactory; + public: SupplicantListener(ISupplicantEventHandler *handlers, struct wpa_ctrl *monitor); diff --git a/nexus/SupplicantScanResultsEvent.cpp b/nexus/SupplicantScanResultsEvent.cpp new file mode 100644 index 0000000..c53adad --- /dev/null +++ b/nexus/SupplicantScanResultsEvent.cpp @@ -0,0 +1,34 @@ +/* + * 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. + */ + +#define LOG_TAG "SupplicantScanResultsEvent" +#include <cutils/log.h> + +#include "SupplicantScanResultsEvent.h" + +SupplicantScanResultsEvent::SupplicantScanResultsEvent(int level, char *event, + size_t len) : + SupplicantEvent(SupplicantEvent::EVENT_SCAN_RESULTS, + level) { +} + +SupplicantScanResultsEvent::SupplicantScanResultsEvent() : + SupplicantEvent(SupplicantEvent::EVENT_SCAN_RESULTS, -1) { +} + +SupplicantScanResultsEvent::~SupplicantScanResultsEvent() { +} + diff --git a/nexus/SupplicantScanResultsEvent.h b/nexus/SupplicantScanResultsEvent.h new file mode 100644 index 0000000..5f82041 --- /dev/null +++ b/nexus/SupplicantScanResultsEvent.h @@ -0,0 +1,30 @@ +/* + * 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 _SupplicantScanResultsEvent_H +#define _SupplicantScanResultsEvent_H + +#include "SupplicantEvent.h" + +class SupplicantScanResultsEvent : public SupplicantEvent { + +public: + SupplicantScanResultsEvent(int level, char *event, size_t len); + SupplicantScanResultsEvent(); + virtual ~SupplicantScanResultsEvent(); +}; + +#endif diff --git a/nexus/SupplicantStateChangeEvent.cpp b/nexus/SupplicantStateChangeEvent.cpp new file mode 100644 index 0000000..cf0b9da --- /dev/null +++ b/nexus/SupplicantStateChangeEvent.cpp @@ -0,0 +1,45 @@ +/* + * 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> + +#define LOG_TAG "SupplicantStateChangeEvent" +#include <cutils/log.h> + +#include "SupplicantStateChangeEvent.h" + +SupplicantStateChangeEvent::SupplicantStateChangeEvent(int level, char *event, + size_t len) : + SupplicantEvent(SupplicantEvent::EVENT_STATE_CHANGE, + level) { + // XXX: move this stuff into a static creation method + char *p = index(event, ' '); + if (!p) { + LOGW("Bad event '%s'\n", event); + return; + } + + mState = atoi(p + strlen("state=") + 1); +} + +SupplicantStateChangeEvent::SupplicantStateChangeEvent(int state) : + SupplicantEvent(SupplicantEvent::EVENT_STATE_CHANGE, -1) { + mState = state; +} + +SupplicantStateChangeEvent::~SupplicantStateChangeEvent() { +} + diff --git a/nexus/SupplicantStateChangeEvent.h b/nexus/SupplicantStateChangeEvent.h new file mode 100644 index 0000000..77bff65 --- /dev/null +++ b/nexus/SupplicantStateChangeEvent.h @@ -0,0 +1,34 @@ +/* + * 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 _SupplicantStateChangeEvent_H +#define _SupplicantStateChangeEvent_H + +#include "SupplicantEvent.h" + +class SupplicantStateChangeEvent : public SupplicantEvent { +private: + int mState; + +public: + SupplicantStateChangeEvent(int level, char *event, size_t len); + SupplicantStateChangeEvent(int state); + virtual ~SupplicantStateChangeEvent(); + + int getState() { return mState; } +}; + +#endif diff --git a/nexus/SupplicantStatus.cpp b/nexus/SupplicantStatus.cpp new file mode 100644 index 0000000..87f6c98 --- /dev/null +++ b/nexus/SupplicantStatus.cpp @@ -0,0 +1,72 @@ +/* + * 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> + +#define LOG_TAG "SupplicantState" +#include <cutils/log.h> + +#include "SupplicantStatus.h" +#include "SupplicantState.h" + +SupplicantStatus::SupplicantStatus() { + mWpaState = SupplicantState::UNKNOWN; + mId = -1; + mBssid = NULL; + mSsid = NULL; +} + +SupplicantStatus::SupplicantStatus(int state, int id, char *bssid, char *ssid) : + mWpaState(state), mId(id), mBssid(bssid), mSsid(ssid) { + +LOGD("state %d, id %d, bssid %p, ssid %p\n", mWpaState, mId, mBssid, mSsid); +} + +SupplicantStatus::~SupplicantStatus() { + if (mBssid) + free(mBssid); + if (mSsid) + free(mSsid); +} + +SupplicantStatus *SupplicantStatus::createStatus(char *data, int len) { + char *bssid = NULL; + char *ssid = NULL; + int id = -1; + int state = SupplicantState::UNKNOWN; + + char *next = data; + char *line; + while((line = strsep(&next, "\n"))) { + char *token = strsep(&next, "="); + char *value = strsep(&next, "="); + + if (!strcmp(token, "bssid")) + bssid = strdup(value); + else if (!strcmp(token, "ssid")) + ssid = strdup(value); + else if (!strcmp(token, "id")) + id = atoi(value); + else if (!strcmp(token, "wpa_state")) + state = atoi(value); + else + LOGD("Ignoring unsupported status token '%s'", token); + } + + return new SupplicantStatus(state, id, bssid, ssid); + +} diff --git a/nexus/SupplicantStatus.h b/nexus/SupplicantStatus.h new file mode 100644 index 0000000..ef01841 --- /dev/null +++ b/nexus/SupplicantStatus.h @@ -0,0 +1,42 @@ +/* + * 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 _SupplicantStatus_H +#define _SupplicantStatus_H + +class SupplicantStatus { +private: + int mWpaState; + int mId; + char *mBssid; + char *mSsid; + +private: + SupplicantStatus(); + SupplicantStatus(int state, int id, char *bssid, char *ssid); + +public: + virtual ~SupplicantStatus(); + static SupplicantStatus *createStatus(char *data, int len); + + int getWpaState() { return mWpaState; } + int getId() { return mId; } + const char *getBssid() { return mBssid; } + const char *getSsid() { return mSsid; } + +}; + +#endif diff --git a/nexus/TiwlanWifiController.cpp b/nexus/TiwlanWifiController.cpp index 307c48c..6945e3e 100644 --- a/nexus/TiwlanWifiController.cpp +++ b/nexus/TiwlanWifiController.cpp @@ -30,8 +30,12 @@ extern "C" int sched_yield(void); -TiwlanWifiController::TiwlanWifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs) : - WifiController(propmngr, modpath, modname, modargs) { +TiwlanWifiController::TiwlanWifiController(PropertyManager *propmngr, + IControllerHandler *handlers, + char *modpath, char *modname, + char *modargs) : + WifiController(propmngr, handlers, modpath, modname, + modargs) { } int TiwlanWifiController::powerUp() { diff --git a/nexus/TiwlanWifiController.h b/nexus/TiwlanWifiController.h index d3ebe88..852a288 100644 --- a/nexus/TiwlanWifiController.h +++ b/nexus/TiwlanWifiController.h @@ -20,9 +20,11 @@ #include "PropertyManager.h" #include "WifiController.h" +class IControllerHandler; + class TiwlanWifiController : public WifiController { public: - TiwlanWifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs); + TiwlanWifiController(PropertyManager *propmngr, IControllerHandler *handlers, char *modpath, char *modname, char *modargs); virtual ~TiwlanWifiController() {} virtual int powerUp(); diff --git a/nexus/VpnController.cpp b/nexus/VpnController.cpp index 1246703..add4dc3 100644 --- a/nexus/VpnController.cpp +++ b/nexus/VpnController.cpp @@ -25,18 +25,19 @@ #include "PropertyManager.h" #include "VpnController.h" -VpnController::VpnController(PropertyManager *propmngr) : - Controller("VPN", propmngr) { +VpnController::VpnController(PropertyManager *propmngr, + IControllerHandler *handlers) : + Controller("VPN", propmngr, handlers) { mEnabled = false; - propmngr->registerProperty("vpn.enabled", this); - propmngr->registerProperty("vpn.gateway", this); } int VpnController::start() { + mPropMngr->registerProperty("vpn.enabled", this); return 0; } int VpnController::stop() { + mPropMngr->unregisterProperty("vpn.enabled"); return 0; } @@ -49,8 +50,13 @@ int VpnController::set(const char *name, const char *value) { return 0; rc = (en ? enable() : disable()); - if (!rc) + if (!rc) { mEnabled = en; + if (en) + mPropMngr->unregisterProperty("vpn.gateway"); + else + mPropMngr->unregisterProperty("vpn.gateway"); + } return rc; } if (!strcmp(name, "vpn.gateway")) { if (!inet_aton(value, &mVpnGateway)) { diff --git a/nexus/VpnController.h b/nexus/VpnController.h index b36856f..1af4d9f 100644 --- a/nexus/VpnController.h +++ b/nexus/VpnController.h @@ -21,6 +21,8 @@ #include "Controller.h" +class IControllerHandler; + class VpnController : public Controller { bool mEnabled; /* @@ -29,7 +31,7 @@ class VpnController : public Controller { struct in_addr mVpnGateway; public: - VpnController(PropertyManager *propmngr); + VpnController(PropertyManager *propmngr, IControllerHandler *handlers); virtual ~VpnController() {} virtual int start(); diff --git a/nexus/WifiController.cpp b/nexus/WifiController.cpp index 3d06806..5c5db1a 100644 --- a/nexus/WifiController.cpp +++ b/nexus/WifiController.cpp @@ -27,34 +27,50 @@ #include "NetworkManager.h" #include "ErrorCode.h" #include "WifiNetwork.h" - -WifiController::WifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs) : - Controller("WIFI", propmngr) { +#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" + +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)); - mSupplicant = new Supplicant(this, propmngr); + mLatestScanResults = new ScanResultCollection(); + pthread_mutex_init(&mLatestScanResultsLock, NULL); + + mSupplicant = new Supplicant(this, this); mScanner = new WifiScanner(mSupplicant, 10); mCurrentScanMode = 0; mEnabled = false; - propmngr->registerProperty("wifi.enabled", this); + mSupplicantState = SupplicantState::UNKNOWN; } int WifiController::start() { + mPropMngr->registerProperty("wifi.enabled", this); return 0; } int WifiController::stop() { - errno = ENOSYS; - return -1; + mPropMngr->unregisterProperty("wifi.enabled"); + return 0; } int WifiController::enable() { if (!isPoweredUp()) { - sendStatusBroadcast("POWERING_UP"); + sendStatusBroadcast("Powering up WiFi hardware"); if (powerUp()) { LOGE("Powerup failed (%s)", strerror(errno)); return -1; @@ -62,7 +78,7 @@ int WifiController::enable() { } if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) { - sendStatusBroadcast("LOADING_DRIVER"); + sendStatusBroadcast("Loading WiFi driver"); if (loadKernelModule(mModulePath, mModuleArgs)) { LOGE("Kernel module load failed (%s)", strerror(errno)); goto out_powerdown; @@ -70,7 +86,7 @@ int WifiController::enable() { } if (!isFirmwareLoaded()) { - sendStatusBroadcast("LOADING_FIRMWARE"); + sendStatusBroadcast("Loading WiFI firmware"); if (loadFirmware()) { LOGE("Firmware load failed (%s)", strerror(errno)); goto out_powerdown; @@ -78,7 +94,7 @@ int WifiController::enable() { } if (!mSupplicant->isStarted()) { - sendStatusBroadcast("STARTING_SUPPLICANT"); + sendStatusBroadcast("Starting WPA Supplicant"); if (mSupplicant->start()) { LOGE("Supplicant start failed (%s)", strerror(errno)); goto out_unloadmodule; @@ -93,6 +109,7 @@ int WifiController::enable() { if (mSupplicant->refreshNetworkList()) LOGW("Error getting list of networks (%s)", strerror(errno)); + mPropMngr->registerProperty("wifi.supplicant.state", this); mPropMngr->registerProperty("wifi.scanmode", this); mPropMngr->registerProperty("wifi.interface", this); @@ -121,8 +138,11 @@ void WifiController::sendStatusBroadcast(const char *msg) { int WifiController::disable() { mPropMngr->unregisterProperty("wifi.scanmode"); + mPropMngr->unregisterProperty("wifi.supplicant.state"); + mPropMngr->unregisterProperty("wifi.scanmode"); + if (mSupplicant->isStarted()) { - sendStatusBroadcast("STOPPING_SUPPLICANT"); + sendStatusBroadcast("Stopping WPA Supplicant"); if (mSupplicant->stop()) { LOGE("Supplicant stop failed (%s)", strerror(errno)); return -1; @@ -131,7 +151,7 @@ int WifiController::disable() { LOGW("disable(): Supplicant not running?"); if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) { - sendStatusBroadcast("UNLOADING_DRIVER"); + sendStatusBroadcast("Unloading WiFi driver"); if (unloadKernelModule(mModuleName)) { LOGE("Unable to unload module (%s)", strerror(errno)); return -1; @@ -139,7 +159,7 @@ int WifiController::disable() { } if (isPoweredUp()) { - sendStatusBroadcast("POWERING_DOWN"); + sendStatusBroadcast("Powering down WiFi hardware"); if (powerDown()) { LOGE("Powerdown failed (%s)", strerror(errno)); return -1; @@ -184,7 +204,15 @@ int WifiController::removeNetwork(int networkId) { } ScanResultCollection *WifiController::createScanResults() { - return mSupplicant->createLatestScanResults(); + 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() { @@ -207,7 +235,10 @@ int WifiController::set(const char *name, const char *value) { return -1; } else if (!strcmp(name, "wifi.scanmode")) return setScanMode((uint32_t) strtoul(value, NULL, 0)); - else + else if (!strcmp(name, "wifi.supplicant.state")) { + errno = EROFS; + return -1; + } else return Controller::set(name, value); return rc; } @@ -221,9 +252,158 @@ const char *WifiController::get(const char *name, char *buffer, size_t maxsize) (getBoundInterface() ? getBoundInterface() : "none")); } else if (!strcmp(name, "wifi.scanmode")) snprintf(buffer, maxsize, "0x%.8x", mCurrentScanMode); + else if (!strcmp(name, "wifi.supplicant.state")) + return SupplicantState::toString(mSupplicantState, buffer, maxsize); else return Controller::get(name, buffer, maxsize); return buffer; } +void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) { + LOGD("onAssociatingEvent(%s, %s, %d)", + (evt->getBssid() ? evt->getBssid() : "n/a"), + (evt->getSsid() ? evt->getSsid() : "n/a"), + evt->getFreq()); +} + +void WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) { + LOGD("onAssociatedEvent(%s)", evt->getBssid()); +} + +void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) { + LOGD("onConnectedEvent(%s, %d)", evt->getBssid(), evt->getReassociated()); + if (!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; + } + + if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) { + LOGW("Error looking up connected network id %d (%s)", + ss->getId(), strerror(errno)); + return; + } + + delete ss; + mHandlers->onInterfaceStarted(this, wn->getIfaceCfg()); + } +} + +void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) { + char *reply; + + if (!(reply = (char *) malloc(4096))) { + LOGE("Out of memory"); + return; + } + + 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)); + + char *tmp; + asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size()); + NetworkManager::Instance()->getBroadcaster()-> + sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false); + free(tmp); + pthread_mutex_unlock(&mLatestScanResultsLock); + free(reply); +} + +void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) { + char tmp[32]; + char tmp2[32]; + + LOGD("onStateChangeEvent(%s -> %s)", + SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)), + SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2))); + + mSupplicantState = evt->getState(); +} + +void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) { + LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid()); +} + +void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) { + LOGD("onDisconnectedEvent()"); +} + +#if 0 +void WifiController::onTerminatingEvent(SupplicantEvent *evt) { + LOGD("onTerminatingEvent(%s)", evt->getEvent()); +} + +void WifiController::onPasswordChangedEvent(SupplicantEvent *evt) { + LOGD("onPasswordChangedEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapNotificationEvent(SupplicantEvent *evt) { + LOGD("onEapNotificationEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapStartedEvent(SupplicantEvent *evt) { + LOGD("onEapStartedEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapMethodEvent(SupplicantEvent *evt) { + LOGD("onEapMethodEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapSuccessEvent(SupplicantEvent *evt) { + LOGD("onEapSuccessEvent(%s)", evt->getEvent()); +} + +void WifiController::onEapFailureEvent(SupplicantEvent *evt) { + LOGD("onEapFailureEvent(%s)", evt->getEvent()); +} + +void WifiController::onLinkSpeedEvent(SupplicantEvent *evt) { + LOGD("onLinkSpeedEvent(%s)", evt->getEvent()); +} + +void WifiController::onDriverStateEvent(SupplicantEvent *evt) { + LOGD("onDriverStateEvent(%s)", evt->getEvent()); +} +#endif diff --git a/nexus/WifiController.h b/nexus/WifiController.h index b2f4530..c61d97a 100644 --- a/nexus/WifiController.h +++ b/nexus/WifiController.h @@ -20,15 +20,21 @@ #include <sys/types.h> #include "Controller.h" +#include "ScanResult.h" +#include "WifiNetwork.h" +#include "ISupplicantEventHandler.h" class NetInterface; class Supplicant; class WifiScanner; - -#include "ScanResult.h" -#include "WifiNetwork.h" - -class WifiController : public Controller { +class SupplicantAssociatingEvent; +class SupplicantAssociatedEvent; +class SupplicantConnectedEvent; +class SupplicantScanResultsEvent; +class SupplicantStateChangeEvent; +class SupplicantDisconnectedEvent; + +class WifiController : public Controller, public ISupplicantEventHandler { public: static const uint32_t SCAN_ENABLE_MASK = 0x01; static const uint32_t SCAN_ACTIVE_MASK = 0x02; @@ -45,12 +51,18 @@ private: char mModulePath[255]; char mModuleName[64]; char mModuleArgs[255]; + uint32_t mCurrentScanMode; WifiScanner *mScanner; + int mSupplicantState; + + ScanResultCollection *mLatestScanResults; + pthread_mutex_t mLatestScanResultsLock; + bool mEnabled; public: - WifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs); + WifiController(PropertyManager *propmngr, IControllerHandler *handlers, char *modpath, char *modname, char *modargs); virtual ~WifiController() {} int start(); @@ -85,6 +97,27 @@ private: int setScanMode(uint32_t mode); int enable(); int disable(); + + // ISupplicantEventHandler methods + virtual void onAssociatingEvent(SupplicantAssociatingEvent *evt); + virtual void onAssociatedEvent(SupplicantAssociatedEvent *evt); + virtual void onConnectedEvent(SupplicantConnectedEvent *evt); + virtual void onScanResultsEvent(SupplicantScanResultsEvent *evt); + virtual void onStateChangeEvent(SupplicantStateChangeEvent *evt); + virtual void onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt); + virtual void onDisconnectedEvent(SupplicantDisconnectedEvent *evt); +#if 0 + virtual void onTerminatingEvent(SupplicantEvent *evt); + virtual void onPasswordChangedEvent(SupplicantEvent *evt); + virtual void onEapNotificationEvent(SupplicantEvent *evt); + virtual void onEapStartedEvent(SupplicantEvent *evt); + virtual void onEapMethodEvent(SupplicantEvent *evt); + virtual void onEapSuccessEvent(SupplicantEvent *evt); + virtual void onEapFailureEvent(SupplicantEvent *evt); + virtual void onLinkSpeedEvent(SupplicantEvent *evt); + virtual void onDriverStateEvent(SupplicantEvent *evt); +#endif + }; #endif diff --git a/nexus/WifiNetwork.cpp b/nexus/WifiNetwork.cpp index 818b91d..7059bd0 100644 --- a/nexus/WifiNetwork.cpp +++ b/nexus/WifiNetwork.cpp @@ -76,7 +76,7 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data) mDefaultKeyIndex = -1; mPriority = -1; mHiddenSsid = NULL; - mAllowedKeyManagement = 0; + mAllowedKeyManagement = KeyManagementMask::UNKNOWN; mAllowedProtocols = 0; mAllowedAuthAlgorithms = 0; mAllowedPairwiseCiphers = 0; @@ -94,8 +94,6 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data) asprintf(&tmp2, "wifi.net.%d", mNetid); mIfaceCfg = new InterfaceConfig(tmp2); free(tmp2); - - registerProperties(); free(tmp); } @@ -121,8 +119,6 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, int networkId) { asprintf(&tmp2, "wifi.net.%d", mNetid); mIfaceCfg = new InterfaceConfig(tmp2); free(tmp2); - - registerProperties(); } WifiNetwork *WifiNetwork::clone() { @@ -153,7 +149,6 @@ WifiNetwork *WifiNetwork::clone() { } WifiNetwork::~WifiNetwork() { - unregisterProperties(); if (mSsid) free(mSsid); if (mBssid) @@ -203,7 +198,26 @@ int WifiNetwork::refresh() { len = sizeof(buffer); if (mSuppl->getNetworkVar(mNetid, "key_mgmt", buffer, len)) { - // TODO + if (!strcmp(buffer, "NONE")) + setAllowedKeyManagement(KeyManagementMask::NONE); + else if (index(buffer, ' ')) { + char *next = buffer; + char *token; + uint32_t mask = 0; + + while((token = strsep(&next, " "))) { + if (!strcmp(token, "WPA-PSK")) + mask |= KeyManagementMask::WPA_PSK; + else if (!strcmp(token, "WPA-EAP")) + mask |= KeyManagementMask::WPA_EAP; + else if (!strcmp(token, "IEE8021X")) + mask |= KeyManagementMask::IEEE8021X; + else + LOGW("Unsupported key management scheme '%s'" , token); + } + setAllowedKeyManagement(mask); + } else + LOGE("Unsupported key management '%s'", buffer); } len = sizeof(buffer); @@ -273,7 +287,7 @@ int WifiNetwork::set(const char *name, const char *value) { while((v_token = strsep(&v_next, " "))) { if (!strcasecmp(v_token, "NONE")) { - mask = 0; + mask = KeyManagementMask::NONE; none = true; } else if (!none) { if (!strcasecmp(v_token, "WPA_PSK")) @@ -363,7 +377,29 @@ const char *WifiNetwork::get(const char *name, char *buffer, size_t maxsize) { snprintf(buffer, maxsize, "%d", getDefaultKeyIndex()); else if (!strcasecmp(fc, "pri")) snprintf(buffer, maxsize, "%d", getPriority()); - else if (!strcasecmp(fc, "hiddenssid")) { + else if (!strcasecmp(fc, "AllowedKeyManagement")) { + if (getAllowedKeyManagement() == KeyManagementMask::NONE) + strncpy(buffer, "NONE", maxsize); + else { + char tmp[80] = { '\0' }; + + if (getAllowedKeyManagement() & KeyManagementMask::WPA_PSK) + strcat(tmp, "WPA_PSK "); + if (getAllowedKeyManagement() & KeyManagementMask::WPA_EAP) + strcat(tmp, "WPA_EAP "); + if (getAllowedKeyManagement() & KeyManagementMask::IEEE8021X) + strcat(tmp, "IEEE8021X"); + if (tmp[0] == '\0') { + strncpy(buffer, "(internal error)", maxsize); + errno = ENOENT; + return NULL; + } + if (tmp[strlen(tmp)] == ' ') + tmp[strlen(tmp)] = '\0'; + + strncpy(buffer, tmp, maxsize); + } + } else if (!strcasecmp(fc, "hiddenssid")) { strncpy(buffer, getHiddenSsid() ? getHiddenSsid() : "none", maxsize); diff --git a/nexus/WifiNetwork.h b/nexus/WifiNetwork.h index 360ccc2..c2f5d23 100644 --- a/nexus/WifiNetwork.h +++ b/nexus/WifiNetwork.h @@ -157,8 +157,6 @@ private: private: WifiNetwork(); - int registerProperties(); - int unregisterProperties(); public: WifiNetwork(WifiController *c, Supplicant *suppl, int networkId); @@ -167,6 +165,8 @@ public: virtual ~WifiNetwork(); WifiNetwork *clone(); + int registerProperties(); + int unregisterProperties(); int getNetworkId() { return mNetid; } const char *getSsid() { return mSsid; } @@ -187,7 +187,7 @@ public: int set(const char *name, const char *value); const char *get(const char *name, char *buffer, size_t maxsize); -// InterfaceConfig *getIfaceCfg() { return mIfaceCfg; } + InterfaceConfig *getIfaceCfg() { return mIfaceCfg; } int setEnabled(bool enabled); int setSsid(const char *ssid); diff --git a/nexus/main.cpp b/nexus/main.cpp index e460d42..936d33f 100644 --- a/nexus/main.cpp +++ b/nexus/main.cpp @@ -40,10 +40,10 @@ int main() { nm->setBroadcaster((SocketListener *) cl); - nm->attachController(new LoopController(nm->getPropMngr())); - nm->attachController(new TiwlanWifiController(nm->getPropMngr(), "/system/lib/modules/wlan.ko", "wlan", "")); -// nm->attachController(new AndroidL2TPVpnController()); - nm->attachController(new OpenVpnController(nm->getPropMngr())); + nm->attachController(new LoopController(nm->getPropMngr(), nm)); + nm->attachController(new TiwlanWifiController(nm->getPropMngr(), nm, "/system/lib/modules/wlan.ko", "wlan", "")); +// nm->attachController(new AndroidL2TPVpnController(nm->getPropMngr(), nm)); + nm->attachController(new OpenVpnController(nm->getPropMngr(), nm)); if (NetworkManager::Instance()->run()) { |