• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


コミットメタ情報

リビジョン43c16197b2a6da3a3125b4a4a9fa6b70f447043e (tree)
日時2009-06-16 06:40:51
作者Android (Google) Code Review <android-gerrit@goog...>
コミッターAndroid (Google) Code Review

ログメッセージ

Merge change 4228 into donut

* changes:

Nexus: Clean up supplicant events, protocol, and continue plumbing

変更サマリ

差分

--- a/nexus/Android.mk
+++ b/nexus/Android.mk
@@ -5,26 +5,35 @@ LOCAL_PATH:= $(call my-dir)
55
66 include $(CLEAR_VARS)
77
8-LOCAL_SRC_FILES:= \
9- main.cpp \
10- NetworkManager.cpp \
11- CommandListener.cpp \
12- Controller.cpp \
13- WifiController.cpp \
14- LoopController.cpp \
15- NexusCommand.cpp \
16- TiwlanWifiController.cpp \
17- Supplicant.cpp \
18- SupplicantEvent.cpp \
19- SupplicantListener.cpp \
20- VpnController.cpp \
21- ScanResult.cpp \
22- WifiScanner.cpp \
23- WifiNetwork.cpp \
24- OpenVpnController.cpp \
25- InterfaceConfig.cpp \
26- PropertyManager.cpp \
27- SupplicantState.cpp
8+LOCAL_SRC_FILES:= \
9+ main.cpp \
10+ NetworkManager.cpp \
11+ CommandListener.cpp \
12+ Controller.cpp \
13+ WifiController.cpp \
14+ LoopController.cpp \
15+ NexusCommand.cpp \
16+ TiwlanWifiController.cpp \
17+ Supplicant.cpp \
18+ SupplicantEvent.cpp \
19+ SupplicantListener.cpp \
20+ VpnController.cpp \
21+ ScanResult.cpp \
22+ WifiScanner.cpp \
23+ WifiNetwork.cpp \
24+ OpenVpnController.cpp \
25+ InterfaceConfig.cpp \
26+ PropertyManager.cpp \
27+ SupplicantState.cpp \
28+ SupplicantEventFactory.cpp \
29+ SupplicantConnectedEvent.cpp \
30+ SupplicantAssociatingEvent.cpp \
31+ SupplicantAssociatedEvent.cpp \
32+ SupplicantStateChangeEvent.cpp \
33+ SupplicantScanResultsEvent.cpp \
34+ SupplicantConnectionTimeoutEvent.cpp \
35+ SupplicantDisconnectedEvent.cpp \
36+ SupplicantStatus.cpp
2837
2938 LOCAL_MODULE:= nexus
3039
--- a/nexus/CommandListener.cpp
+++ b/nexus/CommandListener.cpp
@@ -53,7 +53,8 @@ CommandListener::WifiCreateNetworkCmd::WifiCreateNetworkCmd() :
5353 NexusCommand("wifi_create_network") {
5454 }
5555
56-int CommandListener::WifiCreateNetworkCmd::runCommand(SocketClient *cli, char *data) {
56+int CommandListener::WifiCreateNetworkCmd::runCommand(SocketClient *cli,
57+ int argc, char **argv) {
5758 NetworkManager *nm = NetworkManager::Instance();
5859 WifiController *wc = (WifiController *) nm->findController("WIFI");
5960 WifiNetwork *wn;
@@ -72,11 +73,12 @@ CommandListener::WifiRemoveNetworkCmd::WifiRemoveNetworkCmd() :
7273 NexusCommand("wifi_remove_network") {
7374 }
7475
75-int CommandListener::WifiRemoveNetworkCmd::runCommand(SocketClient *cli, char *data) {
76+int CommandListener::WifiRemoveNetworkCmd::runCommand(SocketClient *cli,
77+ int argc, char **argv) {
7678 NetworkManager *nm = NetworkManager::Instance();
7779 WifiController *wc = (WifiController *) nm->findController("WIFI");
7880
79- if (wc->removeNetwork(atoi(data)))
81+ if (wc->removeNetwork(atoi(argv[1])))
8082 cli->sendMsg(ErrorCode::OperationFailed, "Failed to remove network", true);
8183 else {
8284 cli->sendMsg(ErrorCode::CommandOkay, "Network removed.", false);
@@ -88,7 +90,8 @@ CommandListener::WifiScanResultsCmd::WifiScanResultsCmd() :
8890 NexusCommand("wifi_scan_results") {
8991 }
9092
91-int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, char *data) {
93+int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli,
94+ int argc, char **argv) {
9295 NetworkManager *nm = NetworkManager::Instance();
9396 WifiController *wc = (WifiController *) nm->findController("WIFI");
9497
@@ -114,7 +117,8 @@ CommandListener::WifiListNetworksCmd::WifiListNetworksCmd() :
114117 NexusCommand("wifi_list_networks") {
115118 }
116119
117-int CommandListener::WifiListNetworksCmd::runCommand(SocketClient *cli, char *data) {
120+int CommandListener::WifiListNetworksCmd::runCommand(SocketClient *cli,
121+ int argc, char **argv) {
118122 NetworkManager *nm = NetworkManager::Instance();
119123 WifiController *wc = (WifiController *) nm->findController("WIFI");
120124
@@ -144,23 +148,19 @@ CommandListener::GetCmd::GetCmd() :
144148 NexusCommand("get") {
145149 }
146150
147-int CommandListener::GetCmd::runCommand(SocketClient *cli, char *data) {
148- char *next = data;
149- char *propname;
151+int CommandListener::GetCmd::runCommand(SocketClient *cli, int argc, char **argv) {
152+ char val[Property::ValueMaxSize];
150153
151- if (!(propname = strsep(&next, ":")))
152- goto out_inval;
153-
154- char pb[Property::NameMaxSize + 6];
155- snprintf(pb, sizeof(pb), "%s:", propname);
156-
157- if (!NetworkManager::Instance()->getPropMngr()->get(propname,
158- &pb[strlen(pb)],
159- sizeof(pb) - strlen(pb))) {
154+ if (!NetworkManager::Instance()->getPropMngr()->get(argv[1],
155+ val,
156+ sizeof(val))) {
160157 goto out_inval;
161158 }
162159
163- cli->sendMsg(ErrorCode::PropertyRead, pb, false);
160+ char *tmp;
161+ asprintf(&tmp, "%s %s", argv[1], val);
162+ cli->sendMsg(ErrorCode::PropertyRead, tmp, false);
163+ free(tmp);
164164
165165 cli->sendMsg(ErrorCode::CommandOkay, "Property read.", false);
166166 return 0;
@@ -174,23 +174,9 @@ CommandListener::SetCmd::SetCmd() :
174174 NexusCommand("set") {
175175 }
176176
177-int CommandListener::SetCmd::runCommand(SocketClient *cli, char *data) {
178- char *bword;
179- char *last;
180- char propname[Property::NameMaxSize];
181- char propval[Property::ValueMaxSize];
182-
183- if (!(bword = strtok_r(data, ":", &last)))
184- goto out_inval;
185-
186- strncpy(propname, bword, sizeof(propname));
187-
188- if (!(bword = strtok_r(NULL, ":", &last)))
189- goto out_inval;
190-
191- strncpy(propval, bword, sizeof(propval));
192-
193- if (NetworkManager::Instance()->getPropMngr()->set(propname, propval))
177+int CommandListener::SetCmd::runCommand(SocketClient *cli, int argc,
178+ char **argv) {
179+ if (NetworkManager::Instance()->getPropMngr()->set(argv[1], argv[2]))
194180 goto out_inval;
195181
196182 cli->sendMsg(ErrorCode::CommandOkay, "Property set.", false);
@@ -206,7 +192,7 @@ CommandListener::ListCmd::ListCmd() :
206192 NexusCommand("list") {
207193 }
208194
209-int CommandListener::ListCmd::runCommand(SocketClient *cli, char *data) {
195+int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **argv) {
210196 android::List<char *> *pc;
211197
212198 if (!(pc = NetworkManager::Instance()->getPropMngr()->createPropertyList())) {
@@ -227,7 +213,7 @@ int CommandListener::ListCmd::runCommand(SocketClient *cli, char *data) {
227213 }
228214
229215 char *buf;
230- if (asprintf(&buf, "%s:%s", (*it), p_v) < 0) {
216+ if (asprintf(&buf, "%s %s", (*it), p_v) < 0) {
231217 LOGE("Failed to allocate memory");
232218 free((*it));
233219 continue;
--- a/nexus/CommandListener.h
+++ b/nexus/CommandListener.h
@@ -31,56 +31,56 @@ private:
3131 public:
3232 WifiScanCmd();
3333 virtual ~WifiScanCmd() {}
34- int runCommand(SocketClient *c, char *data);
34+ int runCommand(SocketClient *c, int argc, char ** argv);
3535 };
3636
3737 class WifiScanResultsCmd : public NexusCommand {
3838 public:
3939 WifiScanResultsCmd();
4040 virtual ~WifiScanResultsCmd() {}
41- int runCommand(SocketClient *c, char *data);
41+ int runCommand(SocketClient *c, int argc, char ** argv);
4242 };
4343
4444 class WifiCreateNetworkCmd : public NexusCommand {
4545 public:
4646 WifiCreateNetworkCmd();
4747 virtual ~WifiCreateNetworkCmd() {}
48- int runCommand(SocketClient *c, char *data);
48+ int runCommand(SocketClient *c, int argc, char ** argv);
4949 };
5050
5151 class WifiRemoveNetworkCmd : public NexusCommand {
5252 public:
5353 WifiRemoveNetworkCmd();
5454 virtual ~WifiRemoveNetworkCmd() {}
55- int runCommand(SocketClient *c, char *data);
55+ int runCommand(SocketClient *c, int argc, char ** argv);
5656 };
5757
5858 class WifiListNetworksCmd : public NexusCommand {
5959 public:
6060 WifiListNetworksCmd();
6161 virtual ~WifiListNetworksCmd() {}
62- int runCommand(SocketClient *c, char *data);
62+ int runCommand(SocketClient *c, int argc, char ** argv);
6363 };
6464
6565 class SetCmd : public NexusCommand {
6666 public:
6767 SetCmd();
6868 virtual ~SetCmd() {}
69- int runCommand(SocketClient *c, char *data);
69+ int runCommand(SocketClient *c, int argc, char ** argv);
7070 };
7171
7272 class GetCmd : public NexusCommand {
7373 public:
7474 GetCmd();
7575 virtual ~GetCmd() {}
76- int runCommand(SocketClient *c, char *data);
76+ int runCommand(SocketClient *c, int argc, char ** argv);
7777 };
7878
7979 class ListCmd : public NexusCommand {
8080 public:
8181 ListCmd();
8282 virtual ~ListCmd() {}
83- int runCommand(SocketClient *c, char *data);
83+ int runCommand(SocketClient *c, int argc, char ** argv);
8484 };
8585 };
8686
--- a/nexus/Controller.cpp
+++ b/nexus/Controller.cpp
@@ -34,9 +34,11 @@
3434 extern "C" int init_module(void *, unsigned int, const char *);
3535 extern "C" int delete_module(const char *, unsigned int);
3636
37-Controller::Controller(const char *name, PropertyManager *propMngr) {
37+Controller::Controller(const char *name, PropertyManager *propMngr,
38+ IControllerHandler *handlers) {
3839 mPropMngr = propMngr;
3940 mName = strdup(name);
41+ mHandlers = handlers;
4042 mBoundInterface = NULL;
4143 }
4244
--- a/nexus/Controller.h
+++ b/nexus/Controller.h
@@ -23,12 +23,12 @@
2323 #include <utils/List.h>
2424
2525 class PropertyManager;
26+class IControllerHandler;
2627
2728 #include "PropertyManager.h"
2829 #include "IPropertyProvider.h"
2930
3031 class Controller : public IPropertyProvider {
31-private:
3232 /*
3333 * Name of this controller - WIFI/VPN/USBNET/BTNET/BTDUN/LOOP/etc
3434 */
@@ -42,9 +42,11 @@ private:
4242
4343 protected:
4444 PropertyManager *mPropMngr;
45+ IControllerHandler *mHandlers;
4546
4647 public:
47- Controller(const char *name, PropertyManager *propMngr);
48+ Controller(const char *name, PropertyManager *propMngr,
49+ IControllerHandler *handlers);
4850 virtual ~Controller();
4951
5052 virtual int start();
--- /dev/null
+++ b/nexus/IControllerHandler.h
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _ICONTROLLER_HANDLER_H
18+#define _ICONTROLLER_HANDLER_H
19+
20+class Controller;
21+class InterfaceConfig;
22+
23+class IControllerHandler {
24+public:
25+ virtual void onInterfaceStarted(Controller *c, const InterfaceConfig *cfg) = 0;
26+ virtual void onInterfaceStopping(Controller *c, const char *name) = 0;
27+};
28+
29+#endif
30+
--- a/nexus/ISupplicantEventHandler.h
+++ b/nexus/ISupplicantEventHandler.h
@@ -17,21 +17,34 @@
1717 #ifndef _ISUPPLICANT_EVENT_HANDLER_H
1818 #define _ISUPPLICANT_EVENT_HANDLER_H
1919
20+class SupplicantAssociatingEvent;
21+class SupplicantAssociatedEvent;
22+class SupplicantConnectedEvent;
23+class SupplicantScanResultsEvent;
24+class SupplicantStateChangeEvent;
25+class SupplicantConnectionTimeoutEvent;
26+class SupplicantDisconnectedEvent;
27+
2028 class ISupplicantEventHandler {
2129 public:
22- virtual int onConnectedEvent(SupplicantEvent *evt) = 0;
23- virtual int onDisconnectedEvent(SupplicantEvent *evt) = 0;
24- virtual int onTerminatingEvent(SupplicantEvent *evt) = 0;
25- virtual int onPasswordChangedEvent(SupplicantEvent *evt) = 0;
26- virtual int onEapNotificationEvent(SupplicantEvent *evt) = 0;
27- virtual int onEapStartedEvent(SupplicantEvent *evt) = 0;
28- virtual int onEapMethodEvent(SupplicantEvent *evt) = 0;
29- virtual int onEapSuccessEvent(SupplicantEvent *evt) = 0;
30- virtual int onEapFailureEvent(SupplicantEvent *evt) = 0;
31- virtual int onScanResultsEvent(SupplicantEvent *evt) = 0;
32- virtual int onStateChangeEvent(SupplicantEvent *evt) = 0;
33- virtual int onLinkSpeedEvent(SupplicantEvent *evt) = 0;
34- virtual int onDriverStateEvent(SupplicantEvent *evt) = 0;
30+ virtual void onAssociatingEvent(SupplicantAssociatingEvent *evt) = 0;
31+ virtual void onAssociatedEvent(SupplicantAssociatedEvent *evt) = 0;
32+ virtual void onConnectedEvent(SupplicantConnectedEvent *evt) = 0;
33+ virtual void onScanResultsEvent(SupplicantScanResultsEvent *evt) = 0;
34+ virtual void onStateChangeEvent(SupplicantStateChangeEvent *evt) = 0;
35+ virtual void onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) = 0;
36+ virtual void onDisconnectedEvent(SupplicantDisconnectedEvent *evt) = 0;
37+#if 0
38+ virtual void onTerminatingEvent(SupplicantEvent *evt) = 0;
39+ virtual void onPasswordChangedEvent(SupplicantEvent *evt) = 0;
40+ virtual void onEapNotificationEvent(SupplicantEvent *evt) = 0;
41+ virtual void onEapStartedEvent(SupplicantEvent *evt) = 0;
42+ virtual void onEapMethodEvent(SupplicantEvent *evt) = 0;
43+ virtual void onEapSuccessEvent(SupplicantEvent *evt) = 0;
44+ virtual void onEapFailureEvent(SupplicantEvent *evt) = 0;
45+ virtual void onLinkSpeedEvent(SupplicantEvent *evt) = 0;
46+ virtual void onDriverStateEvent(SupplicantEvent *evt) = 0;
47+#endif
3548 };
3649
3750 #endif
--- a/nexus/LoopController.cpp
+++ b/nexus/LoopController.cpp
@@ -19,8 +19,9 @@
1919 #include "LoopController.h"
2020 #include "PropertyManager.h"
2121
22-LoopController::LoopController(PropertyManager *propmngr) :
23- Controller("LOOP", propmngr) {
22+LoopController::LoopController(PropertyManager *propmngr,
23+ IControllerHandler *handlers) :
24+ Controller("LOOP", propmngr, handlers) {
2425 }
2526
2627 int LoopController::set(const char *name, const char *value) {
--- a/nexus/LoopController.h
+++ b/nexus/LoopController.h
@@ -19,10 +19,11 @@
1919
2020 #include "Controller.h"
2121
22+class ControllerHandler;
2223
2324 class LoopController : public Controller {
2425 public:
25- LoopController(PropertyManager *propmngr);
26+ LoopController(PropertyManager *propmngr, IControllerHandler *h);
2627 virtual ~LoopController() {}
2728
2829 int set(const char *name, const char *value);
--- a/nexus/NetworkManager.cpp
+++ b/nexus/NetworkManager.cpp
@@ -89,23 +89,26 @@ Controller *NetworkManager::findController(const char *name) {
8989 return NULL;
9090 }
9191
92-int NetworkManager::onInterfaceStart(Controller *c, const InterfaceConfig *cfg) {
92+void NetworkManager::onInterfaceStarted(Controller *c, const InterfaceConfig *cfg) {
9393 LOGD("Interface %s started by controller %s", c->getBoundInterface(), c->getName());
9494
9595 // Look up the interface
9696
9797 if (0) { // already started?
98- errno = EADDRINUSE;
99- return -1;
10098 }
10199
102- if (cfg->getUseDhcp()) {
100+ if (cfg) {
101+ if (cfg->getUseDhcp()) {
102+ // Launch DHCP thread
103+ } else {
104+ // Static configuration
105+ }
103106 } else {
107+ LOGD("No InterfaceConfig for %s:%s - assuming self-managed",
108+ c->getName(), c->getBoundInterface());
104109 }
105- return 0;
106110 }
107111
108-int NetworkManager::onInterfaceStop(Controller *c, const char *name) {
112+void NetworkManager::onInterfaceStopping(Controller *c, const char *name) {
109113 LOGD("Interface %s stopped by controller %s", name, c->getName());
110- return 0;
111114 }
--- a/nexus/NetworkManager.h
+++ b/nexus/NetworkManager.h
@@ -20,12 +20,12 @@
2020 #include <sysutils/SocketListener.h>
2121
2222 #include "Controller.h"
23-
2423 #include "PropertyManager.h"
24+#include "IControllerHandler.h"
2525
2626 class InterfaceConfig;
2727
28-class NetworkManager {
28+class NetworkManager : public IControllerHandler {
2929 private:
3030 static NetworkManager *sInstance;
3131
@@ -55,16 +55,7 @@ private:
5555
5656 NetworkManager(PropertyManager *propMngr);
5757
58-public:
59- /*
60- * Called from a controller when an interface is available/ready for use.
61- * 'cfg' contains information on how this interface should be configured.
62- */
63- int onInterfaceStart(Controller *c, const InterfaceConfig *cfg);
64-
65- /*
66- * Called from a controller when an interface should be shut down
67- */
68- int onInterfaceStop(Controller *c, const char *name);
58+ void onInterfaceStarted(Controller *c, const InterfaceConfig *cfg);
59+ void onInterfaceStopping(Controller *c, const char *name);
6960 };
7061 #endif
--- a/nexus/OpenVpnController.cpp
+++ b/nexus/OpenVpnController.cpp
@@ -30,8 +30,9 @@
3030 #define DAEMON_PROP_NAME "vpn.openvpn.status"
3131 #define DAEMON_CONFIG_FILE "/data/misc/openvpn/openvpn.conf"
3232
33-OpenVpnController::OpenVpnController(PropertyManager *propmngr) :
34- VpnController(propmngr) {
33+OpenVpnController::OpenVpnController(PropertyManager *propmngr,
34+ IControllerHandler *handlers) :
35+ VpnController(propmngr, handlers) {
3536 mServiceManager = new ServiceManager();
3637 }
3738
@@ -40,11 +41,11 @@ OpenVpnController::~OpenVpnController() {
4041 }
4142
4243 int OpenVpnController::start() {
43- return 0;
44+ return VpnController::start();
4445 }
4546
4647 int OpenVpnController::stop() {
47- return 0;
48+ return VpnController::stop();
4849 }
4950
5051 int OpenVpnController::enable() {
--- a/nexus/OpenVpnController.h
+++ b/nexus/OpenVpnController.h
@@ -21,13 +21,14 @@
2121 #include "VpnController.h"
2222
2323 class ServiceManager;
24+class IControllerHandler;
2425
2526 class OpenVpnController : public VpnController {
2627 private:
2728 ServiceManager *mServiceManager;
2829
2930 public:
30- OpenVpnController(PropertyManager *propmngr);
31+ OpenVpnController(PropertyManager *propmngr, IControllerHandler *handlers);
3132 virtual ~OpenVpnController();
3233
3334 int start();
--- a/nexus/PropertyManager.cpp
+++ b/nexus/PropertyManager.cpp
@@ -37,7 +37,8 @@ int PropertyManager::registerProperty(const char *name, IPropertyProvider *pp) {
3737 for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) {
3838 if (!strcmp(name, (*it)->getName())) {
3939 errno = EADDRINUSE;
40- LOGE("Failed to register property (%s)", strerror(errno));
40+ LOGE("Failed to register property %s (%s)",
41+ name, strerror(errno));
4142 pthread_mutex_unlock(&mLock);
4243 return -1;
4344 }
--- a/nexus/Supplicant.cpp
+++ b/nexus/Supplicant.cpp
@@ -29,13 +29,10 @@
2929
3030 #include "Supplicant.h"
3131 #include "SupplicantListener.h"
32-#include "SupplicantState.h"
33-#include "SupplicantEvent.h"
34-#include "ScanResult.h"
35-#include "PropertyManager.h"
3632 #include "NetworkManager.h"
3733 #include "ErrorCode.h"
3834 #include "WifiController.h"
35+#include "SupplicantStatus.h"
3936
4037 #include "libwpa_client/wpa_ctrl.h"
4138
@@ -45,21 +42,16 @@
4542 #define SUPP_CONFIG_TEMPLATE "/system/etc/wifi/wpa_supplicant.conf"
4643 #define SUPP_CONFIG_FILE "/data/misc/wifi/wpa_supplicant.conf"
4744
48-Supplicant::Supplicant(WifiController *wc, PropertyManager *propmngr) {
45+Supplicant::Supplicant(WifiController *wc, ISupplicantEventHandler *handlers) {
46+ mHandlers = handlers;
4947 mController = wc;
50- mPropMngr = propmngr;
5148 mInterfaceName = NULL;
5249 mCtrl = NULL;
5350 mMonitor = NULL;
5451 mListener = NULL;
5552
56- mState = SupplicantState::UNKNOWN;
57-
5853 mServiceManager = new ServiceManager();
5954
60- mLatestScanResults = new ScanResultCollection();
61- pthread_mutex_init(&mLatestScanResultsLock, NULL);
62-
6355 mNetworks = new WifiNetworkCollection();
6456 pthread_mutex_init(&mNetworksLock, NULL);
6557 }
@@ -92,14 +84,11 @@ int Supplicant::start() {
9284 return -1;
9385 }
9486
95- mPropMngr->registerProperty("wifi.supplicant.state", this);
9687 return 0;
9788 }
9889
9990 int Supplicant::stop() {
10091
101- mPropMngr->unregisterProperty("wifi.supplicant.state");
102-
10392 if (mListener->stopListener()) {
10493 LOGW("Unable to stop supplicant listener (%s)", strerror(errno));
10594 return -1;
@@ -125,6 +114,30 @@ bool Supplicant::isStarted() {
125114 return mServiceManager->isRunning(SUPPLICANT_SERVICE_NAME);
126115 }
127116
117+SupplicantStatus *Supplicant::getStatus() {
118+ char *reply;
119+ size_t len = 4096;
120+
121+ if (!(reply = (char *) malloc(len))) {
122+ errno = ENOMEM;
123+ return NULL;
124+ }
125+
126+ if (sendCommand("STATUS", reply, &len)) {
127+ free(reply);
128+ return NULL;
129+ }
130+
131+ SupplicantStatus *ss = SupplicantStatus::createStatus(reply, len);
132+
133+ free (reply);
134+ return ss;
135+}
136+
137+/*
138+ * Retrieves the list of networks from Supplicant
139+ * and merge them into our current list
140+ */
128141 int Supplicant::refreshNetworkList() {
129142 char *reply;
130143 size_t len = 4096;
@@ -144,27 +157,59 @@ int Supplicant::refreshNetworkList() {
144157
145158 if (!strtok_r(reply, "\n", &linep_next)) {
146159 LOGW("Malformatted network list\n");
147- } else {
148- pthread_mutex_lock(&mNetworksLock);
149- if (!mNetworks->empty()) {
150- WifiNetworkCollection::iterator i;
151-
152- for (i = mNetworks->begin(); i !=mNetworks->end(); ++i)
153- delete *i;
154- mNetworks->clear();
155- }
160+ free(reply);
161+ errno = EIO;
162+ return -1;
163+ }
156164
157- while((linep = strtok_r(NULL, "\n", &linep_next))) {
158- WifiNetwork *wn = new WifiNetwork(mController, this, linep);
159- mNetworks->push_back(wn);
160- if (wn->refresh())
161- LOGW("Unable to refresh network id %d", wn->getNetworkId());
165+ pthread_mutex_lock(&mNetworksLock);
166+
167+ int num_added = 0;
168+ int num_refreshed = 0;
169+ int num_removed = 0;
170+ while((linep = strtok_r(NULL, "\n", &linep_next))) {
171+ // TODO: Move the decode into a static method so we
172+ // don't create new_wn when we don't have to.
173+ WifiNetwork *new_wn = new WifiNetwork(mController, this, linep);
174+ WifiNetwork *merge_wn;
175+
176+ if ((merge_wn = this->lookupNetwork_UNLOCKED(new_wn->getNetworkId()))) {
177+ num_refreshed++;
178+ if (merge_wn->refresh()) {
179+ LOGW("Error refreshing network %d (%s)",
180+ merge_wn->getNetworkId(), strerror(errno));
181+ }
182+ delete new_wn;
183+ } else {
184+ num_added++;
185+ new_wn->registerProperties();
186+ mNetworks->push_back(new_wn);
187+ if (new_wn->refresh()) {
188+ LOGW("Unable to refresh network id %d (%s)",
189+ new_wn->getNetworkId(), strerror(errno));
190+ }
162191 }
192+ }
163193
164- LOGD("Loaded %d networks\n", mNetworks->size());
165- pthread_mutex_unlock(&mNetworksLock);
194+ if (!mNetworks->empty()) {
195+ // TODO: Add support for detecting removed networks
196+ WifiNetworkCollection::iterator i;
197+
198+ for (i = mNetworks->begin(); i != mNetworks->end(); ++i) {
199+ if (0) {
200+ num_removed++;
201+ (*i)->unregisterProperties();
202+ delete (*i);
203+ i = mNetworks->erase(i);
204+ }
205+ }
166206 }
167207
208+
209+ LOGD("Networks added %d, refreshed %d, removed %d\n",
210+ num_added, num_refreshed, num_removed);
211+ pthread_mutex_unlock(&mNetworksLock);
212+
168213 free(reply);
169214 return 0;
170215 }
@@ -192,7 +237,7 @@ int Supplicant::connectToSupplicant() {
192237 return -1;
193238 }
194239
195- mListener = new SupplicantListener(this, mMonitor);
240+ mListener = new SupplicantListener(mHandlers, mMonitor);
196241
197242 if (mListener->startListener()) {
198243 LOGE("Error - unable to start supplicant listener");
@@ -245,165 +290,6 @@ int Supplicant::triggerScan(bool active) {
245290 return 0;
246291 }
247292
248-int Supplicant::set(const char *name, const char *value) {
249- const char *n = name + strlen("wifi.supplicant.");
250-
251- errno = -EROFS;
252- return -1;
253-}
254-
255-const char *Supplicant::get(const char *name, char *buffer, size_t max) {
256- const char *n = name + strlen("wifi.supplicant.");
257-
258- if (!strcasecmp(n, "state"))
259- return SupplicantState::toString(mState, buffer, max);
260- errno = ENOENT;
261- return NULL;
262-}
263-
264-int Supplicant::onConnectedEvent(SupplicantEvent *evt) {
265- LOGD("onConnectedEvent(%s)", evt->getEvent());
266- return 0;
267-}
268-
269-int Supplicant::onDisconnectedEvent(SupplicantEvent *evt) {
270- LOGD("onDisconnectedEvent(%s)", evt->getEvent());
271- return 0;
272-}
273-
274-int Supplicant::onTerminatingEvent(SupplicantEvent *evt) {
275- LOGD("onTerminatingEvent(%s)", evt->getEvent());
276- return 0;
277-}
278-
279-int Supplicant::onPasswordChangedEvent(SupplicantEvent *evt) {
280- LOGD("onPasswordChangedEvent(%s)", evt->getEvent());
281- return 0;
282-}
283-
284-int Supplicant::onEapNotificationEvent(SupplicantEvent *evt) {
285- LOGD("onEapNotificationEvent(%s)", evt->getEvent());
286- return 0;
287-}
288-
289-int Supplicant::onEapStartedEvent(SupplicantEvent *evt) {
290- LOGD("onEapStartedEvent(%s)", evt->getEvent());
291- return 0;
292-}
293-
294-int Supplicant::onEapMethodEvent(SupplicantEvent *evt) {
295- LOGD("onEapMethodEvent(%s)", evt->getEvent());
296- return 0;
297-}
298-
299-int Supplicant::onEapSuccessEvent(SupplicantEvent *evt) {
300- LOGD("onEapSuccessEvent(%s)", evt->getEvent());
301- return 0;
302-}
303-
304-int Supplicant::onEapFailureEvent(SupplicantEvent *evt) {
305- LOGD("onEapFailureEvent(%s)", evt->getEvent());
306- return 0;
307-}
308-
309-int Supplicant::onScanResultsEvent(SupplicantEvent *evt) {
310- if (!strcmp(evt->getEvent(), "Ready")) {
311- char *reply;
312-
313- if (!(reply = (char *) malloc(4096))) {
314- errno = ENOMEM;
315- return -1;
316- }
317-
318- size_t len = 4096;
319-
320- if (sendCommand("SCAN_RESULTS", reply, &len)) {
321- LOGW("onScanResultsEvent(%s): Error getting scan results (%s)",
322- evt->getEvent(), strerror(errno));
323- free(reply);
324- return -1;
325- }
326-
327- pthread_mutex_lock(&mLatestScanResultsLock);
328- if (!mLatestScanResults->empty()) {
329- ScanResultCollection::iterator i;
330-
331- for (i = mLatestScanResults->begin();
332- i !=mLatestScanResults->end(); ++i) {
333- delete *i;
334- }
335- mLatestScanResults->clear();
336- }
337-
338- char *linep;
339- char *linep_next = NULL;
340-
341- if (!strtok_r(reply, "\n", &linep_next)) {
342- free(reply);
343- pthread_mutex_unlock(&mLatestScanResultsLock);
344- return 0;
345- }
346-
347- while((linep = strtok_r(NULL, "\n", &linep_next)))
348- mLatestScanResults->push_back(new ScanResult(linep));
349-
350- char tmp[128];
351- sprintf(tmp, "Scan results ready (%d)", mLatestScanResults->size());
352- NetworkManager::Instance()->getBroadcaster()->
353- sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false);
354- pthread_mutex_unlock(&mLatestScanResultsLock);
355- free(reply);
356- } else {
357- LOGW("Unknown SCAN_RESULTS event (%s)", evt->getEvent());
358- }
359- return 0;
360-}
361-
362-int Supplicant::onStateChangeEvent(SupplicantEvent *evt) {
363- char *bword, *last;
364- char *tmp = strdup(evt->getEvent());
365-
366- if (!(bword = strtok_r(tmp, " ", &last))) {
367- LOGE("Malformatted state update (%s)", evt->getEvent());
368- free(tmp);
369- return 0;
370- }
371-
372- if (!(bword = strtok_r(NULL, " ", &last))) {
373- LOGE("Malformatted state update (%s)", evt->getEvent());
374- free(tmp);
375- return 0;
376- }
377-
378- mState = atoi(&bword[strlen("state=")]);
379- LOGD("State changed to %d", mState);
380- free(tmp);
381- return 0;
382-}
383-
384-int Supplicant::onLinkSpeedEvent(SupplicantEvent *evt) {
385- LOGD("onLinkSpeedEvent(%s)", evt->getEvent());
386- return 0;
387-}
388-
389-int Supplicant::onDriverStateEvent(SupplicantEvent *evt) {
390- LOGD("onDriverStateEvent(%s)", evt->getEvent());
391- return 0;
392-}
393-
394-// XXX: Use a cursor + smartptr instead
395-ScanResultCollection *Supplicant::createLatestScanResults() {
396- ScanResultCollection *d = new ScanResultCollection();
397- ScanResultCollection::iterator i;
398-
399- pthread_mutex_lock(&mLatestScanResultsLock);
400- for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i)
401- d->push_back((*i)->clone());
402-
403- pthread_mutex_unlock(&mLatestScanResultsLock);
404- return d;
405-}
406-
407293 WifiNetwork *Supplicant::createNetwork() {
408294 char reply[255];
409295 size_t len = sizeof(reply) -1;
@@ -445,14 +331,18 @@ int Supplicant::removeNetwork(WifiNetwork *wn) {
445331
446332 WifiNetwork *Supplicant::lookupNetwork(int networkId) {
447333 pthread_mutex_lock(&mNetworksLock);
334+ WifiNetwork *wn = lookupNetwork_UNLOCKED(networkId);
335+ pthread_mutex_unlock(&mNetworksLock);
336+ return wn;
337+}
338+
339+WifiNetwork *Supplicant::lookupNetwork_UNLOCKED(int networkId) {
448340 WifiNetworkCollection::iterator it;
449341 for (it = mNetworks->begin(); it != mNetworks->end(); ++it) {
450342 if ((*it)->getNetworkId() == networkId) {
451- pthread_mutex_unlock(&mNetworksLock);
452343 return *it;
453344 }
454345 }
455- pthread_mutex_unlock(&mNetworksLock);
456346 errno = ENOENT;
457347 return NULL;
458348 }
@@ -528,6 +418,12 @@ int Supplicant::setNetworkVar(int networkId, const char *var, const char *val) {
528418 return -1;
529419 }
530420 free(tmp);
421+
422+ len = sizeof(reply) -1;
423+ if (sendCommand("SAVE_CONFIG", reply, &len)) {
424+ LOGE("Error saving config after %s = %s", var, val);
425+ return -1;
426+ }
531427 return 0;
532428 }
533429
--- a/nexus/Supplicant.h
+++ b/nexus/Supplicant.h
@@ -19,38 +19,31 @@
1919
2020 struct wpa_ctrl;
2121 class SupplicantListener;
22-class SupplicantEvent;
2322 class ServiceManager;
24-class PropertyManager;
2523 class Controller;
2624 class WifiController;
25+class SupplicantStatus;
2726
2827 #include <pthread.h>
2928
30-#include "ScanResult.h"
3129 #include "WifiNetwork.h"
32-#include "IPropertyProvider.h"
3330 #include "ISupplicantEventHandler.h"
3431
35-class Supplicant : public IPropertyProvider, public ISupplicantEventHandler {
32+class Supplicant {
3633 private:
3734 struct wpa_ctrl *mCtrl;
3835 struct wpa_ctrl *mMonitor;
3936 SupplicantListener *mListener;
40- int mState;
4137 ServiceManager *mServiceManager;
42- PropertyManager *mPropMngr;
4338 WifiController *mController;
4439 char *mInterfaceName;
4540
46- ScanResultCollection *mLatestScanResults;
47- pthread_mutex_t mLatestScanResultsLock;
48-
49- WifiNetworkCollection *mNetworks;
50- pthread_mutex_t mNetworksLock;
41+ WifiNetworkCollection *mNetworks;
42+ pthread_mutex_t mNetworksLock;
43+ ISupplicantEventHandler *mHandlers;
5144
5245 public:
53- Supplicant(WifiController *wc, PropertyManager *propmngr);
46+ Supplicant(WifiController *wc, ISupplicantEventHandler *handlers);
5447 virtual ~Supplicant();
5548
5649 int start();
@@ -58,7 +51,6 @@ public:
5851 bool isStarted();
5952
6053 int triggerScan(bool active);
61- ScanResultCollection *createLatestScanResults();
6254
6355 WifiNetwork *createNetwork();
6456 WifiNetwork *lookupNetwork(int networkId);
@@ -71,33 +63,18 @@ public:
7163 size_t max);
7264 int enableNetwork(int networkId, bool enabled);
7365
74- int getState() { return mState; }
66+ SupplicantStatus *getStatus();
67+
7568 Controller *getController() { return (Controller *) mController; }
7669 const char *getInterfaceName() { return mInterfaceName; }
7770
78- int set(const char *name, const char *value);
79- const char *get(const char *name, char *buffer, size_t max);
71+ int sendCommand(const char *cmd, char *reply, size_t *reply_len);
8072
8173 private:
8274 int connectToSupplicant();
83- int sendCommand(const char *cmd, char *reply, size_t *reply_len);
8475 int setupConfig();
8576 int retrieveInterfaceName();
86-
87- // ISupplicantEventHandler methods
88- virtual int onConnectedEvent(SupplicantEvent *evt);
89- virtual int onDisconnectedEvent(SupplicantEvent *evt);
90- virtual int onTerminatingEvent(SupplicantEvent *evt);
91- virtual int onPasswordChangedEvent(SupplicantEvent *evt);
92- virtual int onEapNotificationEvent(SupplicantEvent *evt);
93- virtual int onEapStartedEvent(SupplicantEvent *evt);
94- virtual int onEapMethodEvent(SupplicantEvent *evt);
95- virtual int onEapSuccessEvent(SupplicantEvent *evt);
96- virtual int onEapFailureEvent(SupplicantEvent *evt);
97- virtual int onScanResultsEvent(SupplicantEvent *evt);
98- virtual int onStateChangeEvent(SupplicantEvent *evt);
99- virtual int onLinkSpeedEvent(SupplicantEvent *evt);
100- virtual int onDriverStateEvent(SupplicantEvent *evt);
77+ WifiNetwork *lookupNetwork_UNLOCKED(int networkId);
10178 };
10279
10380 #endif
--- /dev/null
+++ b/nexus/SupplicantAssociatedEvent.cpp
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#include <stdlib.h>
18+
19+#define LOG_TAG "SupplicantAssociatedEvent"
20+#include <cutils/log.h>
21+
22+#include "SupplicantAssociatedEvent.h"
23+
24+SupplicantAssociatedEvent::SupplicantAssociatedEvent(int level, char *event,
25+ size_t len) :
26+ SupplicantEvent(SupplicantEvent::EVENT_ASSOCIATED,
27+ level) {
28+ char *p = event;
29+
30+ // "00:13:46:40:40:aa"
31+ mBssid = (char *) malloc(18);
32+ strncpy(mBssid, p, 17);
33+ mBssid[17] = '\0';
34+}
35+
36+SupplicantAssociatedEvent::~SupplicantAssociatedEvent() {
37+ if (mBssid)
38+ free(mBssid);
39+}
40+
--- /dev/null
+++ b/nexus/SupplicantAssociatedEvent.h
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _SupplicantAssociatedEvent_H
18+#define _SupplicantAssociatedEvent_H
19+
20+#include "SupplicantEvent.h"
21+
22+class SupplicantAssociatedEvent : public SupplicantEvent {
23+ char *mBssid;
24+ char *mSsid;
25+ int mFreq;
26+
27+public:
28+ SupplicantAssociatedEvent(int level, char *event, size_t len);
29+ virtual ~SupplicantAssociatedEvent();
30+
31+ const char *getBssid() { return mBssid; }
32+};
33+
34+#endif
--- /dev/null
+++ b/nexus/SupplicantAssociatingEvent.cpp
@@ -0,0 +1,99 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#include <stdlib.h>
18+
19+#define LOG_TAG "SupplicantAssociatingEvent"
20+#include <cutils/log.h>
21+
22+#include "SupplicantAssociatingEvent.h"
23+
24+SupplicantAssociatingEvent::SupplicantAssociatingEvent(int level, char *event,
25+ size_t len) :
26+ SupplicantEvent(SupplicantEvent::EVENT_ASSOCIATING,
27+ level) {
28+ char *p = event;
29+
30+ mBssid = NULL;
31+ mSsid = NULL;
32+
33+ // SSID 'default'
34+ // OR
35+ // "00:13:46:40:40:aa (SSID='default' freq=2437 MHz)"
36+
37+ if (strncmp(event, "SSID", 4)) {
38+ mBssid = (char *) malloc(18);
39+ strncpy(mBssid, p, 17);
40+ mBssid[17] = '\0';
41+ p += 25;
42+
43+ // "00:13:46:40:40:aa (SSID='default' freq=2437 MHz)"
44+ // ^
45+ // p
46+ char *q = index(p, '\'');
47+ if (!q) {
48+ LOGE("Unable to decode SSID (p = {%s})\n", p);
49+ return;
50+ }
51+ mSsid = (char *) malloc((q - p) +1);
52+ strncpy(mSsid, p, q-p);
53+ mSsid[q-p] = '\0';
54+
55+ p = q + 7;
56+
57+ // "00:13:46:40:40:aa (SSID='default' freq=2437 MHz)"
58+ // ^
59+ // p
60+ if (!(q = index(p, ' '))) {
61+ LOGE("Unable to decode frequency\n");
62+ return;
63+ }
64+ *q = '\0';
65+ mFreq = atoi(p);
66+ } else {
67+ p+= 6;
68+
69+ // SSID 'default'
70+ // ^
71+ // p
72+
73+ char *q = index(p, '\'');
74+ if (!q) {
75+ LOGE("Unable to decode SSID (p = {%s})\n", p);
76+ return;
77+ }
78+ mSsid = (char *) malloc((q - p) +1);
79+ strncpy(mSsid, p, q-p);
80+ mSsid[q-p] = '\0';
81+ }
82+}
83+
84+SupplicantAssociatingEvent::SupplicantAssociatingEvent(const char *bssid,
85+ const char *ssid,
86+ int freq) :
87+ SupplicantEvent(SupplicantEvent::EVENT_ASSOCIATING, -1) {
88+ mBssid = strdup(bssid);
89+ mSsid= strdup(ssid);
90+ mFreq = freq;
91+}
92+
93+SupplicantAssociatingEvent::~SupplicantAssociatingEvent() {
94+ if (mBssid)
95+ free(mBssid);
96+ if (mSsid)
97+ free(mSsid);
98+}
99+
--- /dev/null
+++ b/nexus/SupplicantAssociatingEvent.h
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _SupplicantAssociatingEvent_H
18+#define _SupplicantAssociatingEvent_H
19+
20+#include "SupplicantEvent.h"
21+
22+class SupplicantAssociatingEvent : public SupplicantEvent {
23+ char *mBssid;
24+ char *mSsid;
25+ int mFreq;
26+
27+public:
28+ SupplicantAssociatingEvent(int level, char *event, size_t len);
29+ SupplicantAssociatingEvent(const char *bssid, const char *ssid, int freq);
30+ virtual ~SupplicantAssociatingEvent();
31+
32+ const char *getBssid() { return mBssid; }
33+ const char *getSsid() { return mSsid; }
34+ int getFreq() { return mFreq;}
35+};
36+
37+#endif
--- /dev/null
+++ b/nexus/SupplicantConnectedEvent.cpp
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#define LOG_TAG "SupplicantConnectedEvent"
18+#include <cutils/log.h>
19+
20+#include "SupplicantConnectedEvent.h"
21+
22+SupplicantConnectedEvent::SupplicantConnectedEvent(int level, char *event,
23+ size_t len) :
24+ SupplicantEvent(SupplicantEvent::EVENT_CONNECTED,
25+ level) {
26+ char *p;
27+
28+ // "- Connection to 00:13:46:40:40:aa completed (auth) [id=1 id_str=], 89"
29+
30+ if ((p = index(event + 2, ' ')) && (++p = index(p, ' '))) {
31+ mBssid = (char *) malloc(18);
32+ strncpy(mBssid, ++p, 17);
33+ mBssid[17] = '\0';
34+
35+ // "- Connection to 00:13:46:40:40:aa completed (auth) [id=1 id_str=], 89"
36+ // ^
37+ // p
38+
39+ if ((p = index(p, ' ')) && ((++p = index(p, ' ')))) {
40+ if (!strncmp(++p, "(auth)", 6))
41+ mReassociated = false;
42+ else
43+ mReassociated = true;
44+ } else
45+ LOGE("Unable to decode re-assocation");
46+ } else
47+ LOGE("Unable to decode event");
48+}
49+
50+SupplicantConnectedEvent::SupplicantConnectedEvent(const char *bssid,
51+ bool reassocated) :
52+ SupplicantEvent(SupplicantEvent::EVENT_CONNECTED, -1) {
53+ mBssid = strdup(bssid);
54+ mReassociated = reassocated;
55+}
56+
57+SupplicantConnectedEvent::~SupplicantConnectedEvent() {
58+ if (mBssid)
59+ free(mBssid);
60+}
61+
--- /dev/null
+++ b/nexus/SupplicantConnectedEvent.h
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _SupplicantConnectedEvent_H
18+#define _SupplicantConnectedEvent_H
19+
20+#include "SupplicantEvent.h"
21+
22+class SupplicantConnectedEvent : public SupplicantEvent {
23+private:
24+ char *mBssid;
25+ bool mReassociated;
26+
27+public:
28+ SupplicantConnectedEvent(int level, char *event, size_t len);
29+ SupplicantConnectedEvent(const char *bssid, bool reassicated);
30+ virtual ~SupplicantConnectedEvent();
31+
32+ const char *getBssid() { return mBssid; }
33+ bool getReassociated() { return mReassociated; }
34+};
35+
36+#endif
--- /dev/null
+++ b/nexus/SupplicantConnectionTimeoutEvent.cpp
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#define LOG_TAG "SupplicantConnectionTimeoutEvent"
18+#include <cutils/log.h>
19+
20+#include "SupplicantConnectionTimeoutEvent.h"
21+
22+SupplicantConnectionTimeoutEvent::SupplicantConnectionTimeoutEvent(int level, char *event,
23+ size_t len) :
24+ SupplicantEvent(SupplicantEvent::EVENT_CONNECTIONTIMEOUT,
25+ level) {
26+ // 00:13:46:40:40:aa timed out.'
27+ mBssid = (char *) malloc(18);
28+ strncpy(mBssid, event, 17);
29+ mBssid[17] = '\0';
30+}
31+
32+SupplicantConnectionTimeoutEvent::~SupplicantConnectionTimeoutEvent() {
33+ if (mBssid)
34+ free(mBssid);
35+}
36+
--- /dev/null
+++ b/nexus/SupplicantConnectionTimeoutEvent.h
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _SupplicantConnectionTimeoutEvent_H
18+#define _SupplicantConnectionTimeoutEvent_H
19+
20+#include "SupplicantEvent.h"
21+
22+class SupplicantConnectionTimeoutEvent : public SupplicantEvent {
23+private:
24+ char *mBssid;
25+ bool mReassociated;
26+
27+public:
28+ SupplicantConnectionTimeoutEvent(int level, char *event, size_t len);
29+ virtual ~SupplicantConnectionTimeoutEvent();
30+
31+ const char *getBssid() { return mBssid; }
32+};
33+
34+#endif
--- /dev/null
+++ b/nexus/SupplicantDisconnectedEvent.cpp
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#define LOG_TAG "SupplicantDisconnectedEvent"
18+#include <cutils/log.h>
19+
20+#include "SupplicantDisconnectedEvent.h"
21+
22+SupplicantDisconnectedEvent::SupplicantDisconnectedEvent(int level, char *event,
23+ size_t len) :
24+ SupplicantEvent(SupplicantEvent::EVENT_DISCONNECTED,
25+ level) {
26+}
27+
28+SupplicantDisconnectedEvent::SupplicantDisconnectedEvent() :
29+ SupplicantEvent(SupplicantEvent::EVENT_DISCONNECTED, -1) {
30+}
31+
32+SupplicantDisconnectedEvent::~SupplicantDisconnectedEvent() {
33+}
--- /dev/null
+++ b/nexus/SupplicantDisconnectedEvent.h
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _SupplicantDisconnectedEvent_H
18+#define _SupplicantDisconnectedEvent_H
19+
20+#include "SupplicantEvent.h"
21+
22+class SupplicantDisconnectedEvent : public SupplicantEvent {
23+
24+public:
25+ SupplicantDisconnectedEvent(int level, char *event, size_t len);
26+ SupplicantDisconnectedEvent();
27+ virtual ~SupplicantDisconnectedEvent();
28+};
29+
30+#endif
--- a/nexus/SupplicantEvent.cpp
+++ b/nexus/SupplicantEvent.cpp
@@ -23,74 +23,7 @@
2323
2424 #include "libwpa_client/wpa_ctrl.h"
2525
26-SupplicantEvent::SupplicantEvent(char *event, size_t len) {
27-
28- if (event[0] == '<') {
29- char *match = strchr(event, '>');
30- if (match) {
31- char tmp[16];
32-
33- strncpy(tmp, &event[1], (match - event));
34- mLevel = atoi(tmp);
35- event += (match - event) + 1;
36- } else
37- LOGW("Unclosed level brace in event");
38- } else
39- LOGW("No level specified in event");
40-
41- /*
42- * <N>CTRL-EVENT-XXX
43- * ^
44- * +---- event
45- */
46-
47- if (!strncmp(event, WPA_EVENT_CONNECTED, strlen(WPA_EVENT_CONNECTED)))
48- mType = SupplicantEvent::EVENT_CONNECTED;
49- else if (!strncmp(event, WPA_EVENT_DISCONNECTED, strlen(WPA_EVENT_DISCONNECTED)))
50- mType = SupplicantEvent::EVENT_DISCONNECTED;
51- else if (!strncmp(event, WPA_EVENT_TERMINATING, strlen(WPA_EVENT_TERMINATING)))
52- mType = SupplicantEvent::EVENT_TERMINATING;
53- else if (!strncmp(event, WPA_EVENT_PASSWORD_CHANGED, strlen(WPA_EVENT_PASSWORD_CHANGED)))
54- mType = SupplicantEvent::EVENT_PASSWORD_CHANGED;
55- else if (!strncmp(event, WPA_EVENT_EAP_NOTIFICATION, strlen(WPA_EVENT_EAP_NOTIFICATION)))
56- mType = SupplicantEvent::EVENT_EAP_NOTIFICATION;
57- else if (!strncmp(event, WPA_EVENT_EAP_STARTED, strlen(WPA_EVENT_EAP_STARTED)))
58- mType = SupplicantEvent::EVENT_EAP_STARTED;
59- else if (!strncmp(event, WPA_EVENT_EAP_METHOD, strlen(WPA_EVENT_EAP_METHOD)))
60- mType = SupplicantEvent::EVENT_EAP_METHOD;
61- else if (!strncmp(event, WPA_EVENT_EAP_SUCCESS, strlen(WPA_EVENT_EAP_SUCCESS)))
62- mType = SupplicantEvent::EVENT_EAP_SUCCESS;
63- else if (!strncmp(event, WPA_EVENT_EAP_FAILURE, strlen(WPA_EVENT_EAP_FAILURE)))
64- mType = SupplicantEvent::EVENT_EAP_FAILURE;
65- else if (!strncmp(event, WPA_EVENT_SCAN_RESULTS, strlen(WPA_EVENT_SCAN_RESULTS)))
66- mType = SupplicantEvent::EVENT_SCAN_RESULTS;
67- else if (!strncmp(event, WPA_EVENT_STATE_CHANGE, strlen(WPA_EVENT_STATE_CHANGE)))
68- mType = SupplicantEvent::EVENT_STATE_CHANGE;
69- else if (!strncmp(event, WPA_EVENT_LINK_SPEED, strlen(WPA_EVENT_LINK_SPEED)))
70- mType = SupplicantEvent::EVENT_LINK_SPEED;
71- else if (!strncmp(event, WPA_EVENT_DRIVER_STATE, strlen(WPA_EVENT_DRIVER_STATE)))
72- mType = SupplicantEvent::EVENT_DRIVER_STATE;
73- else {
74- LOGW("Unknown supplicant event '%s'", event);
75- mType = SupplicantEvent::EVENT_UNKNOWN;
76- }
77-
78- for (event; *event != ' '; event++);
79- event++;
80-
81- /*
82- * <N>CTRL-EVENT-XXX YYYY
83- * ^
84- * +---- event
85- */
86-
87- for (event; *event == ' '; event++);
88-
89- mEvent = strdup(event);
90- mLen = len;
91-}
92-
93-SupplicantEvent::~SupplicantEvent() {
94- if (mEvent)
95- free(mEvent);
26+SupplicantEvent::SupplicantEvent(int type, int level) {
27+ mType = type;
28+ mLevel = level;
9629 }
--- a/nexus/SupplicantEvent.h
+++ b/nexus/SupplicantEvent.h
@@ -22,33 +22,32 @@
2222 class SupplicantEvent {
2323 private:
2424 int mType;
25- char *mEvent;
26- size_t mLen;
2725 int mLevel;
2826
2927 public:
30- static const int EVENT_UNKNOWN = 0;
31- static const int EVENT_CONNECTED = 1;
32- static const int EVENT_DISCONNECTED = 2;
33- static const int EVENT_TERMINATING = 3;
34- static const int EVENT_PASSWORD_CHANGED = 4;
35- static const int EVENT_EAP_NOTIFICATION = 5;
36- static const int EVENT_EAP_STARTED = 6;
37- static const int EVENT_EAP_METHOD = 7;
38- static const int EVENT_EAP_SUCCESS = 8;
39- static const int EVENT_EAP_FAILURE = 9;
40- static const int EVENT_SCAN_RESULTS = 10;
41- static const int EVENT_STATE_CHANGE = 11;
42- static const int EVENT_LINK_SPEED = 12;
43- static const int EVENT_DRIVER_STATE = 13;
28+ static const int EVENT_UNKNOWN = 0;
29+ static const int EVENT_CONNECTED = 1;
30+ static const int EVENT_DISCONNECTED = 2;
31+ static const int EVENT_TERMINATING = 3;
32+ static const int EVENT_PASSWORD_CHANGED = 4;
33+ static const int EVENT_EAP_NOTIFICATION = 5;
34+ static const int EVENT_EAP_STARTED = 6;
35+ static const int EVENT_EAP_METHOD = 7;
36+ static const int EVENT_EAP_SUCCESS = 8;
37+ static const int EVENT_EAP_FAILURE = 9;
38+ static const int EVENT_SCAN_RESULTS = 10;
39+ static const int EVENT_STATE_CHANGE = 11;
40+ static const int EVENT_LINK_SPEED = 12;
41+ static const int EVENT_DRIVER_STATE = 13;
42+ static const int EVENT_ASSOCIATING = 14;
43+ static const int EVENT_ASSOCIATED = 15;
44+ static const int EVENT_CONNECTIONTIMEOUT = 16;
4445
4546 public:
46- SupplicantEvent(char *event, size_t len);
47- virtual ~SupplicantEvent();
47+ SupplicantEvent(int type, int level);
48+ virtual ~SupplicantEvent() {}
4849
4950 int getType() { return mType; }
50- const char *getEvent() { return mEvent; }
51- int getLen() { return mLen; }
5251 int getLevel() { return mLevel; }
5352 };
5453
--- /dev/null
+++ b/nexus/SupplicantEventFactory.cpp
@@ -0,0 +1,119 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#include <stdlib.h>
18+
19+#define LOG_TAG "SupplicantEventFactory"
20+#include <cutils/log.h>
21+
22+#include "SupplicantEvent.h"
23+#include "SupplicantEventFactory.h"
24+#include "SupplicantAssociatingEvent.h"
25+#include "SupplicantAssociatedEvent.h"
26+#include "SupplicantConnectedEvent.h"
27+#include "SupplicantStateChangeEvent.h"
28+#include "SupplicantScanResultsEvent.h"
29+#include "SupplicantConnectionTimeoutEvent.h"
30+#include "SupplicantDisconnectedEvent.h"
31+#if 0
32+#include "SupplicantTerminatingEvent.h"
33+#include "SupplicantPasswordChangedEvent.h"
34+#include "SupplicantEapNotificationEvent.h"
35+#include "SupplicantEapStartedEvent.h"
36+#include "SupplicantEapMethodEvent.h"
37+#include "SupplicantEapSuccessEvent.h"
38+#include "SupplicantEapFailureEvent.h"
39+#include "SupplicantLinkSpeedEvent.h"
40+#include "SupplicantDriverStateEvent.h"
41+#endif
42+
43+#include "libwpa_client/wpa_ctrl.h"
44+
45+SupplicantEventFactory::SupplicantEventFactory() {
46+}
47+
48+SupplicantEvent *SupplicantEventFactory::createEvent(char *event, size_t len) {
49+ int level = 0;
50+
51+ if (event[0] == '<') {
52+ char *match = strchr(event, '>');
53+ if (match) {
54+ char tmp[16];
55+
56+ strncpy(tmp, &event[1], (match - event));
57+ level = atoi(tmp);
58+ event += (match - event) + 1;
59+ } else
60+ LOGW("Unclosed level brace in event");
61+ } else
62+ LOGW("No level specified in event");
63+
64+ /*
65+ * <N>CTRL-EVENT-XXX
66+ * ^
67+ * +---- event
68+ */
69+
70+ if (!strncmp(event, "Authentication with ", 20)) {
71+ if (!strcmp(event + strlen(event) - strlen(" timed out."),
72+ " timed out.")) {
73+ return new SupplicantConnectionTimeoutEvent(level,
74+ event + 20,
75+ len);
76+ } else
77+ return NULL;
78+
79+ } else if (!strncmp(event, "Associated with ", 16))
80+ return new SupplicantAssociatedEvent(level, event + 16, len);
81+ else if (!strncmp(event, "Trying to associate with ", 25))
82+ return new SupplicantAssociatingEvent(level, event + 25, len);
83+ else if (!strncmp(event, WPA_EVENT_CONNECTED, strlen(WPA_EVENT_CONNECTED))) {
84+ return new SupplicantConnectedEvent(level,
85+ event + strlen(WPA_EVENT_CONNECTED),
86+ len);
87+ } else if (!strncmp(event, WPA_EVENT_SCAN_RESULTS, strlen(WPA_EVENT_SCAN_RESULTS))) {
88+ return new SupplicantScanResultsEvent(level,
89+ event + strlen(WPA_EVENT_SCAN_RESULTS),
90+ len);
91+ } else if (!strncmp(event, WPA_EVENT_STATE_CHANGE, strlen(WPA_EVENT_STATE_CHANGE))) {
92+ return new SupplicantStateChangeEvent(level,
93+ event + strlen(WPA_EVENT_STATE_CHANGE),
94+ len);
95+ }
96+ else if (!strncmp(event, WPA_EVENT_DISCONNECTED, strlen(WPA_EVENT_DISCONNECTED)))
97+ return new SupplicantDisconnectedEvent(level, event, len);
98+#if 0
99+ else if (!strncmp(event, WPA_EVENT_TERMINATING, strlen(WPA_EVENT_TERMINATING)))
100+ return new SupplicantTerminatingEvent(event, len);
101+ else if (!strncmp(event, WPA_EVENT_PASSWORD_CHANGED, strlen(WPA_EVENT_PASSWORD_CHANGED)))
102+ return new SupplicantPasswordChangedEvent(event, len);
103+ else if (!strncmp(event, WPA_EVENT_EAP_NOTIFICATION, strlen(WPA_EVENT_EAP_NOTIFICATION)))
104+ return new SupplicantEapNotificationEvent(event, len);
105+ else if (!strncmp(event, WPA_EVENT_EAP_STARTED, strlen(WPA_EVENT_EAP_STARTED)))
106+ return new SupplicantEapStartedEvent(event, len);
107+ else if (!strncmp(event, WPA_EVENT_EAP_METHOD, strlen(WPA_EVENT_EAP_METHOD)))
108+ return new SupplicantEapMethodEvent(event, len);
109+ else if (!strncmp(event, WPA_EVENT_EAP_SUCCESS, strlen(WPA_EVENT_EAP_SUCCESS)))
110+ return new SupplicantEapSuccessEvent(event, len);
111+ else if (!strncmp(event, WPA_EVENT_EAP_FAILURE, strlen(WPA_EVENT_EAP_FAILURE)))
112+ return new SupplicantEapFailureEvent(event, len);
113+ else if (!strncmp(event, WPA_EVENT_LINK_SPEED, strlen(WPA_EVENT_LINK_SPEED)))
114+ return new SupplicantLinkSpeedEvent(event, len);
115+ else if (!strncmp(event, WPA_EVENT_DRIVER_STATE, strlen(WPA_EVENT_DRIVER_STATE)))
116+ return new SupplicantDriverStateEvent(event, len);
117+#endif
118+ return NULL;
119+}
--- /dev/null
+++ b/nexus/SupplicantEventFactory.h
@@ -0,0 +1,31 @@
1+
2+/*
3+ * Copyright (C) 2008 The Android Open Source Project
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ */
17+
18+#ifndef _SupplicantEventFactory_H
19+#define _SupplicantEventFactory_H
20+
21+class SupplicantEvent;
22+
23+class SupplicantEventFactory {
24+public:
25+ SupplicantEventFactory();
26+ virtual ~SupplicantEventFactory() {}
27+
28+ SupplicantEvent *createEvent(char *event, size_t len);
29+};
30+
31+#endif
--- a/nexus/SupplicantListener.cpp
+++ b/nexus/SupplicantListener.cpp
@@ -24,14 +24,21 @@
2424 #include "libwpa_client/wpa_ctrl.h"
2525
2626 #include "SupplicantListener.h"
27-#include "SupplicantEvent.h"
2827 #include "ISupplicantEventHandler.h"
28+#include "SupplicantEventFactory.h"
29+#include "SupplicantEvent.h"
30+#include "SupplicantAssociatingEvent.h"
31+#include "SupplicantAssociatedEvent.h"
32+#include "SupplicantConnectedEvent.h"
33+#include "SupplicantScanResultsEvent.h"
34+#include "SupplicantStateChangeEvent.h"
2935
3036 SupplicantListener::SupplicantListener(ISupplicantEventHandler *handlers,
3137 struct wpa_ctrl *monitor) :
3238 SocketListener(wpa_ctrl_get_fd(monitor), false) {
3339 mHandlers = handlers;
3440 mMonitor = monitor;
41+ mFactory = new SupplicantEventFactory();
3542 }
3643
3744 bool SupplicantListener::onDataAvailable(SocketClient *cli) {
@@ -53,44 +60,50 @@ bool SupplicantListener::onDataAvailable(SocketClient *cli) {
5360 return false;
5461 }
5562
56- SupplicantEvent *evt = new SupplicantEvent(buf, nread);
63+ SupplicantEvent *evt = mFactory->createEvent(buf, nread);
64+
65+ if (!evt) {
66+ LOGW("Dropping unknown supplicant event '%s'", buf);
67+ return true;
68+ }
5769
58- // XXX: Make this a factory
59- // XXX: Instead of calling Supplicant directly
60- // extract an Interface and use that instead
61- if (evt->getType() == SupplicantEvent::EVENT_CONNECTED)
62- rc = mHandlers->onConnectedEvent(evt);
70+ // Call the appropriate handler
71+ if (evt->getType() == SupplicantEvent::EVENT_ASSOCIATING)
72+ mHandlers->onAssociatingEvent((SupplicantAssociatingEvent *) evt);
73+ else if (evt->getType() == SupplicantEvent::EVENT_ASSOCIATED)
74+ mHandlers->onAssociatedEvent((SupplicantAssociatedEvent *) evt);
75+ else if (evt->getType() == SupplicantEvent::EVENT_CONNECTED)
76+ mHandlers->onConnectedEvent((SupplicantConnectedEvent *) evt);
77+ else if (evt->getType() == SupplicantEvent::EVENT_SCAN_RESULTS)
78+ mHandlers->onScanResultsEvent((SupplicantScanResultsEvent *) evt);
79+ else if (evt->getType() == SupplicantEvent::EVENT_STATE_CHANGE)
80+ mHandlers->onStateChangeEvent((SupplicantStateChangeEvent *) evt);
81+ else if (evt->getType() == SupplicantEvent::EVENT_CONNECTIONTIMEOUT)
82+ mHandlers->onConnectionTimeoutEvent((SupplicantConnectionTimeoutEvent *) evt);
6383 else if (evt->getType() == SupplicantEvent::EVENT_DISCONNECTED)
64- rc = mHandlers->onDisconnectedEvent(evt);
84+ mHandlers->onDisconnectedEvent((SupplicantDisconnectedEvent *) evt);
85+ else
86+ LOGW("Whoops - no handler available for event '%s'\n", buf);
87+#if 0
6588 else if (evt->getType() == SupplicantEvent::EVENT_TERMINATING)
66- rc = mHandlers->onTerminatingEvent(evt);
89+ mHandlers->onTerminatingEvent(evt);
6790 else if (evt->getType() == SupplicantEvent::EVENT_PASSWORD_CHANGED)
68- rc = mHandlers->onPasswordChangedEvent(evt);
91+ mHandlers->onPasswordChangedEvent(evt);
6992 else if (evt->getType() == SupplicantEvent::EVENT_EAP_NOTIFICATION)
70- rc = mHandlers->onEapNotificationEvent(evt);
93+ mHandlers->onEapNotificationEvent(evt);
7194 else if (evt->getType() == SupplicantEvent::EVENT_EAP_STARTED)
72- rc = mHandlers->onEapStartedEvent(evt);
95+ mHandlers->onEapStartedEvent(evt);
7396 else if (evt->getType() == SupplicantEvent::EVENT_EAP_SUCCESS)
74- rc = mHandlers->onEapSuccessEvent(evt);
97+ mHandlers->onEapSuccessEvent(evt);
7598 else if (evt->getType() == SupplicantEvent::EVENT_EAP_FAILURE)
76- rc = mHandlers->onEapFailureEvent(evt);
77- else if (evt->getType() == SupplicantEvent::EVENT_SCAN_RESULTS)
78- rc = mHandlers->onScanResultsEvent(evt);
79- else if (evt->getType() == SupplicantEvent::EVENT_STATE_CHANGE)
80- rc = mHandlers->onStateChangeEvent(evt);
99+ mHandlers->onEapFailureEvent(evt);
81100 else if (evt->getType() == SupplicantEvent::EVENT_LINK_SPEED)
82- rc = mHandlers->onLinkSpeedEvent(evt);
101+ mHandlers->onLinkSpeedEvent(evt);
83102 else if (evt->getType() == SupplicantEvent::EVENT_DRIVER_STATE)
84- rc = mHandlers->onDriverStateEvent(evt);
85- else {
86- LOGW("Ignoring unknown event");
87- }
103+ mHandlers->onDriverStateEvent(evt);
104+#endif
88105
89106 delete evt;
90107
91- if (rc) {
92- LOGW("Handler %d (%s) error: %s", evt->getType(), evt->getEvent(), strerror(errno));
93- return false;
94- }
95108 return true;
96109 }
--- a/nexus/SupplicantListener.h
+++ b/nexus/SupplicantListener.h
@@ -23,12 +23,13 @@ struct wpa_ctrl;
2323 class Supplicant;
2424 class SocketClient;
2525 class ISupplicantEventHandler;
26+class SupplicantEventFactory;
2627
2728 class SupplicantListener: public SocketListener {
28-private:
2929 struct wpa_ctrl *mMonitor;
3030 ISupplicantEventHandler *mHandlers;
31-
31+ SupplicantEventFactory *mFactory;
32+
3233 public:
3334 SupplicantListener(ISupplicantEventHandler *handlers,
3435 struct wpa_ctrl *monitor);
--- /dev/null
+++ b/nexus/SupplicantScanResultsEvent.cpp
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#define LOG_TAG "SupplicantScanResultsEvent"
18+#include <cutils/log.h>
19+
20+#include "SupplicantScanResultsEvent.h"
21+
22+SupplicantScanResultsEvent::SupplicantScanResultsEvent(int level, char *event,
23+ size_t len) :
24+ SupplicantEvent(SupplicantEvent::EVENT_SCAN_RESULTS,
25+ level) {
26+}
27+
28+SupplicantScanResultsEvent::SupplicantScanResultsEvent() :
29+ SupplicantEvent(SupplicantEvent::EVENT_SCAN_RESULTS, -1) {
30+}
31+
32+SupplicantScanResultsEvent::~SupplicantScanResultsEvent() {
33+}
34+
--- /dev/null
+++ b/nexus/SupplicantScanResultsEvent.h
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _SupplicantScanResultsEvent_H
18+#define _SupplicantScanResultsEvent_H
19+
20+#include "SupplicantEvent.h"
21+
22+class SupplicantScanResultsEvent : public SupplicantEvent {
23+
24+public:
25+ SupplicantScanResultsEvent(int level, char *event, size_t len);
26+ SupplicantScanResultsEvent();
27+ virtual ~SupplicantScanResultsEvent();
28+};
29+
30+#endif
--- /dev/null
+++ b/nexus/SupplicantStateChangeEvent.cpp
@@ -0,0 +1,45 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#include <stdlib.h>
18+
19+#define LOG_TAG "SupplicantStateChangeEvent"
20+#include <cutils/log.h>
21+
22+#include "SupplicantStateChangeEvent.h"
23+
24+SupplicantStateChangeEvent::SupplicantStateChangeEvent(int level, char *event,
25+ size_t len) :
26+ SupplicantEvent(SupplicantEvent::EVENT_STATE_CHANGE,
27+ level) {
28+ // XXX: move this stuff into a static creation method
29+ char *p = index(event, ' ');
30+ if (!p) {
31+ LOGW("Bad event '%s'\n", event);
32+ return;
33+ }
34+
35+ mState = atoi(p + strlen("state=") + 1);
36+}
37+
38+SupplicantStateChangeEvent::SupplicantStateChangeEvent(int state) :
39+ SupplicantEvent(SupplicantEvent::EVENT_STATE_CHANGE, -1) {
40+ mState = state;
41+}
42+
43+SupplicantStateChangeEvent::~SupplicantStateChangeEvent() {
44+}
45+
--- /dev/null
+++ b/nexus/SupplicantStateChangeEvent.h
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _SupplicantStateChangeEvent_H
18+#define _SupplicantStateChangeEvent_H
19+
20+#include "SupplicantEvent.h"
21+
22+class SupplicantStateChangeEvent : public SupplicantEvent {
23+private:
24+ int mState;
25+
26+public:
27+ SupplicantStateChangeEvent(int level, char *event, size_t len);
28+ SupplicantStateChangeEvent(int state);
29+ virtual ~SupplicantStateChangeEvent();
30+
31+ int getState() { return mState; }
32+};
33+
34+#endif
--- /dev/null
+++ b/nexus/SupplicantStatus.cpp
@@ -0,0 +1,72 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#include <stdlib.h>
18+#include <string.h>
19+
20+#define LOG_TAG "SupplicantState"
21+#include <cutils/log.h>
22+
23+#include "SupplicantStatus.h"
24+#include "SupplicantState.h"
25+
26+SupplicantStatus::SupplicantStatus() {
27+ mWpaState = SupplicantState::UNKNOWN;
28+ mId = -1;
29+ mBssid = NULL;
30+ mSsid = NULL;
31+}
32+
33+SupplicantStatus::SupplicantStatus(int state, int id, char *bssid, char *ssid) :
34+ mWpaState(state), mId(id), mBssid(bssid), mSsid(ssid) {
35+
36+LOGD("state %d, id %d, bssid %p, ssid %p\n", mWpaState, mId, mBssid, mSsid);
37+}
38+
39+SupplicantStatus::~SupplicantStatus() {
40+ if (mBssid)
41+ free(mBssid);
42+ if (mSsid)
43+ free(mSsid);
44+}
45+
46+SupplicantStatus *SupplicantStatus::createStatus(char *data, int len) {
47+ char *bssid = NULL;
48+ char *ssid = NULL;
49+ int id = -1;
50+ int state = SupplicantState::UNKNOWN;
51+
52+ char *next = data;
53+ char *line;
54+ while((line = strsep(&next, "\n"))) {
55+ char *token = strsep(&next, "=");
56+ char *value = strsep(&next, "=");
57+
58+ if (!strcmp(token, "bssid"))
59+ bssid = strdup(value);
60+ else if (!strcmp(token, "ssid"))
61+ ssid = strdup(value);
62+ else if (!strcmp(token, "id"))
63+ id = atoi(value);
64+ else if (!strcmp(token, "wpa_state"))
65+ state = atoi(value);
66+ else
67+ LOGD("Ignoring unsupported status token '%s'", token);
68+ }
69+
70+ return new SupplicantStatus(state, id, bssid, ssid);
71+
72+}
--- /dev/null
+++ b/nexus/SupplicantStatus.h
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright (C) 2008 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#ifndef _SupplicantStatus_H
18+#define _SupplicantStatus_H
19+
20+class SupplicantStatus {
21+private:
22+ int mWpaState;
23+ int mId;
24+ char *mBssid;
25+ char *mSsid;
26+
27+private:
28+ SupplicantStatus();
29+ SupplicantStatus(int state, int id, char *bssid, char *ssid);
30+
31+public:
32+ virtual ~SupplicantStatus();
33+ static SupplicantStatus *createStatus(char *data, int len);
34+
35+ int getWpaState() { return mWpaState; }
36+ int getId() { return mId; }
37+ const char *getBssid() { return mBssid; }
38+ const char *getSsid() { return mSsid; }
39+
40+};
41+
42+#endif
--- a/nexus/TiwlanWifiController.cpp
+++ b/nexus/TiwlanWifiController.cpp
@@ -30,8 +30,12 @@
3030
3131 extern "C" int sched_yield(void);
3232
33-TiwlanWifiController::TiwlanWifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs) :
34- WifiController(propmngr, modpath, modname, modargs) {
33+TiwlanWifiController::TiwlanWifiController(PropertyManager *propmngr,
34+ IControllerHandler *handlers,
35+ char *modpath, char *modname,
36+ char *modargs) :
37+ WifiController(propmngr, handlers, modpath, modname,
38+ modargs) {
3539 }
3640
3741 int TiwlanWifiController::powerUp() {
--- a/nexus/TiwlanWifiController.h
+++ b/nexus/TiwlanWifiController.h
@@ -20,9 +20,11 @@
2020 #include "PropertyManager.h"
2121 #include "WifiController.h"
2222
23+class IControllerHandler;
24+
2325 class TiwlanWifiController : public WifiController {
2426 public:
25- TiwlanWifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs);
27+ TiwlanWifiController(PropertyManager *propmngr, IControllerHandler *handlers, char *modpath, char *modname, char *modargs);
2628 virtual ~TiwlanWifiController() {}
2729
2830 virtual int powerUp();
--- a/nexus/VpnController.cpp
+++ b/nexus/VpnController.cpp
@@ -25,18 +25,19 @@
2525 #include "PropertyManager.h"
2626 #include "VpnController.h"
2727
28-VpnController::VpnController(PropertyManager *propmngr) :
29- Controller("VPN", propmngr) {
28+VpnController::VpnController(PropertyManager *propmngr,
29+ IControllerHandler *handlers) :
30+ Controller("VPN", propmngr, handlers) {
3031 mEnabled = false;
31- propmngr->registerProperty("vpn.enabled", this);
32- propmngr->registerProperty("vpn.gateway", this);
3332 }
3433
3534 int VpnController::start() {
35+ mPropMngr->registerProperty("vpn.enabled", this);
3636 return 0;
3737 }
3838
3939 int VpnController::stop() {
40+ mPropMngr->unregisterProperty("vpn.enabled");
4041 return 0;
4142 }
4243
@@ -49,8 +50,13 @@ int VpnController::set(const char *name, const char *value) {
4950 return 0;
5051 rc = (en ? enable() : disable());
5152
52- if (!rc)
53+ if (!rc) {
5354 mEnabled = en;
55+ if (en)
56+ mPropMngr->unregisterProperty("vpn.gateway");
57+ else
58+ mPropMngr->unregisterProperty("vpn.gateway");
59+ }
5460 return rc;
5561 } if (!strcmp(name, "vpn.gateway")) {
5662 if (!inet_aton(value, &mVpnGateway)) {
--- a/nexus/VpnController.h
+++ b/nexus/VpnController.h
@@ -21,6 +21,8 @@
2121
2222 #include "Controller.h"
2323
24+class IControllerHandler;
25+
2426 class VpnController : public Controller {
2527 bool mEnabled;
2628 /*
@@ -29,7 +31,7 @@ class VpnController : public Controller {
2931 struct in_addr mVpnGateway;
3032
3133 public:
32- VpnController(PropertyManager *propmngr);
34+ VpnController(PropertyManager *propmngr, IControllerHandler *handlers);
3335 virtual ~VpnController() {}
3436
3537 virtual int start();
--- a/nexus/WifiController.cpp
+++ b/nexus/WifiController.cpp
@@ -27,34 +27,50 @@
2727 #include "NetworkManager.h"
2828 #include "ErrorCode.h"
2929 #include "WifiNetwork.h"
30-
31-WifiController::WifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs) :
32- Controller("WIFI", propmngr) {
30+#include "ISupplicantEventHandler.h"
31+#include "SupplicantState.h"
32+#include "SupplicantStatus.h"
33+#include "SupplicantAssociatingEvent.h"
34+#include "SupplicantAssociatedEvent.h"
35+#include "SupplicantConnectedEvent.h"
36+#include "SupplicantScanResultsEvent.h"
37+#include "SupplicantStateChangeEvent.h"
38+#include "SupplicantConnectionTimeoutEvent.h"
39+#include "SupplicantDisconnectedEvent.h"
40+
41+WifiController::WifiController(PropertyManager *mPropMngr,
42+ IControllerHandler *handlers,
43+ char *modpath, char *modname, char *modargs) :
44+ Controller("WIFI", mPropMngr, handlers) {
3345 strncpy(mModulePath, modpath, sizeof(mModulePath));
3446 strncpy(mModuleName, modname, sizeof(mModuleName));
3547 strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
3648
37- mSupplicant = new Supplicant(this, propmngr);
49+ mLatestScanResults = new ScanResultCollection();
50+ pthread_mutex_init(&mLatestScanResultsLock, NULL);
51+
52+ mSupplicant = new Supplicant(this, this);
3853 mScanner = new WifiScanner(mSupplicant, 10);
3954 mCurrentScanMode = 0;
4055
4156 mEnabled = false;
4257
43- propmngr->registerProperty("wifi.enabled", this);
58+ mSupplicantState = SupplicantState::UNKNOWN;
4459 }
4560
4661 int WifiController::start() {
62+ mPropMngr->registerProperty("wifi.enabled", this);
4763 return 0;
4864 }
4965
5066 int WifiController::stop() {
51- errno = ENOSYS;
52- return -1;
67+ mPropMngr->unregisterProperty("wifi.enabled");
68+ return 0;
5369 }
5470
5571 int WifiController::enable() {
5672 if (!isPoweredUp()) {
57- sendStatusBroadcast("POWERING_UP");
73+ sendStatusBroadcast("Powering up WiFi hardware");
5874 if (powerUp()) {
5975 LOGE("Powerup failed (%s)", strerror(errno));
6076 return -1;
@@ -62,7 +78,7 @@ int WifiController::enable() {
6278 }
6379
6480 if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
65- sendStatusBroadcast("LOADING_DRIVER");
81+ sendStatusBroadcast("Loading WiFi driver");
6682 if (loadKernelModule(mModulePath, mModuleArgs)) {
6783 LOGE("Kernel module load failed (%s)", strerror(errno));
6884 goto out_powerdown;
@@ -70,7 +86,7 @@ int WifiController::enable() {
7086 }
7187
7288 if (!isFirmwareLoaded()) {
73- sendStatusBroadcast("LOADING_FIRMWARE");
89+ sendStatusBroadcast("Loading WiFI firmware");
7490 if (loadFirmware()) {
7591 LOGE("Firmware load failed (%s)", strerror(errno));
7692 goto out_powerdown;
@@ -78,7 +94,7 @@ int WifiController::enable() {
7894 }
7995
8096 if (!mSupplicant->isStarted()) {
81- sendStatusBroadcast("STARTING_SUPPLICANT");
97+ sendStatusBroadcast("Starting WPA Supplicant");
8298 if (mSupplicant->start()) {
8399 LOGE("Supplicant start failed (%s)", strerror(errno));
84100 goto out_unloadmodule;
@@ -93,6 +109,7 @@ int WifiController::enable() {
93109 if (mSupplicant->refreshNetworkList())
94110 LOGW("Error getting list of networks (%s)", strerror(errno));
95111
112+ mPropMngr->registerProperty("wifi.supplicant.state", this);
96113 mPropMngr->registerProperty("wifi.scanmode", this);
97114 mPropMngr->registerProperty("wifi.interface", this);
98115
@@ -121,8 +138,11 @@ void WifiController::sendStatusBroadcast(const char *msg) {
121138 int WifiController::disable() {
122139
123140 mPropMngr->unregisterProperty("wifi.scanmode");
141+ mPropMngr->unregisterProperty("wifi.supplicant.state");
142+ mPropMngr->unregisterProperty("wifi.scanmode");
143+
124144 if (mSupplicant->isStarted()) {
125- sendStatusBroadcast("STOPPING_SUPPLICANT");
145+ sendStatusBroadcast("Stopping WPA Supplicant");
126146 if (mSupplicant->stop()) {
127147 LOGE("Supplicant stop failed (%s)", strerror(errno));
128148 return -1;
@@ -131,7 +151,7 @@ int WifiController::disable() {
131151 LOGW("disable(): Supplicant not running?");
132152
133153 if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
134- sendStatusBroadcast("UNLOADING_DRIVER");
154+ sendStatusBroadcast("Unloading WiFi driver");
135155 if (unloadKernelModule(mModuleName)) {
136156 LOGE("Unable to unload module (%s)", strerror(errno));
137157 return -1;
@@ -139,7 +159,7 @@ int WifiController::disable() {
139159 }
140160
141161 if (isPoweredUp()) {
142- sendStatusBroadcast("POWERING_DOWN");
162+ sendStatusBroadcast("Powering down WiFi hardware");
143163 if (powerDown()) {
144164 LOGE("Powerdown failed (%s)", strerror(errno));
145165 return -1;
@@ -184,7 +204,15 @@ int WifiController::removeNetwork(int networkId) {
184204 }
185205
186206 ScanResultCollection *WifiController::createScanResults() {
187- return mSupplicant->createLatestScanResults();
207+ ScanResultCollection *d = new ScanResultCollection();
208+ ScanResultCollection::iterator i;
209+
210+ pthread_mutex_lock(&mLatestScanResultsLock);
211+ for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i)
212+ d->push_back((*i)->clone());
213+
214+ pthread_mutex_unlock(&mLatestScanResultsLock);
215+ return d;
188216 }
189217
190218 WifiNetworkCollection *WifiController::createNetworkList() {
@@ -207,7 +235,10 @@ int WifiController::set(const char *name, const char *value) {
207235 return -1;
208236 } else if (!strcmp(name, "wifi.scanmode"))
209237 return setScanMode((uint32_t) strtoul(value, NULL, 0));
210- else
238+ else if (!strcmp(name, "wifi.supplicant.state")) {
239+ errno = EROFS;
240+ return -1;
241+ } else
211242 return Controller::set(name, value);
212243 return rc;
213244 }
@@ -221,9 +252,158 @@ const char *WifiController::get(const char *name, char *buffer, size_t maxsize)
221252 (getBoundInterface() ? getBoundInterface() : "none"));
222253 } else if (!strcmp(name, "wifi.scanmode"))
223254 snprintf(buffer, maxsize, "0x%.8x", mCurrentScanMode);
255+ else if (!strcmp(name, "wifi.supplicant.state"))
256+ return SupplicantState::toString(mSupplicantState, buffer, maxsize);
224257 else
225258 return Controller::get(name, buffer, maxsize);
226259
227260 return buffer;
228261 }
229262
263+void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) {
264+ LOGD("onAssociatingEvent(%s, %s, %d)",
265+ (evt->getBssid() ? evt->getBssid() : "n/a"),
266+ (evt->getSsid() ? evt->getSsid() : "n/a"),
267+ evt->getFreq());
268+}
269+
270+void WifiController::onAssociatedEvent(SupplicantAssociatedEvent *evt) {
271+ LOGD("onAssociatedEvent(%s)", evt->getBssid());
272+}
273+
274+void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
275+ LOGD("onConnectedEvent(%s, %d)", evt->getBssid(), evt->getReassociated());
276+ if (!evt->getReassociated()) {
277+ SupplicantStatus *ss = mSupplicant->getStatus();
278+ WifiNetwork *wn;
279+
280+ if (ss->getWpaState() != SupplicantState::COMPLETED) {
281+ char tmp[32];
282+
283+ LOGW("onConnected() with SupplicantState = %s!",
284+ SupplicantState::toString(ss->getWpaState(), tmp,
285+ sizeof(tmp)));
286+ return;
287+ }
288+
289+ if (ss->getId() == -1) {
290+ LOGW("onConnected() with id = -1!");
291+ return;
292+ }
293+
294+ if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) {
295+ LOGW("Error looking up connected network id %d (%s)",
296+ ss->getId(), strerror(errno));
297+ return;
298+ }
299+
300+ delete ss;
301+ mHandlers->onInterfaceStarted(this, wn->getIfaceCfg());
302+ }
303+}
304+
305+void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
306+ char *reply;
307+
308+ if (!(reply = (char *) malloc(4096))) {
309+ LOGE("Out of memory");
310+ return;
311+ }
312+
313+ size_t len = 4096;
314+
315+ if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
316+ LOGW("onScanResultsEvent: Error getting scan results (%s)",
317+ strerror(errno));
318+ free(reply);
319+ return;
320+ }
321+
322+ pthread_mutex_lock(&mLatestScanResultsLock);
323+ if (!mLatestScanResults->empty()) {
324+ ScanResultCollection::iterator i;
325+
326+ for (i = mLatestScanResults->begin();
327+ i !=mLatestScanResults->end(); ++i) {
328+ delete *i;
329+ }
330+ mLatestScanResults->clear();
331+ }
332+
333+ char *linep;
334+ char *linep_next = NULL;
335+
336+ if (!strtok_r(reply, "\n", &linep_next)) {
337+ free(reply);
338+ pthread_mutex_unlock(&mLatestScanResultsLock);
339+ return;
340+ }
341+
342+ while((linep = strtok_r(NULL, "\n", &linep_next)))
343+ mLatestScanResults->push_back(new ScanResult(linep));
344+
345+ char *tmp;
346+ asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size());
347+ NetworkManager::Instance()->getBroadcaster()->
348+ sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false);
349+ free(tmp);
350+ pthread_mutex_unlock(&mLatestScanResultsLock);
351+ free(reply);
352+}
353+
354+void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) {
355+ char tmp[32];
356+ char tmp2[32];
357+
358+ LOGD("onStateChangeEvent(%s -> %s)",
359+ SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)),
360+ SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2)));
361+
362+ mSupplicantState = evt->getState();
363+}
364+
365+void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
366+ LOGD("onConnectionTimeoutEvent(%s)", evt->getBssid());
367+}
368+
369+void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
370+ LOGD("onDisconnectedEvent()");
371+}
372+
373+#if 0
374+void WifiController::onTerminatingEvent(SupplicantEvent *evt) {
375+ LOGD("onTerminatingEvent(%s)", evt->getEvent());
376+}
377+
378+void WifiController::onPasswordChangedEvent(SupplicantEvent *evt) {
379+ LOGD("onPasswordChangedEvent(%s)", evt->getEvent());
380+}
381+
382+void WifiController::onEapNotificationEvent(SupplicantEvent *evt) {
383+ LOGD("onEapNotificationEvent(%s)", evt->getEvent());
384+}
385+
386+void WifiController::onEapStartedEvent(SupplicantEvent *evt) {
387+ LOGD("onEapStartedEvent(%s)", evt->getEvent());
388+}
389+
390+void WifiController::onEapMethodEvent(SupplicantEvent *evt) {
391+ LOGD("onEapMethodEvent(%s)", evt->getEvent());
392+}
393+
394+void WifiController::onEapSuccessEvent(SupplicantEvent *evt) {
395+ LOGD("onEapSuccessEvent(%s)", evt->getEvent());
396+}
397+
398+void WifiController::onEapFailureEvent(SupplicantEvent *evt) {
399+ LOGD("onEapFailureEvent(%s)", evt->getEvent());
400+}
401+
402+void WifiController::onLinkSpeedEvent(SupplicantEvent *evt) {
403+ LOGD("onLinkSpeedEvent(%s)", evt->getEvent());
404+}
405+
406+void WifiController::onDriverStateEvent(SupplicantEvent *evt) {
407+ LOGD("onDriverStateEvent(%s)", evt->getEvent());
408+}
409+#endif
--- a/nexus/WifiController.h
+++ b/nexus/WifiController.h
@@ -20,15 +20,21 @@
2020 #include <sys/types.h>
2121
2222 #include "Controller.h"
23+#include "ScanResult.h"
24+#include "WifiNetwork.h"
25+#include "ISupplicantEventHandler.h"
2326
2427 class NetInterface;
2528 class Supplicant;
2629 class WifiScanner;
27-
28-#include "ScanResult.h"
29-#include "WifiNetwork.h"
30-
31-class WifiController : public Controller {
30+class SupplicantAssociatingEvent;
31+class SupplicantAssociatedEvent;
32+class SupplicantConnectedEvent;
33+class SupplicantScanResultsEvent;
34+class SupplicantStateChangeEvent;
35+class SupplicantDisconnectedEvent;
36+
37+class WifiController : public Controller, public ISupplicantEventHandler {
3238 public:
3339 static const uint32_t SCAN_ENABLE_MASK = 0x01;
3440 static const uint32_t SCAN_ACTIVE_MASK = 0x02;
@@ -45,12 +51,18 @@ private:
4551 char mModulePath[255];
4652 char mModuleName[64];
4753 char mModuleArgs[255];
54+
4855 uint32_t mCurrentScanMode;
4956 WifiScanner *mScanner;
57+ int mSupplicantState;
58+
59+ ScanResultCollection *mLatestScanResults;
60+ pthread_mutex_t mLatestScanResultsLock;
61+
5062 bool mEnabled;
5163
5264 public:
53- WifiController(PropertyManager *propmngr, char *modpath, char *modname, char *modargs);
65+ WifiController(PropertyManager *propmngr, IControllerHandler *handlers, char *modpath, char *modname, char *modargs);
5466 virtual ~WifiController() {}
5567
5668 int start();
@@ -85,6 +97,27 @@ private:
8597 int setScanMode(uint32_t mode);
8698 int enable();
8799 int disable();
100+
101+ // ISupplicantEventHandler methods
102+ virtual void onAssociatingEvent(SupplicantAssociatingEvent *evt);
103+ virtual void onAssociatedEvent(SupplicantAssociatedEvent *evt);
104+ virtual void onConnectedEvent(SupplicantConnectedEvent *evt);
105+ virtual void onScanResultsEvent(SupplicantScanResultsEvent *evt);
106+ virtual void onStateChangeEvent(SupplicantStateChangeEvent *evt);
107+ virtual void onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt);
108+ virtual void onDisconnectedEvent(SupplicantDisconnectedEvent *evt);
109+#if 0
110+ virtual void onTerminatingEvent(SupplicantEvent *evt);
111+ virtual void onPasswordChangedEvent(SupplicantEvent *evt);
112+ virtual void onEapNotificationEvent(SupplicantEvent *evt);
113+ virtual void onEapStartedEvent(SupplicantEvent *evt);
114+ virtual void onEapMethodEvent(SupplicantEvent *evt);
115+ virtual void onEapSuccessEvent(SupplicantEvent *evt);
116+ virtual void onEapFailureEvent(SupplicantEvent *evt);
117+ virtual void onLinkSpeedEvent(SupplicantEvent *evt);
118+ virtual void onDriverStateEvent(SupplicantEvent *evt);
119+#endif
120+
88121 };
89122
90123 #endif
--- a/nexus/WifiNetwork.cpp
+++ b/nexus/WifiNetwork.cpp
@@ -76,7 +76,7 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data)
7676 mDefaultKeyIndex = -1;
7777 mPriority = -1;
7878 mHiddenSsid = NULL;
79- mAllowedKeyManagement = 0;
79+ mAllowedKeyManagement = KeyManagementMask::UNKNOWN;
8080 mAllowedProtocols = 0;
8181 mAllowedAuthAlgorithms = 0;
8282 mAllowedPairwiseCiphers = 0;
@@ -94,8 +94,6 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data)
9494 asprintf(&tmp2, "wifi.net.%d", mNetid);
9595 mIfaceCfg = new InterfaceConfig(tmp2);
9696 free(tmp2);
97-
98- registerProperties();
9997 free(tmp);
10098 }
10199
@@ -121,8 +119,6 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, int networkId) {
121119 asprintf(&tmp2, "wifi.net.%d", mNetid);
122120 mIfaceCfg = new InterfaceConfig(tmp2);
123121 free(tmp2);
124-
125- registerProperties();
126122 }
127123
128124 WifiNetwork *WifiNetwork::clone() {
@@ -153,7 +149,6 @@ WifiNetwork *WifiNetwork::clone() {
153149 }
154150
155151 WifiNetwork::~WifiNetwork() {
156- unregisterProperties();
157152 if (mSsid)
158153 free(mSsid);
159154 if (mBssid)
@@ -203,7 +198,26 @@ int WifiNetwork::refresh() {
203198
204199 len = sizeof(buffer);
205200 if (mSuppl->getNetworkVar(mNetid, "key_mgmt", buffer, len)) {
206- // TODO
201+ if (!strcmp(buffer, "NONE"))
202+ setAllowedKeyManagement(KeyManagementMask::NONE);
203+ else if (index(buffer, ' ')) {
204+ char *next = buffer;
205+ char *token;
206+ uint32_t mask = 0;
207+
208+ while((token = strsep(&next, " "))) {
209+ if (!strcmp(token, "WPA-PSK"))
210+ mask |= KeyManagementMask::WPA_PSK;
211+ else if (!strcmp(token, "WPA-EAP"))
212+ mask |= KeyManagementMask::WPA_EAP;
213+ else if (!strcmp(token, "IEE8021X"))
214+ mask |= KeyManagementMask::IEEE8021X;
215+ else
216+ LOGW("Unsupported key management scheme '%s'" , token);
217+ }
218+ setAllowedKeyManagement(mask);
219+ } else
220+ LOGE("Unsupported key management '%s'", buffer);
207221 }
208222
209223 len = sizeof(buffer);
@@ -273,7 +287,7 @@ int WifiNetwork::set(const char *name, const char *value) {
273287
274288 while((v_token = strsep(&v_next, " "))) {
275289 if (!strcasecmp(v_token, "NONE")) {
276- mask = 0;
290+ mask = KeyManagementMask::NONE;
277291 none = true;
278292 } else if (!none) {
279293 if (!strcasecmp(v_token, "WPA_PSK"))
@@ -363,7 +377,29 @@ const char *WifiNetwork::get(const char *name, char *buffer, size_t maxsize) {
363377 snprintf(buffer, maxsize, "%d", getDefaultKeyIndex());
364378 else if (!strcasecmp(fc, "pri"))
365379 snprintf(buffer, maxsize, "%d", getPriority());
366- else if (!strcasecmp(fc, "hiddenssid")) {
380+ else if (!strcasecmp(fc, "AllowedKeyManagement")) {
381+ if (getAllowedKeyManagement() == KeyManagementMask::NONE)
382+ strncpy(buffer, "NONE", maxsize);
383+ else {
384+ char tmp[80] = { '\0' };
385+
386+ if (getAllowedKeyManagement() & KeyManagementMask::WPA_PSK)
387+ strcat(tmp, "WPA_PSK ");
388+ if (getAllowedKeyManagement() & KeyManagementMask::WPA_EAP)
389+ strcat(tmp, "WPA_EAP ");
390+ if (getAllowedKeyManagement() & KeyManagementMask::IEEE8021X)
391+ strcat(tmp, "IEEE8021X");
392+ if (tmp[0] == '\0') {
393+ strncpy(buffer, "(internal error)", maxsize);
394+ errno = ENOENT;
395+ return NULL;
396+ }
397+ if (tmp[strlen(tmp)] == ' ')
398+ tmp[strlen(tmp)] = '\0';
399+
400+ strncpy(buffer, tmp, maxsize);
401+ }
402+ } else if (!strcasecmp(fc, "hiddenssid")) {
367403 strncpy(buffer,
368404 getHiddenSsid() ? getHiddenSsid() : "none",
369405 maxsize);
--- a/nexus/WifiNetwork.h
+++ b/nexus/WifiNetwork.h
@@ -157,8 +157,6 @@ private:
157157
158158 private:
159159 WifiNetwork();
160- int registerProperties();
161- int unregisterProperties();
162160
163161 public:
164162 WifiNetwork(WifiController *c, Supplicant *suppl, int networkId);
@@ -167,6 +165,8 @@ public:
167165 virtual ~WifiNetwork();
168166
169167 WifiNetwork *clone();
168+ int registerProperties();
169+ int unregisterProperties();
170170
171171 int getNetworkId() { return mNetid; }
172172 const char *getSsid() { return mSsid; }
@@ -187,7 +187,7 @@ public:
187187 int set(const char *name, const char *value);
188188 const char *get(const char *name, char *buffer, size_t maxsize);
189189
190-// InterfaceConfig *getIfaceCfg() { return mIfaceCfg; }
190+ InterfaceConfig *getIfaceCfg() { return mIfaceCfg; }
191191
192192 int setEnabled(bool enabled);
193193 int setSsid(const char *ssid);
--- a/nexus/main.cpp
+++ b/nexus/main.cpp
@@ -40,10 +40,10 @@ int main() {
4040
4141 nm->setBroadcaster((SocketListener *) cl);
4242
43- nm->attachController(new LoopController(nm->getPropMngr()));
44- nm->attachController(new TiwlanWifiController(nm->getPropMngr(), "/system/lib/modules/wlan.ko", "wlan", ""));
45-// nm->attachController(new AndroidL2TPVpnController());
46- nm->attachController(new OpenVpnController(nm->getPropMngr()));
43+ nm->attachController(new LoopController(nm->getPropMngr(), nm));
44+ nm->attachController(new TiwlanWifiController(nm->getPropMngr(), nm, "/system/lib/modules/wlan.ko", "wlan", ""));
45+// nm->attachController(new AndroidL2TPVpnController(nm->getPropMngr(), nm));
46+ nm->attachController(new OpenVpnController(nm->getPropMngr(), nm));
4747
4848
4949 if (NetworkManager::Instance()->run()) {