• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

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

system/corennnnn


Commit MetaInfo

Revisiónc4a895b7094461c98101924cf096680bfb7856f1 (tree)
Tiempo2009-07-11 06:23:51
AutorSan Mehat <san@goog...>
CommiterSan Mehat

Log Message

nexus: Rollup update for nexus

nexus: Change field separator from : to ' '

Signed-off-by: San Mehat <san@google.com>

nexus: Add some prototypes for stuff to come

Signed-off-by: San Mehat <san@google.com>

nexus: Add some TODOs

Signed-off-by: San Mehat <san@google.com>

libsysutils: Put a proper token parser into the FrameworkListener which
supports minimal \ escapes and quotes

Signed-off-by: San Mehat <san@google.com>

nexus: Fix a lot of bugs

Signed-off-by: San Mehat <san@google.com>

libsysutils: Remove some debugging
Signed-off-by: San Mehat <san@google.com>

nexus: Send broadcasts for supplicant state changes

Signed-off-by: San Mehat <san@google.com>

nexus: Plumb DHCP listener state changes to NetworkManager

Signed-off-by: San Mehat <san@google.com>

nexus: Make the SupplicantState strings more parsable

Signed-off-by: San Mehat <san@google.com>

nexus: Broadcast a message when dhcp state changes.

Signed-off-by: San Mehat <san@google.com>

nexus: Add a few new response codes

Signed-off-by: San Mehat <san@google.com>

nexus: Rename ErrorCode -> ResponseCode

Signed-off-by: San Mehat <san@google.com>

nexus: Add DHCP event broadcasting. Also adds the framework for
tracking supplicant 'searching-for-AP' state

Signed-off-by: San Mehat <san@google.com>

nexus: REmove WifiScanner

Signed-off-by: San Mehat <san@google.com>

nexus: Change the way scanning works. scanmode can now be selected
independantly of triggering a scan. Also adds rxfilter support

Signed-off-by: San Mehat <san@google.com>

nexus: Add support for configuring bluetooth coexistence scanning and modes

Signed-off-by: San Mehat <san@google.com>

nexus: use case insensitive match for property names

Signed-off-by: San Mehat <san@google.com>

nexus: Rollup of a bunch of stuff:

- 'list' command now takes an argument to match against
- InterfaceConfig has been moved into the Controller base (for now)
- DhcpClient now has some rudimentry locking
- process 'ADDRINFO' messages from dhcpcd
- Drop tertiary dns

Signed-off-by: San Mehat <san@google.com>

nexus: Clean up some of the supplicant variable parsing and add 'wifi.current'

Signed-off-by: San Mehat <san@google.com>

nexus: Add driver-stop/start, initial suspend support

Signed-off-by: San Mehat <san@google.com>

nexus: Add Controller suspend/resume callbacks, as well as locking

Signed-off-by: San Mehat <san@google.com>

nexus: Make ARP probing configurable for DhcpClient

Signed-off-by: San Mehat <san@google.com>

nexus: Add linkspeed / rssi retrieval

Signed-off-by: San Mehat <san@google.com>

nexus: Add WifiStatusPoller to track RSSI/linkspeed when associated

Signed-off-by: San Mehat <san@google.com>

nexus: Disable some debugging and add 'wifi.netcount' property

Signed-off-by: San Mehat <san@google.com>

nexus: Replace the hackish property system with something more flexible with namespaces

Signed-off-by: San Mehat <san@google.com>

libsysutils: Fix a few bugs in SocketListener

Signed-off-by: San Mehat <san@google.com>

nexus: PropertyManager: Add array support

Signed-off-by: San Mehat <san@google.com>

nexus: Clean up properties
Signed-off-by: San Mehat <san@google.com>

nexus: WifiController: Change name of 'CurrentNetwork' property

Signed-off-by: San Mehat <san@google.com>

Cambiar Resumen

Diferencia incremental

--- a/include/sysutils/SocketListener.h
+++ b/include/sysutils/SocketListener.h
@@ -33,7 +33,7 @@ public:
3333 SocketListener(const char *socketNames, bool listen);
3434 SocketListener(int socketFd, bool listen);
3535
36- virtual ~SocketListener() {}
36+ virtual ~SocketListener();
3737 int startListener();
3838 int stopListener();
3939
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -56,24 +56,73 @@ void FrameworkListener::registerCmd(FrameworkCommand *cmd) {
5656 }
5757
5858 void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
59- int argc;
59+ FrameworkCommandCollection::iterator i;
60+ int argc = 0;
6061 char *argv[FrameworkListener::CMD_ARGS_MAX];
62+ char tmp[255];
63+ char *p = data;
64+ char *q = tmp;
65+ bool esc = false;
66+ bool quote = false;
67+ int k;
68+
69+ memset(argv, 0, sizeof(argv));
70+ memset(tmp, 0, sizeof(tmp));
71+ while(*p) {
72+ if (*p == '\\') {
73+ if (esc) {
74+ *q++ = '\\';
75+ esc = false;
76+ } else
77+ esc = true;
78+ p++;
79+ continue;
80+ } else if (esc) {
81+ if (*p == '"')
82+ *q++ = '"';
83+ else if (*p == '\\')
84+ *q++ = '\\';
85+ else {
86+ cli->sendMsg(500, "Unsupported escape sequence", false);
87+ goto out;
88+ }
89+ p++;
90+ esc = false;
91+ continue;
92+ }
93+
94+ if (*p == '"') {
95+ if (quote)
96+ quote = false;
97+ else
98+ quote = true;
99+ p++;
100+ continue;
101+ }
61102
62- if (!index(data, '"')) {
63- char *next = data;
64- char *field;
65- int i;
66-
67- for (i = 0; (i < FrameworkListener::CMD_ARGS_MAX) &&
68- (argv[i] = strsep(&next, " ")); i++);
69- argc = i+1;
70- } else {
71- LOGD("blehhh not supported");
72- return;
103+ *q = *p++;
104+ if (!quote && *q == ' ') {
105+ *q = '\0';
106+ argv[argc++] = strdup(tmp);
107+ memset(tmp, 0, sizeof(tmp));
108+ q = tmp;
109+ continue;
110+ }
111+ q++;
73112 }
74113
75- FrameworkCommandCollection::iterator i;
114+ argv[argc++] = strdup(tmp);
115+#if 0
116+ for (k = 0; k < argc; k++) {
117+ LOGD("arg[%d] = '%s'", k, argv[k]);
118+ }
119+#endif
76120
121+ if (quote) {
122+ cli->sendMsg(500, "Unclosed quotes error", false);
123+ goto out;
124+ }
125+
77126 for (i = mCommands->begin(); i != mCommands->end(); ++i) {
78127 FrameworkCommand *c = *i;
79128
@@ -81,10 +130,14 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
81130 if (c->runCommand(cli, argc, argv)) {
82131 LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno));
83132 }
84- return;
133+ goto out;
85134 }
86135 }
87136
88137 cli->sendMsg(500, "Command not recognized", false);
138+out:
139+ int j;
140+ for (j = 0; j < argc; j++)
141+ free(argv[j]);
89142 return;
90143 }
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -45,9 +45,26 @@ SocketListener::SocketListener(int socketFd, bool listen) {
4545 mClients = new SocketClientCollection();
4646 }
4747
48+SocketListener::~SocketListener() {
49+ if (mSocketName && mSock > -1)
50+ close(mSock);
51+
52+ if (mCtrlPipe[0] != -1) {
53+ close(mCtrlPipe[0]);
54+ close(mCtrlPipe[1]);
55+ }
56+ SocketClientCollection::iterator it;
57+ for (it = mClients->begin(); it != mClients->end(); ++it) {
58+ delete (*it);
59+ it = mClients->erase(it);
60+ }
61+ delete mClients;
62+}
63+
4864 int SocketListener::startListener() {
4965
5066 if (!mSocketName && mSock == -1) {
67+ LOGE("Failed to start unbound listener");
5168 errno = EINVAL;
5269 return -1;
5370 } else if (mSocketName) {
@@ -64,11 +81,15 @@ int SocketListener::startListener() {
6481 } else if (!mListen)
6582 mClients->push_back(new SocketClient(mSock));
6683
67- if (pipe(mCtrlPipe))
84+ if (pipe(mCtrlPipe)) {
85+ LOGE("pipe failed (%s)", strerror(errno));
6886 return -1;
87+ }
6988
70- if (pthread_create(&mThread, NULL, SocketListener::threadStart, this))
89+ if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) {
90+ LOGE("pthread_create (%s)", strerror(errno));
7191 return -1;
92+ }
7293
7394 return 0;
7495 }
@@ -88,6 +109,19 @@ int SocketListener::stopListener() {
88109 }
89110 close(mCtrlPipe[0]);
90111 close(mCtrlPipe[1]);
112+ mCtrlPipe[0] = -1;
113+ mCtrlPipe[1] = -1;
114+
115+ if (mSocketName && mSock > -1) {
116+ close(mSock);
117+ mSock = -1;
118+ }
119+
120+ SocketClientCollection::iterator it;
121+ for (it = mClients->begin(); it != mClients->end(); ++it) {
122+ delete (*it);
123+ it = mClients->erase(it);
124+ }
91125 return 0;
92126 }
93127
--- a/nexus/Android.mk
+++ b/nexus/Android.mk
@@ -7,23 +7,22 @@ include $(CLEAR_VARS)
77
88 LOCAL_SRC_FILES:= \
99 main.cpp \
10- NetworkManager.cpp \
10+ NexusCommand.cpp \
1111 CommandListener.cpp \
12+ Property.cpp \
13+ PropertyManager.cpp \
14+ InterfaceConfig.cpp \
15+ NetworkManager.cpp \
1216 Controller.cpp \
1317 WifiController.cpp \
14- LoopController.cpp \
15- NexusCommand.cpp \
1618 TiwlanWifiController.cpp \
19+ TiwlanEventListener.cpp \
20+ WifiNetwork.cpp \
21+ WifiStatusPoller.cpp \
22+ ScanResult.cpp \
1723 Supplicant.cpp \
1824 SupplicantEvent.cpp \
1925 SupplicantListener.cpp \
20- VpnController.cpp \
21- ScanResult.cpp \
22- WifiScanner.cpp \
23- WifiNetwork.cpp \
24- OpenVpnController.cpp \
25- InterfaceConfig.cpp \
26- PropertyManager.cpp \
2726 SupplicantState.cpp \
2827 SupplicantEventFactory.cpp \
2928 SupplicantConnectedEvent.cpp \
@@ -34,8 +33,11 @@ LOCAL_SRC_FILES:= \
3433 SupplicantConnectionTimeoutEvent.cpp \
3534 SupplicantDisconnectedEvent.cpp \
3635 SupplicantStatus.cpp \
37- TiwlanEventListener.cpp \
36+ OpenVpnController.cpp \
37+ VpnController.cpp \
38+ LoopController.cpp \
3839 DhcpClient.cpp DhcpListener.cpp \
40+ DhcpState.cpp DhcpEvent.cpp \
3941
4042 LOCAL_MODULE:= nexus
4143
--- a/nexus/CommandListener.cpp
+++ b/nexus/CommandListener.cpp
@@ -31,7 +31,7 @@
3131 #include "NetworkManager.h"
3232 #include "WifiController.h"
3333 #include "VpnController.h"
34-#include "ErrorCode.h"
34+#include "ResponseCode.h"
3535
3636 CommandListener::CommandListener() :
3737 FrameworkListener("nexus") {
@@ -60,11 +60,11 @@ int CommandListener::WifiCreateNetworkCmd::runCommand(SocketClient *cli,
6060 WifiNetwork *wn;
6161
6262 if (!(wn = wc->createNetwork()))
63- cli->sendMsg(ErrorCode::OperationFailed, "Failed to create network", true);
63+ cli->sendMsg(ResponseCode::OperationFailed, "Failed to create network", true);
6464 else {
6565 char tmp[128];
6666 sprintf(tmp, "Created network id %d.", wn->getNetworkId());
67- cli->sendMsg(ErrorCode::CommandOkay, tmp, false);
67+ cli->sendMsg(ResponseCode::CommandOkay, tmp, false);
6868 }
6969 return 0;
7070 }
@@ -79,9 +79,9 @@ int CommandListener::WifiRemoveNetworkCmd::runCommand(SocketClient *cli,
7979 WifiController *wc = (WifiController *) nm->findController("WIFI");
8080
8181 if (wc->removeNetwork(atoi(argv[1])))
82- cli->sendMsg(ErrorCode::OperationFailed, "Failed to remove network", true);
82+ cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove network", true);
8383 else {
84- cli->sendMsg(ErrorCode::CommandOkay, "Network removed.", false);
84+ cli->sendMsg(ResponseCode::CommandOkay, "Network removed.", false);
8585 }
8686 return 0;
8787 }
@@ -100,16 +100,16 @@ int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli,
100100 char buffer[256];
101101
102102 for(it = src->begin(); it != src->end(); ++it) {
103- sprintf(buffer, "%s:%u:%d:%s:%s",
103+ sprintf(buffer, "%s %u %d %s %s",
104104 (*it)->getBssid(), (*it)->getFreq(), (*it)->getLevel(),
105105 (*it)->getFlags(), (*it)->getSsid());
106- cli->sendMsg(ErrorCode::WifiScanResult, buffer, false);
106+ cli->sendMsg(ResponseCode::WifiScanResult, buffer, false);
107107 delete (*it);
108108 it = src->erase(it);
109109 }
110110
111111 delete src;
112- cli->sendMsg(ErrorCode::CommandOkay, "Scan results complete.", false);
112+ cli->sendMsg(ResponseCode::CommandOkay, "Scan results complete.", false);
113113 return 0;
114114 }
115115
@@ -128,12 +128,12 @@ int CommandListener::WifiListNetworksCmd::runCommand(SocketClient *cli,
128128
129129 for(it = src->begin(); it != src->end(); ++it) {
130130 sprintf(buffer, "%d:%s", (*it)->getNetworkId(), (*it)->getSsid());
131- cli->sendMsg(ErrorCode::WifiNetworkList, buffer, false);
131+ cli->sendMsg(ResponseCode::WifiNetworkList, buffer, false);
132132 delete (*it);
133133 }
134134
135135 delete src;
136- cli->sendMsg(ErrorCode::CommandOkay, "Network listing complete.", false);
136+ cli->sendMsg(ResponseCode::CommandOkay, "Network listing complete.", false);
137137 return 0;
138138 }
139139
@@ -159,14 +159,14 @@ int CommandListener::GetCmd::runCommand(SocketClient *cli, int argc, char **argv
159159
160160 char *tmp;
161161 asprintf(&tmp, "%s %s", argv[1], val);
162- cli->sendMsg(ErrorCode::PropertyRead, tmp, false);
162+ cli->sendMsg(ResponseCode::PropertyRead, tmp, false);
163163 free(tmp);
164164
165- cli->sendMsg(ErrorCode::CommandOkay, "Property read.", false);
165+ cli->sendMsg(ResponseCode::CommandOkay, "Property read.", false);
166166 return 0;
167167 out_inval:
168168 errno = EINVAL;
169- cli->sendMsg(ErrorCode::CommandParameterError, "Failed to read property.", true);
169+ cli->sendMsg(ResponseCode::CommandParameterError, "Failed to read property.", true);
170170 return 0;
171171 }
172172
@@ -179,12 +179,12 @@ int CommandListener::SetCmd::runCommand(SocketClient *cli, int argc,
179179 if (NetworkManager::Instance()->getPropMngr()->set(argv[1], argv[2]))
180180 goto out_inval;
181181
182- cli->sendMsg(ErrorCode::CommandOkay, "Property set.", false);
182+ cli->sendMsg(ResponseCode::CommandOkay, "Property set.", false);
183183 return 0;
184184
185185 out_inval:
186186 errno = EINVAL;
187- cli->sendMsg(ErrorCode::CommandParameterError, "Failed to set property.", true);
187+ cli->sendMsg(ResponseCode::CommandParameterError, "Failed to set property.", true);
188188 return 0;
189189 }
190190
@@ -194,10 +194,14 @@ CommandListener::ListCmd::ListCmd() :
194194
195195 int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **argv) {
196196 android::List<char *> *pc;
197+ char *prefix = NULL;
197198
198- if (!(pc = NetworkManager::Instance()->getPropMngr()->createPropertyList())) {
199+ if (argc > 1)
200+ prefix = argv[1];
201+
202+ if (!(pc = NetworkManager::Instance()->getPropMngr()->createPropertyList(prefix))) {
199203 errno = ENODATA;
200- cli->sendMsg(ErrorCode::CommandParameterError, "Failed to list properties.", true);
204+ cli->sendMsg(ResponseCode::CommandParameterError, "Failed to list properties.", true);
201205 return 0;
202206 }
203207
@@ -218,7 +222,7 @@ int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **arg
218222 free((*it));
219223 continue;
220224 }
221- cli->sendMsg(ErrorCode::PropertyList, buf, false);
225+ cli->sendMsg(ResponseCode::PropertyList, buf, false);
222226 free(buf);
223227
224228 free((*it));
@@ -226,6 +230,6 @@ int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **arg
226230
227231 delete pc;
228232
229- cli->sendMsg(ErrorCode::CommandOkay, "Properties list complete.", false);
233+ cli->sendMsg(ResponseCode::CommandOkay, "Properties list complete.", false);
230234 return 0;
231235 }
--- a/nexus/Controller.cpp
+++ b/nexus/Controller.cpp
@@ -30,6 +30,7 @@
3030 #include <cutils/log.h>
3131
3232 #include "Controller.h"
33+#include "InterfaceConfig.h"
3334
3435 extern "C" int init_module(void *, unsigned int, const char *);
3536 extern "C" int delete_module(const char *, unsigned int);
@@ -57,16 +58,6 @@ int Controller::stop() {
5758 return 0;
5859 }
5960
60-int Controller::set(const char *name, const char *value) {
61- errno = ENOENT;
62- return -1;
63-}
64-
65-const char *Controller::get(const char *name, char *buffer, size_t maxsize) {
66- errno = ENOENT;
67- return NULL;
68-}
69-
7061 int Controller::loadKernelModule(char *modpath, const char *args) {
7162 void *module;
7263 unsigned int size;
@@ -164,13 +155,11 @@ bail:
164155
165156 int Controller::bindInterface(const char *ifname) {
166157 mBoundInterface = strdup(ifname);
167- LOGD("Controller %s bound to %s", mName, ifname);
168158 return 0;
169159 }
170160
171161 int Controller::unbindInterface(const char *ifname) {
172162 free(mBoundInterface);
173163 mBoundInterface = NULL;
174- LOGD("Controller %s unbound from %s", mName, ifname);
175164 return 0;
176165 }
--- a/nexus/Controller.h
+++ b/nexus/Controller.h
@@ -26,9 +26,8 @@ class PropertyManager;
2626 class IControllerHandler;
2727
2828 #include "PropertyManager.h"
29-#include "IPropertyProvider.h"
3029
31-class Controller : public IPropertyProvider {
30+class Controller {
3231 /*
3332 * Name of this controller - WIFI/VPN/USBNET/BTNET/BTDUN/LOOP/etc
3433 */
@@ -54,11 +53,7 @@ public:
5453
5554 const char *getName() { return mName; }
5655 const char *getBoundInterface() { return mBoundInterface; }
57-
58- /* IPropertyProvider methods */
59- virtual int set(const char *name, const char *value);
60- virtual const char *get(const char *name, char *buffer, size_t maxsize);
61-
56+
6257 protected:
6358 int loadKernelModule(char *modpath, const char *args);
6459 bool isKernelModuleLoaded(const char *modtag);
--- a/nexus/DhcpClient.cpp
+++ b/nexus/DhcpClient.cpp
@@ -17,7 +17,9 @@
1717 #include <stdio.h>
1818 #include <errno.h>
1919 #include <sys/types.h>
20+#include <sys/socket.h>
2021 #include <arpa/inet.h>
22+#include <pthread.h>
2123
2224 #define LOG_TAG "DhcpClient"
2325 #include <cutils/log.h>
@@ -29,6 +31,7 @@
2931 #include "DhcpState.h"
3032 #include "DhcpListener.h"
3133 #include "IDhcpEventHandlers.h"
34+#include "Controller.h"
3235
3336 extern "C" {
3437 int ifc_disable(const char *ifname);
@@ -54,9 +57,13 @@ char *dhcp_get_errmsg();
5457 }
5558
5659 DhcpClient::DhcpClient(IDhcpEventHandlers *handlers) :
57- mState(DhcpState::STOPPED), mHandlers(handlers) {
60+ mState(DhcpState::INIT), mHandlers(handlers) {
5861 mServiceManager = new ServiceManager();
5962 mListener = NULL;
63+ mListenerSocket = NULL;
64+ mController = NULL;
65+ mDoArpProbe = false;
66+ pthread_mutex_init(&mLock, NULL);
6067 }
6168
6269 DhcpClient::~DhcpClient() {
@@ -65,41 +72,89 @@ DhcpClient::~DhcpClient() {
6572 delete mListener;
6673 }
6774
68-int DhcpClient::start(const char *interface) {
69-
75+int DhcpClient::start(Controller *c) {
76+ LOGD("Starting DHCP service (arp probe = %d)", mDoArpProbe);
7077 char svc[PROPERTY_VALUE_MAX];
71- snprintf(svc, sizeof(svc), "dhcpcd_ng:%s", interface);
78+ snprintf(svc,
79+ sizeof(svc),
80+ "dhcpcd:%s%s",
81+ (!mDoArpProbe ? "-A " : ""),
82+ c->getBoundInterface());
83+
84+ pthread_mutex_lock(&mLock);
85+
86+ if (mController) {
87+ pthread_mutex_unlock(&mLock);
88+ errno = EBUSY;
89+ return -1;
90+ }
91+ mController = c;
92+
93+ sockaddr_in addr;
94+ if ((mListenerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
95+ LOGE("Failed to create DHCP listener socket");
96+ pthread_mutex_unlock(&mLock);
97+ return -1;
98+ }
99+ memset(&addr, 0, sizeof(addr));
100+ addr.sin_family = AF_INET;
101+ addr.sin_addr.s_addr = inet_addr("127.0.0.1");
102+ addr.sin_port = htons(DhcpClient::STATUS_MONITOR_PORT);
103+
104+ if (bind(mListenerSocket, (struct sockaddr *) &addr, sizeof(addr))) {
105+ LOGE("Failed to bind DHCP listener socket");
106+ close(mListenerSocket);
107+ mListenerSocket = -1;
108+ pthread_mutex_unlock(&mLock);
109+ return -1;
110+ }
72111
73112 if (mServiceManager->start(svc)) {
74113 LOGE("Failed to start dhcp service");
114+ pthread_mutex_unlock(&mLock);
75115 return -1;
76116 }
77117
78- mListener = new DhcpListener(mHandlers);
118+ mListener = new DhcpListener(mController, mListenerSocket, mHandlers);
79119 if (mListener->startListener()) {
80120 LOGE("Failed to start listener");
81121 #if 0
82- mServiceManager->stop("dhcpcd_ng");
122+ mServiceManager->stop("dhcpcd");
83123 return -1;
84124 #endif
85125 delete mListener;
86126 mListener = NULL;
127+ pthread_mutex_unlock(&mLock);
87128 }
88129
89- mState = DhcpState::STARTED;
90-
130+ pthread_mutex_unlock(&mLock);
91131 return 0;
92132 }
93133
94134 int DhcpClient::stop() {
135+ pthread_mutex_lock(&mLock);
136+ if (!mController) {
137+ pthread_mutex_unlock(&mLock);
138+ return 0;
139+ }
140+
95141 if (mListener) {
96142 mListener->stopListener();
97143 delete mListener;
98144 mListener = NULL;
99145 }
146+ close(mListenerSocket);
100147
101- if (mServiceManager->stop("dhcpcd_ng"))
148+ if (mServiceManager->stop("dhcpcd")) {
102149 LOGW("Failed to stop DHCP service (%s)", strerror(errno));
103- mState = DhcpState::STOPPED;
150+ // XXX: Kill it the hard way.. but its gotta go!
151+ }
152+
153+ mController = NULL;
154+ pthread_mutex_unlock(&mLock);
104155 return 0;
105156 }
157+
158+void DhcpClient::setDoArpProbe(bool probe) {
159+ mDoArpProbe = probe;
160+}
--- a/nexus/DhcpClient.h
+++ b/nexus/DhcpClient.h
@@ -18,23 +18,36 @@
1818 #ifndef _DhcpClient_H
1919 #define _DhcpClient_H
2020
21+#include <pthread.h>
22+
2123 class IDhcpEventHandlers;
2224 class ServiceManager;
2325 class DhcpListener;
26+class Controller;
2427
2528 class DhcpClient {
29+public:
30+ static const int STATUS_MONITOR_PORT = 6666;
31+
32+private:
2633 int mState;
2734 IDhcpEventHandlers *mHandlers;
2835 ServiceManager *mServiceManager;
2936 DhcpListener *mListener;
37+ int mListenerSocket;
38+ pthread_mutex_t mLock;
39+ Controller *mController;
40+ bool mDoArpProbe;
3041
3142 public:
3243 DhcpClient(IDhcpEventHandlers *handlers);
3344 virtual ~DhcpClient();
3445
3546 int getState() { return mState; }
47+ bool getDoArpProbe() { return mDoArpProbe; }
48+ void setDoArpProbe(bool probe);
3649
37- int start(const char *interface);
50+ int start(Controller *c);
3851 int stop();
3952 };
4053
--- /dev/null
+++ b/nexus/DhcpEvent.cpp
@@ -0,0 +1,56 @@
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 <stdio.h>
18+
19+#define LOG_TAG "DhcpEvent"
20+#include <cutils/log.h>
21+
22+#include "DhcpEvent.h"
23+
24+char *DhcpEvent::toString(int val, char *buffer, int max) {
25+ if (val == DhcpEvent::UNKNOWN)
26+ strncpy(buffer, "UNKNOWN", max);
27+ else if (val == DhcpEvent::STOP)
28+ strncpy(buffer, "STOP", max);
29+ else if (val == DhcpEvent::RENEW)
30+ strncpy(buffer, "RENEW", max);
31+ else if (val == DhcpEvent::RELEASE)
32+ strncpy(buffer, "RELEASE", max);
33+ else if (val == DhcpEvent::TIMEOUT)
34+ strncpy(buffer, "TIMEOUT", max);
35+ else
36+ strncpy(buffer, "(internal error)", max);
37+
38+ return buffer;
39+}
40+
41+int DhcpEvent::parseString(const char *buffer) {
42+ if (!strcasecmp(buffer, "UNKNOWN"))
43+ return DhcpEvent::UNKNOWN;
44+ else if (!strcasecmp(buffer, "STOP"))
45+ return DhcpEvent::STOP;
46+ else if (!strcasecmp(buffer, "RENEW"))
47+ return DhcpEvent::RENEW;
48+ else if (!strcasecmp(buffer, "RELEASE"))
49+ return DhcpEvent::RELEASE;
50+ else if (!strcasecmp(buffer, "TIMEOUT"))
51+ return DhcpEvent::TIMEOUT;
52+ else {
53+ LOGW("Bad event '%s'", buffer);
54+ return -1;
55+ }
56+}
--- a/nexus/IPropertyProvider.h
+++ b/nexus/DhcpEvent.h
@@ -14,20 +14,20 @@
1414 * limitations under the License.
1515 */
1616
17-#ifndef _IPROPERTY_PROVIDER_H
18-#define _IPROPERTY_PROVIDER_H
17+#ifndef _DHCP_EVENT_H
18+#define _DHCP_EVENT_H
1919
20-#include <unistd.h>
21-#include <sys/types.h>
20+class DhcpEvent {
21+public:
22+ static const int UNKNOWN = 0;
23+ static const int STOP = 1;
24+ static const int RENEW = 2;
25+ static const int RELEASE = 3;
26+ static const int TIMEOUT = 4;
2227
23-#include <utils/List.h>
28+ static char *toString(int val, char *buffer, int max);
2429
25-class IPropertyProvider {
26-public:
27- virtual int set(const char *name, const char *value) = 0;
28- virtual const char *get(const char *name, char *buffer, size_t max) = 0;
30+ static int parseString(const char *buffer);
2931 };
3032
31-typedef android::List<IPropertyProvider *> IPropertyProviderCollection;
32-
3333 #endif
--- a/nexus/DhcpListener.cpp
+++ b/nexus/DhcpListener.cpp
@@ -14,21 +14,95 @@
1414 * limitations under the License.
1515 */
1616
17+#include <errno.h>
18+#include <sys/socket.h>
19+#include <netinet/in.h>
20+#include <arpa/inet.h>
21+
1722 #define LOG_TAG "DhcpListener"
1823 #include <cutils/log.h>
1924
2025 #include <DhcpListener.h>
2126 #include "IDhcpEventHandlers.h"
27+#include "DhcpState.h"
28+#include "DhcpEvent.h"
29+#include "Controller.h"
2230
23-DhcpListener::DhcpListener(IDhcpEventHandlers *handlers) :
24- SocketListener("dhcp_ng", false) {
31+DhcpListener::DhcpListener(Controller *c, int socket, IDhcpEventHandlers *handlers) :
32+ SocketListener(socket, false) {
2533 mHandlers = handlers;
34+ mController = c;
2635 }
2736
2837 DhcpListener::~DhcpListener() {
2938 }
3039
3140 bool DhcpListener::onDataAvailable(SocketClient *cli) {
32- LOGD("onDataAvailable()");
41+ char buffer[255];
42+ int rc;
43+
44+ if ((rc = read(cli->getSocket(), buffer, sizeof(buffer))) < 0) {
45+ LOGW("Error reading dhcp status msg (%s)", strerror(errno));
46+ return true;
47+ }
48+
49+ if (!strncmp(buffer, "STATE:", 6)) {
50+ char *next = buffer;
51+ char *tmp;
52+ int i;
53+
54+ for (i = 0; i < 2; i++) {
55+ if (!(tmp = strsep(&next, ":"))) {
56+ LOGW("Error parsing state '%s'", buffer);
57+ return true;
58+ }
59+ }
60+
61+ int st = DhcpState::parseString(tmp);
62+ mHandlers->onDhcpStateChanged(mController, st);
63+ } else if (!strncmp(buffer, "ADDRINFO:", 9)) {
64+ char *next = buffer + 9;
65+ struct in_addr ipaddr, netmask, gateway, broadcast, dns1, dns2;
66+
67+ if (!inet_aton(strsep(&next, ":"), &ipaddr)) {
68+ LOGW("Malformatted IP specified");
69+ }
70+ if (!inet_aton(strsep(&next, ":"), &netmask)) {
71+ LOGW("Malformatted netmask specified");
72+ }
73+ if (!inet_aton(strsep(&next, ":"), &broadcast)) {
74+ LOGW("Malformatted broadcast specified");
75+ }
76+ if (!inet_aton(strsep(&next, ":"), &gateway)) {
77+ LOGW("Malformatted gateway specified");
78+ }
79+ if (!inet_aton(strsep(&next, ":"), &dns1)) {
80+ LOGW("Malformatted dns1 specified");
81+ }
82+ if (!inet_aton(strsep(&next, ":"), &dns2)) {
83+ LOGW("Malformatted dns2 specified");
84+ }
85+ mHandlers->onDhcpLeaseUpdated(mController, &ipaddr, &netmask,
86+ &broadcast, &gateway, &dns1, &dns2);
87+
88+ } else if (!strncmp(buffer, "EVENT:", 6)) {
89+ char *next = buffer;
90+ char *tmp;
91+ int i;
92+
93+ for (i = 0; i < 2; i++) {
94+ if (!(tmp = strsep(&next, ":"))) {
95+ LOGW("Error parsing event '%s'", buffer);
96+ return true;
97+ }
98+ }
99+
100+ int ev = DhcpEvent::parseString(tmp);
101+ mHandlers->onDhcpEvent(mController, ev);
102+
103+ } else {
104+ LOGW("Unknown DHCP monitor msg '%s'", buffer);
105+ }
106+
33107 return true;
34108 }
--- a/nexus/DhcpListener.h
+++ b/nexus/DhcpListener.h
@@ -20,13 +20,15 @@
2020 #include <sysutils/SocketListener.h>
2121
2222 class IDhcpEventHandlers;
23+class Controller;
2324
2425 class DhcpListener : public SocketListener {
2526 IDhcpEventHandlers *mHandlers;
27+ Controller *mController;
2628
2729 public:
2830
29- DhcpListener(IDhcpEventHandlers *handlers);
31+ DhcpListener(Controller *c, int socket, IDhcpEventHandlers *handlers);
3032 virtual ~DhcpListener();
3133
3234 private:
--- /dev/null
+++ b/nexus/DhcpState.cpp
@@ -0,0 +1,80 @@
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 <stdio.h>
18+
19+#define LOG_TAG "DhcpState"
20+#include <cutils/log.h>
21+
22+#include "DhcpState.h"
23+
24+char *DhcpState::toString(int val, char *buffer, int max) {
25+ if (val == DhcpState::INIT)
26+ strncpy(buffer, "INIT", max);
27+ else if (val == DhcpState::DISCOVERING)
28+ strncpy(buffer, "DISCOVERING", max);
29+ else if (val == DhcpState::REQUESTING)
30+ strncpy(buffer, "REQUESTING", max);
31+ else if (val == DhcpState::BOUND)
32+ strncpy(buffer, "BOUND", max);
33+ else if (val == DhcpState::RENEWING)
34+ strncpy(buffer, "RENEWING", max);
35+ else if (val == DhcpState::REBINDING)
36+ strncpy(buffer, "REBINDING", max);
37+ else if (val == DhcpState::REBOOT)
38+ strncpy(buffer, "REBOOT", max);
39+ else if (val == DhcpState::RENEW_REQUESTED)
40+ strncpy(buffer, "RENEW_REQUESTED", max);
41+ else if (val == DhcpState::INIT_IPV4LL)
42+ strncpy(buffer, "INIT_IPV4LL", max);
43+ else if (val == DhcpState::PROBING)
44+ strncpy(buffer, "PROBING", max);
45+ else if (val == DhcpState::ANNOUNCING)
46+ strncpy(buffer, "ANNOUNCING", max);
47+ else
48+ strncpy(buffer, "(internal error)", max);
49+
50+ return buffer;
51+}
52+
53+int DhcpState::parseString(const char *buffer) {
54+ if (!strcasecmp(buffer, "INIT"))
55+ return DhcpState::INIT;
56+ else if (!strcasecmp(buffer, "DISCOVERING"))
57+ return DhcpState::DISCOVERING;
58+ else if (!strcasecmp(buffer, "REQUESTING"))
59+ return DhcpState::REQUESTING;
60+ else if (!strcasecmp(buffer, "BOUND"))
61+ return DhcpState::BOUND;
62+ else if (!strcasecmp(buffer, "RENEWING"))
63+ return DhcpState::RENEWING;
64+ else if (!strcasecmp(buffer, "REBINDING"))
65+ return DhcpState::REBINDING;
66+ else if (!strcasecmp(buffer, "REBOOT"))
67+ return DhcpState::REBOOT;
68+ else if (!strcasecmp(buffer, "RENEW_REQUESTED"))
69+ return DhcpState::INIT_IPV4LL;
70+ else if (!strcasecmp(buffer, "INIT_IPV4LL"))
71+ return DhcpState::INIT_IPV4LL;
72+ else if (!strcasecmp(buffer, "PROBING"))
73+ return DhcpState::PROBING;
74+ else if (!strcasecmp(buffer, "ANNOUNCING"))
75+ return DhcpState::ANNOUNCING;
76+ else {
77+ LOGW("Bad state '%s'", buffer);
78+ return -1;
79+ }
80+}
--- a/nexus/DhcpState.h
+++ b/nexus/DhcpState.h
@@ -14,14 +14,26 @@
1414 * limitations under the License.
1515 */
1616
17-#ifndef _DhcpState_H
18-#define _DhcpState_H
17+#ifndef _DHCP_STATE_H
18+#define _DHCP_STATE_H
1919
2020 class DhcpState {
2121 public:
22- static const int UNKNOWN = 0;
23- static const int STOPPED = 1;
24- static const int STARTED = 2;
22+ static const int INIT = 0;
23+ static const int DISCOVERING = 1;
24+ static const int REQUESTING = 2;
25+ static const int BOUND = 3;
26+ static const int RENEWING = 4;
27+ static const int REBINDING = 5;
28+ static const int REBOOT = 6;
29+ static const int RENEW_REQUESTED = 7;
30+ static const int INIT_IPV4LL = 8;
31+ static const int PROBING = 9;
32+ static const int ANNOUNCING = 10;
33+
34+ static char *toString(int val, char *buffer, int max);
35+
36+ static int parseString(const char *buffer);
2537 };
2638
2739 #endif
--- a/nexus/IControllerHandler.h
+++ b/nexus/IControllerHandler.h
@@ -22,8 +22,11 @@ class InterfaceConfig;
2222
2323 class IControllerHandler {
2424 public:
25- virtual void onInterfaceConnected(Controller *c, const InterfaceConfig *cfg) = 0;
26- virtual void onInterfaceDisconnected(Controller *c, const char *name) = 0;
25+ virtual ~IControllerHandler() {}
26+ virtual void onInterfaceConnected(Controller *c) = 0;
27+ virtual void onInterfaceDisconnected(Controller *c) = 0;
28+ virtual void onControllerSuspending(Controller *c) = 0;
29+ virtual void onControllerResumed(Controller *c) = 0;
2730 };
2831
2932 #endif
--- a/nexus/IDhcpEventHandlers.h
+++ b/nexus/IDhcpEventHandlers.h
@@ -20,6 +20,14 @@
2020
2121 class IDhcpEventHandlers {
2222 public:
23+ virtual ~IDhcpEventHandlers() {}
24+ virtual void onDhcpStateChanged(Controller *c, int state) = 0;
25+ virtual void onDhcpEvent(Controller *c, int event) = 0;
26+ virtual void onDhcpLeaseUpdated(Controller *c,
27+ struct in_addr *addr, struct in_addr *net,
28+ struct in_addr *brd,
29+ struct in_addr *gw, struct in_addr *dns1,
30+ struct in_addr *dns2) = 0;
2331 };
2432
2533 #endif
--- a/nexus/ISupplicantEventHandler.h
+++ b/nexus/ISupplicantEventHandler.h
@@ -27,6 +27,7 @@ class SupplicantDisconnectedEvent;
2727
2828 class ISupplicantEventHandler {
2929 public:
30+ virtual ~ISupplicantEventHandler(){}
3031 virtual void onAssociatingEvent(SupplicantAssociatingEvent *evt) = 0;
3132 virtual void onAssociatedEvent(SupplicantAssociatedEvent *evt) = 0;
3233 virtual void onConnectedEvent(SupplicantConnectedEvent *evt) = 0;
--- /dev/null
+++ b/nexus/IWifiStatusPollerHandler.h
@@ -0,0 +1,26 @@
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 _IWIFISTATUSPOLLER_HANDLER_H
18+#define _IWIFISTATUSPOLLER_HANDLER_H
19+
20+class IWifiStatusPollerHandler {
21+public:
22+ virtual ~IWifiStatusPollerHandler() {}
23+ virtual void onStatusPollInterval() = 0;
24+};
25+
26+#endif
--- a/nexus/InterfaceConfig.cpp
+++ b/nexus/InterfaceConfig.cpp
@@ -23,147 +23,72 @@
2323 #include "InterfaceConfig.h"
2424 #include "NetworkManager.h"
2525
26-const char *InterfaceConfig::PropertyNames[] = { "dhcp", "ip",
27- "netmask",
28- "gateway", "dns1", "dns2",
29- "dns3", '\0' };
30-
31-InterfaceConfig::InterfaceConfig(const char *prop_prefix) {
32- mPropPrefix = strdup(prop_prefix);
33- mUseDhcp = true;
34- registerProperties();
26+InterfaceConfig::InterfaceConfig(bool propertiesReadOnly) {
27+ mStaticProperties.propIp = new IPV4AddressPropertyHelper("Addr", propertiesReadOnly, &mIp);
28+ mStaticProperties.propNetmask = new IPV4AddressPropertyHelper("Netmask", propertiesReadOnly, &mNetmask);
29+ mStaticProperties.propGateway = new IPV4AddressPropertyHelper("Gateway", propertiesReadOnly, &mGateway);
30+ mStaticProperties.propBroadcast = new IPV4AddressPropertyHelper("Broadcast", propertiesReadOnly, &mBroadcast);
31+ mStaticProperties.propDns = new InterfaceDnsProperty(this, propertiesReadOnly);
3532 }
3633
3734 InterfaceConfig::~InterfaceConfig() {
38- unregisterProperties();
39- free(mPropPrefix);
35+ delete mStaticProperties.propIp;
36+ delete mStaticProperties.propNetmask;
37+ delete mStaticProperties.propGateway;
38+ delete mStaticProperties.propBroadcast;
39+ delete mStaticProperties.propDns;
4040 }
4141
42-InterfaceConfig::InterfaceConfig(const char *prop_prefix,
43- const char *ip, const char *nm,
44- const char *gw, const char *dns1, const char *dns2,
45- const char *dns3) {
46- mPropPrefix = strdup(prop_prefix);
47- mUseDhcp = false;
42+void InterfaceConfig::setIp(struct in_addr *addr) {
43+ memcpy(&mIp, addr, sizeof(struct in_addr));
44+}
4845
49- if (!inet_aton(ip, &mIp))
50- LOGW("Unable to parse ip (%s)", ip);
51- if (!inet_aton(nm, &mNetmask))
52- LOGW("Unable to parse netmask (%s)", nm);
53- if (!inet_aton(gw, &mGateway))
54- LOGW("Unable to parse gateway (%s)", gw);
55- if (!inet_aton(dns1, &mDns1))
56- LOGW("Unable to parse dns1 (%s)", dns1);
57- if (!inet_aton(dns2, &mDns2))
58- LOGW("Unable to parse dns2 (%s)", dns2);
59- if (!inet_aton(dns3, &mDns3))
60- LOGW("Unable to parse dns3 (%s)", dns3);
61- registerProperties();
46+void InterfaceConfig::setNetmask(struct in_addr *addr) {
47+ memcpy(&mNetmask, addr, sizeof(struct in_addr));
6248 }
6349
64-InterfaceConfig::InterfaceConfig(const char *prop_prefix,
65- const struct in_addr *ip,
66- const struct in_addr *nm, const struct in_addr *gw,
67- const struct in_addr *dns1, const struct in_addr *dns2,
68- const struct in_addr *dns3) {
69- mPropPrefix = strdup(prop_prefix);
70- mUseDhcp = false;
50+void InterfaceConfig::setGateway(struct in_addr *addr) {
51+ memcpy(&mGateway, addr, sizeof(struct in_addr));
52+}
7153
72- memcpy(&mIp, ip, sizeof(struct in_addr));
73- memcpy(&mNetmask, nm, sizeof(struct in_addr));
74- memcpy(&mGateway, gw, sizeof(struct in_addr));
75- memcpy(&mDns1, dns1, sizeof(struct in_addr));
76- memcpy(&mDns2, dns2, sizeof(struct in_addr));
77- memcpy(&mDns3, dns3, sizeof(struct in_addr));
78- registerProperties();
54+void InterfaceConfig::setBroadcast(struct in_addr *addr) {
55+ memcpy(&mBroadcast, addr, sizeof(struct in_addr));
7956 }
8057
81-int InterfaceConfig::registerProperties() {
82- for (const char **p = InterfaceConfig::PropertyNames; *p != '\0'; p++) {
83- char *tmp;
84- asprintf(&tmp, "%s.if.%s", mPropPrefix, *p);
58+void InterfaceConfig::setDns(int idx, struct in_addr *addr) {
59+ memcpy(&mDns[idx], addr, sizeof(struct in_addr));
60+}
8561
86- if (NetworkManager::Instance()->getPropMngr()->registerProperty(tmp,
87- this)) {
88- free(tmp);
89- return -1;
90- }
91- free(tmp);
92- }
62+int InterfaceConfig::attachProperties(PropertyManager *pm, const char *nsName) {
63+ pm->attachProperty(nsName, mStaticProperties.propIp);
64+ pm->attachProperty(nsName, mStaticProperties.propNetmask);
65+ pm->attachProperty(nsName, mStaticProperties.propGateway);
66+ pm->attachProperty(nsName, mStaticProperties.propBroadcast);
67+ pm->attachProperty(nsName, mStaticProperties.propDns);
9368 return 0;
9469 }
9570
96-int InterfaceConfig::unregisterProperties() {
97- for (const char **p = InterfaceConfig::PropertyNames; *p != '\0'; p++) {
98- char *tmp;
99- asprintf(&tmp, "%s.if.%s", mPropPrefix, *p);
100-
101- if (NetworkManager::Instance()->getPropMngr()->unregisterProperty(tmp))
102- LOGW("Unable to remove property '%s' (%s)", tmp, strerror(errno));
103- free(tmp);
104- }
71+int InterfaceConfig::detachProperties(PropertyManager *pm, const char *nsName) {
72+ pm->detachProperty(nsName, mStaticProperties.propIp);
73+ pm->detachProperty(nsName, mStaticProperties.propNetmask);
74+ pm->detachProperty(nsName, mStaticProperties.propGateway);
75+ pm->detachProperty(nsName, mStaticProperties.propBroadcast);
76+ pm->detachProperty(nsName, mStaticProperties.propDns);
10577 return 0;
10678 }
10779
108-int InterfaceConfig::set(const char *name, const char *value) {
109- const char *n;
110-
111- for (n = &name[strlen(name)]; *n != '.'; n--);
112- n++;
113-
114- if (!strcasecmp(n, "name")) {
115- errno = EROFS;
116- return -1;
117- } else if (!strcasecmp(n, "ip") && !inet_aton(value, &mIp))
118- goto out_inval;
119- else if (!strcasecmp(n, "dhcp"))
120- mUseDhcp = (atoi(value) == 0 ? false : true);
121- else if (!strcasecmp(n, "netmask") && !inet_aton(value, &mNetmask))
122- goto out_inval;
123- else if (!strcasecmp(n, "gateway") && !inet_aton(value, &mGateway))
124- goto out_inval;
125- else if (!strcasecmp(n, "dns1") && !inet_aton(value, &mDns1))
126- goto out_inval;
127- else if (!strcasecmp(n, "dns2") && !inet_aton(value, &mDns2))
128- goto out_inval;
129- else if (!strcasecmp(n, "dns3") && !inet_aton(value, &mDns3))
130- goto out_inval;
131- else {
132- errno = ENOENT;
133- return -1;
134- }
80+InterfaceConfig::InterfaceDnsProperty::InterfaceDnsProperty(InterfaceConfig *c,
81+ bool ro) :
82+ IPV4AddressProperty("Dns", ro, 2) {
83+ mCfg = c;
84+}
13585
86+int InterfaceConfig::InterfaceDnsProperty::set(int idx, struct in_addr *value) {
87+ memcpy(&mCfg->mDns[idx], value, sizeof(struct in_addr));
13688 return 0;
137-
138-out_inval:
139- errno = EINVAL;
140- return -1;
14189 }
142-
143-const char *InterfaceConfig::get(const char *name, char *buffer, size_t max) {
144- const char *n;
145-
146- for (n = &name[strlen(name)]; *n != '.'; n--);
147- n++;
148-
149- if (!strcasecmp(n, "ip"))
150- strncpy(buffer, inet_ntoa(mIp), max);
151- else if (!strcasecmp(n, "dhcp"))
152- snprintf(buffer, max, "%d", mUseDhcp);
153- else if (!strcasecmp(n, "netmask"))
154- strncpy(buffer, inet_ntoa(mNetmask), max);
155- else if (!strcasecmp(n, "gateway"))
156- strncpy(buffer, inet_ntoa(mGateway), max);
157- else if (!strcasecmp(n, "dns1"))
158- strncpy(buffer, inet_ntoa(mDns1), max);
159- else if (!strcasecmp(n, "dns2"))
160- strncpy(buffer, inet_ntoa(mDns2), max);
161- else if (!strcasecmp(n, "dns3"))
162- strncpy(buffer, inet_ntoa(mDns3), max);
163- else {
164- strncpy(buffer, "(internal error)", max);
165- errno = ENOENT;
166- return NULL;
167- }
168- return buffer;
90+int InterfaceConfig::InterfaceDnsProperty::get(int idx, struct in_addr *buf) {
91+ memcpy(buf, &mCfg->mDns[idx], sizeof(struct in_addr));
92+ return 0;
16993 }
94+
--- a/nexus/InterfaceConfig.h
+++ b/nexus/InterfaceConfig.h
@@ -22,53 +22,58 @@
2222 #include <netinet/in.h>
2323 #include <arpa/inet.h>
2424
25-#include "IPropertyProvider.h"
26-
25+#include "Property.h"
2726 class PropertyManager;
2827
29-class InterfaceConfig : public IPropertyProvider {
30-public:
31- static const char *PropertyNames[];
28+class InterfaceConfig {
29+ class InterfaceDnsProperty;
30+ friend class InterfaceConfig::InterfaceDnsProperty;
31+
32+ struct {
33+ IPV4AddressPropertyHelper *propIp;
34+ IPV4AddressPropertyHelper *propNetmask;
35+ IPV4AddressPropertyHelper *propGateway;
36+ IPV4AddressPropertyHelper *propBroadcast;
37+ InterfaceDnsProperty *propDns;
38+ } mStaticProperties;
3239
33-private:
34- char *mPropPrefix;
35- bool mUseDhcp;
3640 struct in_addr mIp;
3741 struct in_addr mNetmask;
3842 struct in_addr mGateway;
39- struct in_addr mDns1;
40- struct in_addr mDns2;
41- struct in_addr mDns3;
43+ struct in_addr mBroadcast;
44+ struct in_addr mDns[2];
4245
4346 public:
44- InterfaceConfig(const char *prop_prefix);
45- InterfaceConfig(const char *prop_prefix,
46- const char *ip, const char *nm,
47- const char *gw, const char *dns1, const char *dns2,
48- const char *dns3);
49-
50- InterfaceConfig(const char *prop_prefix,
51- const struct in_addr *ip,
52- const struct in_addr *nm, const struct in_addr *gw,
53- const struct in_addr *dns1, const struct in_addr *dns2,
54- const struct in_addr *dns3);
55-
47+ InterfaceConfig(bool propertiesReadOnly);
5648 virtual ~InterfaceConfig();
5749
5850 int set(const char *name, const char *value);
5951 const char *get(const char *name, char *buffer, size_t maxsize);
6052
61- bool getUseDhcp() const { return mUseDhcp; }
6253 const struct in_addr &getIp() const { return mIp; }
6354 const struct in_addr &getNetmask() const { return mNetmask; }
6455 const struct in_addr &getGateway() const { return mGateway; }
65- const struct in_addr &getDns1() const { return mDns1; }
66- const struct in_addr &getDns2() const { return mDns2; }
67- const struct in_addr &getDns3() const { return mDns3; }
56+ const struct in_addr &getBroadcast() const { return mBroadcast; }
57+ const struct in_addr &getDns(int idx) const { return mDns[idx]; }
58+
59+ void setIp(struct in_addr *addr);
60+ void setNetmask(struct in_addr *addr);
61+ void setGateway(struct in_addr *addr);
62+ void setBroadcast(struct in_addr *addr);
63+ void setDns(int idx, struct in_addr *addr);
64+
65+ int attachProperties(PropertyManager *pm, const char *nsName);
66+ int detachProperties(PropertyManager *pm, const char *nsName);
6867
6968 private:
70- int registerProperties();
71- int unregisterProperties();
69+
70+ class InterfaceDnsProperty : public IPV4AddressProperty {
71+ InterfaceConfig *mCfg;
72+ public:
73+ InterfaceDnsProperty(InterfaceConfig *cfg, bool ro);
74+ int set(int idx, struct in_addr *value);
75+ int get(int idx, struct in_addr *buffer);
76+ };
7277 };
7378
7479
--- a/nexus/LoopController.cpp
+++ b/nexus/LoopController.cpp
@@ -21,14 +21,5 @@
2121
2222 LoopController::LoopController(PropertyManager *propmngr,
2323 IControllerHandler *handlers) :
24- Controller("LOOP", propmngr, handlers) {
24+ Controller("loop", propmngr, handlers) {
2525 }
26-
27-int LoopController::set(const char *name, const char *value) {
28- return Controller::set(name, value);
29-}
30-
31-const char *LoopController::get(const char *name, char *buffer, size_t maxsize) {
32- return Controller::get(name, buffer, maxsize);
33-}
34-
--- a/nexus/NetworkManager.cpp
+++ b/nexus/NetworkManager.cpp
@@ -24,6 +24,9 @@
2424 #include "NetworkManager.h"
2525 #include "InterfaceConfig.h"
2626 #include "DhcpClient.h"
27+#include "DhcpState.h"
28+#include "DhcpEvent.h"
29+#include "ResponseCode.h"
2730
2831 NetworkManager *NetworkManager::sInstance = NULL;
2932
@@ -35,8 +38,9 @@ NetworkManager *NetworkManager::Instance() {
3538
3639 NetworkManager::NetworkManager(PropertyManager *propMngr) {
3740 mBroadcaster = NULL;
38- mControllers = new ControllerCollection();
41+ mControllerBindings = new ControllerBindingCollection();
3942 mPropMngr = propMngr;
43+ mLastDhcpState = DhcpState::INIT;
4044 mDhcp = new DhcpClient(this);
4145 }
4246
@@ -51,17 +55,17 @@ int NetworkManager::run() {
5155 }
5256
5357 int NetworkManager::attachController(Controller *c) {
54- mControllers->push_back(c);
58+ ControllerBinding *cb = new ControllerBinding(c);
59+ mControllerBindings->push_back(cb);
5560 return 0;
5661 }
5762
5863 int NetworkManager::startControllers() {
5964 int rc = 0;
60- ControllerCollection::iterator i;
65+ ControllerBindingCollection::iterator it;
6166
62- for (i = mControllers->begin(); i != mControllers->end(); ++i) {
63- int irc = (*i)->start();
64- LOGD("Controller '%s' start rc = %d", (*i)->getName(), irc);
67+ for (it = mControllerBindings->begin(); it != mControllerBindings->end(); ++it) {
68+ int irc = (*it)->getController()->start();
6569 if (irc && !rc)
6670 rc = irc;
6771 }
@@ -70,52 +74,132 @@ int NetworkManager::startControllers() {
7074
7175 int NetworkManager::stopControllers() {
7276 int rc = 0;
73- ControllerCollection::iterator i;
77+ ControllerBindingCollection::iterator it;
7478
75- for (i = mControllers->begin(); i != mControllers->end(); ++i) {
76- int irc = (*i)->stop();
77- LOGD("Controller '%s' stop rc = %d", (*i)->getName(), irc);
79+ for (it = mControllerBindings->begin(); it != mControllerBindings->end(); ++it) {
80+ int irc = (*it)->getController()->stop();
7881 if (irc && !rc)
7982 rc = irc;
8083 }
8184 return rc;
8285 }
8386
87+NetworkManager::ControllerBinding *NetworkManager::lookupBinding(Controller *c) {
88+ ControllerBindingCollection::iterator it;
89+
90+ for (it = mControllerBindings->begin(); it != mControllerBindings->end(); ++it) {
91+ if ((*it)->getController() == c)
92+ return (*it);
93+ }
94+ errno = ENOENT;
95+ return NULL;
96+}
97+
8498 Controller *NetworkManager::findController(const char *name) {
85- ControllerCollection::iterator i;
86- for (i = mControllers->begin(); i != mControllers->end(); ++i) {
87- if (!strcmp((*i)->getName(), name))
88- return *i;
99+ ControllerBindingCollection::iterator it;
100+
101+ for (it = mControllerBindings->begin(); it != mControllerBindings->end(); ++it) {
102+ if (!strcasecmp((*it)->getController()->getName(), name))
103+ return (*it)->getController();
89104 }
90- LOGW("Controller '%s' not found", name);
105+ errno = ENOENT;
91106 return NULL;
92107 }
93108
94-void NetworkManager::onInterfaceConnected(Controller *c, const InterfaceConfig *cfg) {
109+void NetworkManager::onInterfaceConnected(Controller *c) {
95110 LOGD("Controller %s interface %s connected", c->getName(), c->getBoundInterface());
96111
97- // Look up the interface
98-
99- if (0) { // already started?
112+ if (mDhcp->start(c)) {
113+ LOGE("Failed to start DHCP (%s)", strerror(errno));
114+ return;
100115 }
116+}
101117
102- if (cfg) {
103- if (cfg->getUseDhcp() && mDhcp->start(c->getBoundInterface())) {
104- LOGE("DHCP start failed");
105- } else if (!cfg->getUseDhcp()) {
106- // Static configuration
107- }
108- } else {
109- LOGD("No InterfaceConfig for %s:%s - assuming self-managed",
110- c->getName(), c->getBoundInterface());
111- }
118+void NetworkManager::onInterfaceDisconnected(Controller *c) {
119+ LOGD("Controller %s interface %s disconnected", c->getName(),
120+ c->getBoundInterface());
121+
122+ mDhcp->stop();
112123 }
113124
114-void NetworkManager::onInterfaceDisconnected(Controller *c, const char *name) {
115- LOGD("Controller %s interface %s disconnected", c->getName(), name);
125+void NetworkManager::onControllerSuspending(Controller *c) {
126+ LOGD("Controller %s interface %s suspending", c->getName(),
127+ c->getBoundInterface());
128+ mDhcp->stop();
129+}
130+
131+void NetworkManager::onControllerResumed(Controller *c) {
132+ LOGD("Controller %s interface %s resumed", c->getName(),
133+ c->getBoundInterface());
134+}
116135
117- // If we have a DHCP request out on this interface then stop it
118- if (1) {
119- mDhcp->stop();
136+void NetworkManager::onDhcpStateChanged(Controller *c, int state) {
137+ char tmp[255];
138+ char tmp2[255];
139+
140+ LOGD("onDhcpStateChanged(%s -> %s)",
141+ DhcpState::toString(mLastDhcpState, tmp, sizeof(tmp)),
142+ DhcpState::toString(state, tmp2, sizeof(tmp2)));
143+
144+ switch(state) {
145+ case DhcpState::BOUND:
146+ // Refresh the 'net.xxx' for the controller
147+ break;
148+ case DhcpState::RENEWING:
149+ break;
150+ default:
151+ break;
120152 }
153+
154+ char *tmp3;
155+ asprintf(&tmp3,
156+ "DHCP state changed from %d (%s) -> %d (%s)",
157+ mLastDhcpState,
158+ DhcpState::toString(mLastDhcpState, tmp, sizeof(tmp)),
159+ state,
160+ DhcpState::toString(state, tmp2, sizeof(tmp2)));
161+
162+ getBroadcaster()->sendBroadcast(ResponseCode::DhcpStateChange,
163+ tmp3,
164+ false);
165+ free(tmp3);
166+
167+ mLastDhcpState = state;
168+}
169+
170+void NetworkManager::onDhcpEvent(Controller *c, int evt) {
171+ char tmp[64];
172+ LOGD("onDhcpEvent(%s)", DhcpEvent::toString(evt, tmp, sizeof(tmp)));
173+}
174+
175+void NetworkManager::onDhcpLeaseUpdated(Controller *c, struct in_addr *addr,
176+ struct in_addr *net,
177+ struct in_addr *brd,
178+ struct in_addr *gw,
179+ struct in_addr *dns1,
180+ struct in_addr *dns2) {
181+ ControllerBinding *bind = lookupBinding(c);
182+
183+ if (!bind->getCurrentCfg())
184+ bind->setCurrentCfg(new InterfaceConfig(true));
185+
186+ bind->getCurrentCfg()->setIp(addr);
187+ bind->getCurrentCfg()->setNetmask(net);
188+ bind->getCurrentCfg()->setGateway(gw);
189+ bind->getCurrentCfg()->setBroadcast(brd);
190+ bind->getCurrentCfg()->setDns(0, dns1);
191+ bind->getCurrentCfg()->setDns(1, dns2);
192+}
193+
194+NetworkManager::ControllerBinding::ControllerBinding(Controller *c) :
195+ mController(c) {
196+}
197+
198+void NetworkManager::ControllerBinding::setCurrentCfg(InterfaceConfig *c) {
199+ mCurrentCfg = c;
121200 }
201+
202+void NetworkManager::ControllerBinding::setBoundCfg(InterfaceConfig *c) {
203+ mBoundCfg = c;
204+}
205+
--- a/nexus/NetworkManager.h
+++ b/nexus/NetworkManager.h
@@ -17,6 +17,7 @@
1717 #ifndef _NETWORKMANAGER_H
1818 #define _NETWORKMANAGER_H
1919
20+#include <utils/List.h>
2021 #include <sysutils/SocketListener.h>
2122
2223 #include "Controller.h"
@@ -28,14 +29,33 @@ class InterfaceConfig;
2829 class DhcpClient;
2930
3031 class NetworkManager : public IControllerHandler, public IDhcpEventHandlers {
31-private:
3232 static NetworkManager *sInstance;
3333
34+ class ControllerBinding {
35+ Controller *mController;
36+ InterfaceConfig *mCurrentCfg;
37+ InterfaceConfig *mBoundCfg;
38+
39+ public:
40+ ControllerBinding(Controller *c);
41+ virtual ~ControllerBinding() {}
42+
43+ InterfaceConfig *getCurrentCfg() { return mCurrentCfg; }
44+ InterfaceConfig *getBoundCfg() { return mCurrentCfg; }
45+ Controller *getController() { return mController; }
46+
47+ void setCurrentCfg(InterfaceConfig *cfg);
48+ void setBoundCfg(InterfaceConfig *cfg);
49+ };
50+
51+ typedef android::List<ControllerBinding *> ControllerBindingCollection;
52+
3453 private:
35- ControllerCollection *mControllers;
36- SocketListener *mBroadcaster;
37- PropertyManager *mPropMngr;
38- DhcpClient *mDhcp;
54+ ControllerBindingCollection *mControllerBindings;
55+ SocketListener *mBroadcaster;
56+ PropertyManager *mPropMngr;
57+ DhcpClient *mDhcp;
58+ int mLastDhcpState;
3959
4060 public:
4161 virtual ~NetworkManager();
@@ -57,8 +77,19 @@ private:
5777 int stopControllers();
5878
5979 NetworkManager(PropertyManager *propMngr);
80+ ControllerBinding *lookupBinding(Controller *c);
81+
82+ void onInterfaceConnected(Controller *c);
83+ void onInterfaceDisconnected(Controller *c);
84+ void onControllerSuspending(Controller *c);
85+ void onControllerResumed(Controller *c);
6086
61- void onInterfaceConnected(Controller *c, const InterfaceConfig *cfg);
62- void onInterfaceDisconnected(Controller *c, const char *name);
87+ void onDhcpStateChanged(Controller *c, int state);
88+ void onDhcpEvent(Controller *c, int event);
89+ void onDhcpLeaseUpdated(Controller *c,
90+ struct in_addr *addr, struct in_addr *net,
91+ struct in_addr *brd,
92+ struct in_addr *gw, struct in_addr *dns1,
93+ struct in_addr *dns2);
6394 };
6495 #endif
--- /dev/null
+++ b/nexus/Property.cpp
@@ -0,0 +1,203 @@
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 <errno.h>
19+#include <strings.h>
20+#include <netinet/in.h>
21+
22+#define LOG_TAG "Property"
23+
24+#include <cutils/log.h>
25+
26+#include "Property.h"
27+
28+Property::Property(const char *name, bool readOnly,
29+ int type, int numElements) :
30+ mName(name), mReadOnly(readOnly), mType(type),
31+ mNumElements(numElements) {
32+ if (index(name, '.')) {
33+ LOGW("Property name %s violates namespace rules", name);
34+ }
35+}
36+
37+StringProperty::StringProperty(const char *name, bool ro, int elements) :
38+ Property(name, ro, Property::Type_STRING, elements) {
39+}
40+int StringProperty::set(int idx, int value) {
41+ LOGE("Integer 'set' called on string property!");
42+ errno = EINVAL;
43+ return -1;
44+}
45+int StringProperty::set(int idx, struct in_addr *value) {
46+ LOGE("IpAddr 'set' called on string property!");
47+ errno = EINVAL;
48+ return -1;
49+}
50+int StringProperty::get(int idx, int *buffer) {
51+ LOGE("Integer 'get' called on string property!");
52+ errno = EINVAL;
53+ return -1;
54+}
55+int StringProperty::get(int idx, struct in_addr *buffer) {
56+ LOGE("IpAddr 'get' called on string property!");
57+ errno = EINVAL;
58+ return -1;
59+}
60+
61+StringPropertyHelper::StringPropertyHelper(const char *name, bool ro,
62+ char *buffer, size_t max) :
63+ StringProperty(name, ro, 1) {
64+ mBuffer = buffer;
65+ mMax = max;
66+}
67+
68+int StringPropertyHelper::set(int idx, const char *value) {
69+ if (idx != 0) {
70+ LOGW("Attempt to use array index on StringPropertyHelper::set");
71+ errno = EINVAL;
72+ return -1;
73+ }
74+ strncpy(mBuffer, value, mMax);
75+ return 0;
76+}
77+
78+int StringPropertyHelper::get(int idx, char *buffer, size_t max) {
79+ if (idx != 0) {
80+ LOGW("Attempt to use array index on StringPropertyHelper::get");
81+ errno = EINVAL;
82+ return -1;
83+ }
84+ strncpy(buffer, mBuffer, max);
85+ return 0;
86+}
87+
88+IntegerProperty::IntegerProperty(const char *name, bool ro, int elements) :
89+ Property(name, ro, Property::Type_INTEGER, elements) {
90+}
91+
92+int IntegerProperty::set(int idx, const char *value) {
93+ LOGE("String 'set' called on integer property!");
94+ errno = EINVAL;
95+ return -1;
96+}
97+int IntegerProperty::set(int idx, struct in_addr *value) {
98+ LOGE("IpAddr 'set' called on integer property!");
99+ errno = EINVAL;
100+ return -1;
101+}
102+int IntegerProperty::get(int idx, char *buffer, size_t max) {
103+ LOGE("String 'get' called on integer property!");
104+ errno = EINVAL;
105+ return -1;
106+}
107+int IntegerProperty::get(int idx, struct in_addr *buffer) {
108+ LOGE("IpAddr 'get' called on integer property!");
109+ errno = EINVAL;
110+ return -1;
111+}
112+
113+IntegerPropertyHelper::IntegerPropertyHelper(const char *name, bool ro,
114+ int *buffer) :
115+ IntegerProperty(name, ro, 1) {
116+ mBuffer = buffer;
117+}
118+
119+int IntegerPropertyHelper::set(int idx, int value) {
120+ if (idx != 0) {
121+ LOGW("Attempt to use array index on IntegerPropertyHelper::set");
122+ errno = EINVAL;
123+ return -1;
124+ }
125+ *mBuffer = value;
126+ return 0;
127+}
128+
129+int IntegerPropertyHelper::get(int idx, int *buffer) {
130+ if (idx != 0) {
131+ LOGW("Attempt to use array index on IntegerPropertyHelper::get");
132+ errno = EINVAL;
133+ return -1;
134+ }
135+ *buffer = *mBuffer;
136+ return 0;
137+}
138+
139+IPV4AddressProperty::IPV4AddressProperty(const char *name, bool ro, int elements) :
140+ Property(name, ro, Property::Type_IPV4, elements) {
141+}
142+
143+int IPV4AddressProperty::set(int idx, const char *value) {
144+ LOGE("String 'set' called on ipv4 property!");
145+ errno = EINVAL;
146+ return -1;
147+}
148+int IPV4AddressProperty::set(int idx, int value) {
149+ LOGE("Integer 'set' called on ipv4 property!");
150+ errno = EINVAL;
151+ return -1;
152+}
153+int IPV4AddressProperty::get(int idx, char *buffer, size_t max) {
154+ LOGE("String 'get' called on ipv4 property!");
155+ errno = EINVAL;
156+ return -1;
157+}
158+int IPV4AddressProperty::get(int idx, int *buffer) {
159+ LOGE("Integer 'get' called on ipv4 property!");
160+ errno = EINVAL;
161+ return -1;
162+}
163+
164+IPV4AddressPropertyHelper::IPV4AddressPropertyHelper(const char *name, bool ro,
165+ struct in_addr *buffer) :
166+ IPV4AddressProperty(name, ro, 1) {
167+ mBuffer = buffer;
168+}
169+
170+int IPV4AddressPropertyHelper::set(int idx, struct in_addr *value) {
171+ if (idx != 0) {
172+ LOGW("Attempt to use array index on IPV4AddressPropertyHelper::set");
173+ errno = EINVAL;
174+ return -1;
175+ }
176+ memcpy(mBuffer, value, sizeof(struct in_addr));
177+ return 0;
178+}
179+
180+int IPV4AddressPropertyHelper::get(int idx, struct in_addr *buffer) {
181+ if (idx != 0) {
182+ LOGW("Attempt to use array index on IPV4AddressPropertyHelper::get");
183+ errno = EINVAL;
184+ return -1;
185+ }
186+ memcpy(buffer, mBuffer, sizeof(struct in_addr));
187+ return 0;
188+}
189+
190+PropertyNamespace::PropertyNamespace(const char *name) {
191+ mName = strdup(name);
192+ mProperties = new PropertyCollection();
193+}
194+
195+PropertyNamespace::~PropertyNamespace() {
196+ PropertyCollection::iterator it;
197+ for (it = mProperties->begin(); it != mProperties->end();) {
198+ delete (*it);
199+ it = mProperties->erase(it);
200+ }
201+ delete mProperties;
202+ free(mName);
203+}
--- a/nexus/Property.h
+++ b/nexus/Property.h
@@ -14,8 +14,124 @@
1414 * limitations under the License.
1515 */
1616
17+#ifndef _PROPERTY_H
18+#define _PROPERTY_H
19+
20+#include <netinet/in.h>
21+#include <utils/List.h>
22+
1723 class Property {
24+ const char *mName;
25+ bool mReadOnly;
26+ int mType;
27+ int mNumElements;
28+
1829 public:
19- static const int NameMaxSize = 128;
30+ static const int NameMaxSize = 128;
2031 static const int ValueMaxSize = 255;
32+
33+ static const int Type_STRING = 1;
34+ static const int Type_INTEGER = 2;
35+ static const int Type_IPV4 = 3;
36+
37+ Property(const char *name, bool ro, int type, int elements);
38+ virtual ~Property() {}
39+
40+ virtual int set(int idx, const char *value) = 0;
41+ virtual int set(int idx, int value) = 0;
42+ virtual int set(int idx, struct in_addr *value) = 0;
43+
44+ virtual int get(int idx, char *buffer, size_t max) = 0;
45+ virtual int get(int idx, int *buffer) = 0;
46+ virtual int get(int idx, struct in_addr *buffer) = 0;
47+
48+ int getType() { return mType; }
49+ bool getReadOnly() { return mReadOnly; }
50+ int getNumElements() { return mNumElements; }
51+ const char *getName() { return mName; }
52+};
53+
54+class StringProperty : public Property {
55+public:
56+ StringProperty(const char *name, bool ro, int elements);
57+ virtual ~StringProperty() {}
58+
59+ virtual int set(int idx, const char *value) = 0;
60+ int set(int idx, int value);
61+ int set(int idx, struct in_addr *value);
62+
63+ virtual int get(int idx, char *buffer, size_t max) = 0;
64+ int get(int idx, int *buffer);
65+ int get(int idx, struct in_addr *buffer);
66+};
67+
68+class StringPropertyHelper : public StringProperty {
69+ char *mBuffer;
70+ size_t mMax;
71+public:
72+ StringPropertyHelper(const char *name, bool ro,
73+ char *buffer, size_t max);
74+ int set(int idx, const char *value);
75+ int get(int idx, char *buffer, size_t max);
76+};
77+
78+class IntegerProperty : public Property {
79+public:
80+ IntegerProperty(const char *name, bool ro, int elements);
81+ virtual ~IntegerProperty() {}
82+
83+ int set(int idx, const char *value);
84+ virtual int set(int idx, int value) = 0;
85+ int set(int idx, struct in_addr *value);
86+
87+ int get(int idx, char *buffer, size_t max);
88+ virtual int get(int idx, int *buffer) = 0;
89+ int get(int idx, struct in_addr *buffer);
90+};
91+
92+class IntegerPropertyHelper : public IntegerProperty {
93+ int *mBuffer;
94+public:
95+ IntegerPropertyHelper(const char *name, bool ro, int *buffer);
96+ int set(int idx, int value);
97+ int get(int idx, int *buffer);
98+};
99+
100+class IPV4AddressProperty : public Property {
101+public:
102+ IPV4AddressProperty(const char *name, bool ro, int elements);
103+ virtual ~IPV4AddressProperty() {}
104+
105+ int set(int idx, const char *value);
106+ int set(int idx, int value);
107+ virtual int set(int idx, struct in_addr *value) = 0;
108+
109+ int get(int idx, char *buffer, size_t max);
110+ int get(int idx, int *buffer);
111+ virtual int get(int idx, struct in_addr *buffer) = 0;
112+};
113+
114+class IPV4AddressPropertyHelper : public IPV4AddressProperty {
115+ struct in_addr *mBuffer;
116+public:
117+ IPV4AddressPropertyHelper(const char *name, bool ro, struct in_addr *buf);
118+ int set(int idx, struct in_addr *value);
119+ int get(int idx, struct in_addr *buffer);
21120 };
121+
122+typedef android::List<Property *> PropertyCollection;
123+
124+class PropertyNamespace {
125+ char *mName;
126+ PropertyCollection *mProperties;
127+
128+public:
129+ PropertyNamespace(const char *name);
130+ virtual ~PropertyNamespace();
131+
132+ const char *getName() { return mName; }
133+ PropertyCollection *getProperties() { return mProperties; }
134+};
135+
136+typedef android::List<PropertyNamespace *> PropertyNamespaceCollection;
137+#endif
--- a/nexus/PropertyManager.cpp
+++ b/nexus/PropertyManager.cpp
@@ -14,6 +14,11 @@
1414 * limitations under the License.
1515 */
1616
17+#include <stdlib.h>
18+#include <sys/socket.h>
19+#include <netinet/in.h>
20+#include <arpa/inet.h>
21+
1722 #define LOG_TAG "PropertyManager"
1823
1924 #include <cutils/log.h>
@@ -21,103 +26,255 @@
2126 #include "PropertyManager.h"
2227
2328 PropertyManager::PropertyManager() {
24- mPropertyPairs = new PropertyPairCollection();
29+ mNamespaces = new PropertyNamespaceCollection();
2530 pthread_mutex_init(&mLock, NULL);
2631 }
2732
2833 PropertyManager::~PropertyManager() {
29- delete mPropertyPairs;
34+ PropertyNamespaceCollection::iterator it;
35+
36+ for (it = mNamespaces->begin(); it != mNamespaces->end();) {
37+ delete (*it);
38+ it = mNamespaces->erase(it);
39+ }
40+ delete mNamespaces;
41+}
42+
43+PropertyNamespace *PropertyManager::lookupNamespace_UNLOCKED(const char *ns) {
44+ PropertyNamespaceCollection::iterator ns_it;
45+
46+ for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
47+ if (!strcasecmp(ns, (*ns_it)->getName()))
48+ return (*ns_it);
49+ }
50+ errno = ENOENT;
51+ return NULL;
3052 }
3153
32-int PropertyManager::registerProperty(const char *name, IPropertyProvider *pp) {
33- PropertyPairCollection::iterator it;
54+Property *PropertyManager::lookupProperty_UNLOCKED(PropertyNamespace *ns, const char *name) {
55+ PropertyCollection::iterator it;
3456
35-// LOGD("registerProperty(%s)", name);
57+ for (it = ns->getProperties()->begin();
58+ it != ns->getProperties()->end(); ++it) {
59+ if (!strcasecmp(name, (*it)->getName()))
60+ return (*it);
61+ }
62+ errno = ENOENT;
63+ return NULL;
64+}
65+
66+int PropertyManager::attachProperty(const char *ns_name, Property *p) {
67+ PropertyNamespace *ns;
68+
69+ LOGD("Attaching property %s to namespace %s", p->getName(), ns_name);
3670 pthread_mutex_lock(&mLock);
37- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) {
38- if (!strcmp(name, (*it)->getName())) {
39- errno = EADDRINUSE;
40- LOGE("Failed to register property %s (%s)",
41- name, strerror(errno));
42- pthread_mutex_unlock(&mLock);
43- return -1;
44- }
71+ if (!(ns = lookupNamespace_UNLOCKED(ns_name))) {
72+ LOGD("Creating namespace %s", ns_name);
73+ ns = new PropertyNamespace(ns_name);
74+ mNamespaces->push_back(ns);
75+ }
76+
77+ if (lookupProperty_UNLOCKED(ns, p->getName())) {
78+ errno = EADDRINUSE;
79+ pthread_mutex_unlock(&mLock);
80+ LOGE("Failed to register property %s.%s (%s)",
81+ ns_name, p->getName(), strerror(errno));
82+ return -1;
4583 }
46- mPropertyPairs->push_back(new PropertyPair(name, pp));
84+
85+ ns->getProperties()->push_back(p);
4786 pthread_mutex_unlock(&mLock);
4887 return 0;
4988 }
5089
51-int PropertyManager::unregisterProperty(const char *name) {
52- PropertyPairCollection::iterator it;
90+int PropertyManager::detachProperty(const char *ns_name, Property *p) {
91+ PropertyNamespace *ns;
5392
54-// LOGD("unregisterProperty(%s)", name);
93+ LOGD("Detaching property %s from namespace %s", p->getName(), ns_name);
5594 pthread_mutex_lock(&mLock);
56- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) {
57- if (!strcmp(name, (*it)->getName())) {
95+ if (!(ns = lookupNamespace_UNLOCKED(ns_name))) {
96+ pthread_mutex_unlock(&mLock);
97+ LOGE("Namespace '%s' not found", ns_name);
98+ return -1;
99+ }
100+
101+ PropertyCollection::iterator it;
102+
103+ for (it = ns->getProperties()->begin();
104+ it != ns->getProperties()->end(); ++it) {
105+ if (!strcasecmp(p->getName(), (*it)->getName())) {
58106 delete ((*it));
59- mPropertyPairs->erase(it);
107+ ns->getProperties()->erase(it);
60108 pthread_mutex_unlock(&mLock);
61109 return 0;
62110 }
63111 }
112+
113+ LOGE("Property %s.%s not found", ns_name, p->getName());
64114 pthread_mutex_unlock(&mLock);
65115 errno = ENOENT;
66116 return -1;
67117 }
68118
119+int PropertyManager::doSet(Property *p, int idx, const char *value) {
120+
121+ if (p->getReadOnly()) {
122+ errno = EROFS;
123+ return -1;
124+ }
125+
126+ if (p->getType() == Property::Type_STRING) {
127+ return p->set(idx, value);
128+ } else if (p->getType() == Property::Type_INTEGER) {
129+ int tmp;
130+ errno = 0;
131+ tmp = strtol(value, (char **) NULL, 10);
132+ if (errno) {
133+ LOGE("Failed to convert '%s' to int", value);
134+ errno = EINVAL;
135+ return -1;
136+ }
137+ return p->set(idx, tmp);
138+ } else if (p->getType() == Property::Type_IPV4) {
139+ struct in_addr tmp;
140+ if (!inet_aton(value, &tmp)) {
141+ LOGE("Failed to convert '%s' to ipv4", value);
142+ errno = EINVAL;
143+ return -1;
144+ }
145+ return p->set(idx, &tmp);
146+ } else {
147+ LOGE("Property '%s' has an unknown type (%d)", p->getName(),
148+ p->getType());
149+ errno = EINVAL;
150+ return -1;
151+ }
152+ errno = ENOENT;
153+ return -1;
154+}
155+
156+int PropertyManager::doGet(Property *p, int idx, char *buffer, size_t max) {
157+
158+ if (p->getType() == Property::Type_STRING) {
159+ if (p->get(idx, buffer, max)) {
160+ LOGW("String property %s get failed (%s)", p->getName(),
161+ strerror(errno));
162+ return -1;
163+ }
164+ }
165+ else if (p->getType() == Property::Type_INTEGER) {
166+ int tmp;
167+ if (p->get(idx, &tmp)) {
168+ LOGW("Integer property %s get failed (%s)", p->getName(),
169+ strerror(errno));
170+ return -1;
171+ }
172+ snprintf(buffer, max, "%d", tmp);
173+ } else if (p->getType() == Property::Type_IPV4) {
174+ struct in_addr tmp;
175+ if (p->get(idx, &tmp)) {
176+ LOGW("IPV4 property %s get failed (%s)", p->getName(),
177+ strerror(errno));
178+ return -1;
179+ }
180+ strncpy(buffer, inet_ntoa(tmp), max);
181+ } else {
182+ LOGE("Property '%s' has an unknown type (%d)", p->getName(),
183+ p->getType());
184+ errno = EINVAL;
185+ return -1;
186+ }
187+ return 0;
188+}
189+
69190 /*
70191 * IPropertyManager methods
71192 */
72193
73194 int PropertyManager::set(const char *name, const char *value) {
74- PropertyPairCollection::iterator it;
75195
196+ LOGD("set %s = '%s'", name, value);
76197 pthread_mutex_lock(&mLock);
77- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) {
78- if (!strcmp(name, (*it)->getName())) {
79- pthread_mutex_unlock(&mLock);
80- return (*it)->getProvider()->set(name, value);
198+ PropertyNamespaceCollection::iterator ns_it;
199+ for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
200+ PropertyCollection::iterator p_it;
201+ for (p_it = (*ns_it)->getProperties()->begin();
202+ p_it != (*ns_it)->getProperties()->end(); ++p_it) {
203+ for (int i = 0; i < (*p_it)->getNumElements(); i++) {
204+ char fqn[255];
205+ char tmp[8];
206+ sprintf(tmp, "_%d", i);
207+ snprintf(fqn, sizeof(fqn), "%s.%s%s",
208+ (*ns_it)->getName(), (*p_it)->getName(),
209+ ((*p_it)->getNumElements() > 1 ? tmp : ""));
210+ if (!strcasecmp(name, fqn)) {
211+ pthread_mutex_unlock(&mLock);
212+ return doSet((*p_it), i, value);
213+ }
214+ }
81215 }
82216 }
217+
218+ LOGE("Property %s not found", name);
83219 pthread_mutex_unlock(&mLock);
84220 errno = ENOENT;
85221 return -1;
86222 }
87223
88224 const char *PropertyManager::get(const char *name, char *buffer, size_t max) {
89- PropertyPairCollection::iterator it;
90-
91- memset(buffer, 0, max);
92225 pthread_mutex_lock(&mLock);
93- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) {
94- if (!strcmp(name, (*it)->getName())) {
95- pthread_mutex_unlock(&mLock);
96- return (*it)->getProvider()->get(name, buffer, max);
226+ PropertyNamespaceCollection::iterator ns_it;
227+ for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
228+ PropertyCollection::iterator p_it;
229+ for (p_it = (*ns_it)->getProperties()->begin();
230+ p_it != (*ns_it)->getProperties()->end(); ++p_it) {
231+
232+ for (int i = 0; i < (*p_it)->getNumElements(); i++) {
233+ char fqn[255];
234+ char tmp[8];
235+ sprintf(tmp, "_%d", i);
236+ snprintf(fqn, sizeof(fqn), "%s.%s%s",
237+ (*ns_it)->getName(), (*p_it)->getName(),
238+ ((*p_it)->getNumElements() > 1 ? tmp : ""));
239+ if (!strcasecmp(name, fqn)) {
240+ pthread_mutex_unlock(&mLock);
241+ if (doGet((*p_it), i, buffer, max))
242+ return NULL;
243+ return buffer;
244+ }
97245 }
246+ }
98247 }
248+
249+ LOGE("Property %s not found", name);
99250 pthread_mutex_unlock(&mLock);
100251 errno = ENOENT;
101252 return NULL;
102253 }
103254
104-android::List<char *> *PropertyManager::createPropertyList() {
255+android::List<char *> *PropertyManager::createPropertyList(const char *prefix) {
105256 android::List<char *> *c = new android::List<char *>();
106257
107- PropertyPairCollection::iterator it;
108-
109258 pthread_mutex_lock(&mLock);
110- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it)
111- c->push_back(strdup((*it)->getName()));
259+ PropertyNamespaceCollection::iterator ns_it;
260+ for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
261+ PropertyCollection::iterator p_it;
262+ for (p_it = (*ns_it)->getProperties()->begin();
263+ p_it != (*ns_it)->getProperties()->end(); ++p_it) {
264+ for (int i = 0; i < (*p_it)->getNumElements(); i++) {
265+ char fqn[255];
266+ char tmp[8];
267+ sprintf(tmp, "_%d", i);
268+ snprintf(fqn, sizeof(fqn), "%s.%s%s",
269+ (*ns_it)->getName(), (*p_it)->getName(),
270+ ((*p_it)->getNumElements() > 1 ? tmp : ""));
271+ if (!prefix ||
272+ (prefix && !strncasecmp(fqn, prefix, strlen(prefix)))) {
273+ c->push_back(strdup(fqn));
274+ }
275+ }
276+ }
277+ }
112278 pthread_mutex_unlock(&mLock);
113279 return c;
114280 }
115-
116-PropertyPair::PropertyPair(const char *name, IPropertyProvider *pp) {
117- mName = strdup(name);
118- mPp = pp;
119-}
120-
121-PropertyPair::~PropertyPair() {
122- free(mName);
123-}
--- a/nexus/PropertyManager.h
+++ b/nexus/PropertyManager.h
@@ -22,36 +22,28 @@
2222
2323 #include <utils/List.h>
2424
25-#include "IPropertyProvider.h"
26-
27-class PropertyPair {
28-private:
29- char *mName;
30- IPropertyProvider *mPp;
31-
32-public:
33- PropertyPair(const char *name, IPropertyProvider *pp);
34- virtual ~PropertyPair();
35-
36- const char *getName() { return mName; }
37- IPropertyProvider *getProvider() { return mPp; }
38-};
39-
40-typedef android::List<PropertyPair *> PropertyPairCollection;
25+#include "Property.h"
4126
4227 class PropertyManager {
43- PropertyPairCollection *mPropertyPairs;
44- pthread_mutex_t mLock;
28+ PropertyNamespaceCollection *mNamespaces;
29+ pthread_mutex_t mLock;
4530
4631 public:
4732 PropertyManager();
48- virtual ~PropertyManager();
49- int registerProperty(const char *name, IPropertyProvider *pp);
50- int unregisterProperty(const char *name);
51- android::List<char *> *createPropertyList();
33+ virtual ~PropertyManager();
34+ int attachProperty(const char *ns, Property *p);
35+ int detachProperty(const char *ns, Property *p);
36+
37+ android::List<char *> *createPropertyList(const char *prefix);
5238
5339 int set(const char *name, const char *value);
5440 const char *get(const char *name, char *buffer, size_t max);
41+
42+private:
43+ PropertyNamespace *lookupNamespace_UNLOCKED(const char *ns);
44+ Property *lookupProperty_UNLOCKED(PropertyNamespace *ns, const char *name);
45+ int doSet(Property *p, int idx, const char *value);
46+ int doGet(Property *p, int idx, char *buffer, size_t max);
5547 };
5648
5749 #endif
--- a/nexus/ErrorCode.h
+++ b/nexus/ResponseCode.h
@@ -14,10 +14,10 @@
1414 * limitations under the License.
1515 */
1616
17-#ifndef _ERRORCODE_H
18-#define _ERRORCODE_H
17+#ifndef _RESPONSECODE_H
18+#define _RESPONSECODE_H
1919
20-class ErrorCode {
20+class ResponseCode {
2121 public:
2222 // 100 series - Requestion action was initiated; expect another reply
2323 // before proceeding with a new command.
@@ -44,5 +44,10 @@ public:
4444
4545 // 600 series - Unsolicited broadcasts
4646 static const int UnsolicitedInformational = 600;
47+ static const int DhcpStateChange = 605;
48+ static const int SupplicantStateChange = 610;
49+ static const int ScanResultsReady = 615;
50+ static const int LinkSpeedChange = 620;
51+ static const int RssiChange = 625;
4752 };
4853 #endif
--- a/nexus/Supplicant.cpp
+++ b/nexus/Supplicant.cpp
@@ -30,7 +30,6 @@
3030 #include "Supplicant.h"
3131 #include "SupplicantListener.h"
3232 #include "NetworkManager.h"
33-#include "ErrorCode.h"
3433 #include "WifiController.h"
3534 #include "SupplicantStatus.h"
3635
@@ -114,6 +113,29 @@ bool Supplicant::isStarted() {
114113 return mServiceManager->isRunning(SUPPLICANT_SERVICE_NAME);
115114 }
116115
116+int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len) {
117+
118+ if (!mCtrl) {
119+ errno = ENOTCONN;
120+ return -1;
121+ }
122+
123+// LOGD("sendCommand(): -> '%s'", cmd);
124+
125+ int rc;
126+ memset(reply, 0, *reply_len);
127+ if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) {
128+ errno = ETIMEDOUT;
129+ return -1;
130+ } else if (rc < 0 || !strncmp(reply, "FAIL", 4)) {
131+ strcpy(reply, "FAIL");
132+ errno = EIO;
133+ return -1;
134+ }
135+
136+ // LOGD("sendCommand(): <- '%s'", reply);
137+ return 0;
138+}
117139 SupplicantStatus *Supplicant::getStatus() {
118140 char *reply;
119141 size_t len = 4096;
@@ -162,6 +184,7 @@ int Supplicant::refreshNetworkList() {
162184 return -1;
163185 }
164186
187+ PropertyManager *pm = NetworkManager::Instance()->getPropMngr();
165188 pthread_mutex_lock(&mNetworksLock);
166189
167190 int num_added = 0;
@@ -182,7 +205,9 @@ int Supplicant::refreshNetworkList() {
182205 delete new_wn;
183206 } else {
184207 num_added++;
185- new_wn->registerProperties();
208+ char new_ns[20];
209+ snprintf(new_ns, sizeof(new_ns), "wifi.net.%d", new_wn->getNetworkId());
210+ new_wn->attachProperties(pm, new_ns);
186211 mNetworks->push_back(new_wn);
187212 if (new_wn->refresh()) {
188213 LOGW("Unable to refresh network id %d (%s)",
@@ -198,7 +223,9 @@ int Supplicant::refreshNetworkList() {
198223 for (i = mNetworks->begin(); i != mNetworks->end(); ++i) {
199224 if (0) {
200225 num_removed++;
201- (*i)->unregisterProperties();
226+ char del_ns[20];
227+ snprintf(del_ns, sizeof(del_ns), "wifi.net.%d", (*i)->getNetworkId());
228+ (*i)->detachProperties(pm, del_ns);
202229 delete (*i);
203230 i = mNetworks->erase(i);
204231 }
@@ -247,44 +274,98 @@ int Supplicant::connectToSupplicant() {
247274 return 0;
248275 }
249276
250-int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len)
251-{
252- if (!mCtrl) {
253- errno = ENOTCONN;
277+int Supplicant::setScanMode(bool active) {
278+ char reply[255];
279+ size_t len = sizeof(reply);
280+
281+ if (sendCommand((active ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"),
282+ reply, &len)) {
283+ LOGW("triggerScan(%d): Error setting scan mode (%s)", active,
284+ strerror(errno));
254285 return -1;
255286 }
287+ return 0;
288+}
256289
257-// LOGD("sendCommand(): -> '%s'", cmd);
290+int Supplicant::triggerScan() {
291+ char reply[255];
292+ size_t len = sizeof(reply);
258293
259- int rc;
260- memset(reply, 0, *reply_len);
261- if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) {
262- errno = ETIMEDOUT;
294+ if (sendCommand("SCAN", reply, &len)) {
295+ LOGW("triggerScan(): Error initiating scan");
263296 return -1;
264- } else if (rc < 0 || !strncmp(reply, "FAIL", 4)) {
265- strcpy(reply, "FAIL");
266- errno = EIO;
297+ }
298+ return 0;
299+}
300+
301+int Supplicant::getRssi(int *buffer) {
302+ char reply[64];
303+ size_t len = sizeof(reply);
304+
305+ if (sendCommand("DRIVER RSSI", reply, &len)) {
306+ LOGW("Failed to get RSSI (%s)", strerror(errno));
267307 return -1;
268308 }
269309
270-// LOGD("sendCommand(): <- '%s'", reply);
310+ char *next = reply;
311+ char *s;
312+ for (int i = 0; i < 3; i++) {
313+ if (!(s = strsep(&next, " "))) {
314+ LOGE("Error parsing RSSI");
315+ errno = EIO;
316+ return -1;
317+ }
318+ }
319+ *buffer = atoi(s);
271320 return 0;
272321 }
273322
274-int Supplicant::triggerScan(bool active) {
275- char reply[255];
323+int Supplicant::getLinkSpeed() {
324+ char reply[64];
276325 size_t len = sizeof(reply);
277326
278- if (sendCommand((active ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"),
279- reply, &len)) {
280- LOGW("triggerScan(%d): Error setting scan mode (%s)", active,
281- strerror(errno));
327+ if (sendCommand("DRIVER LINKSPEED", reply, &len)) {
328+ LOGW("Failed to get LINKSPEED (%s)", strerror(errno));
282329 return -1;
283330 }
284- len = sizeof(reply);
285331
286- if (sendCommand("SCAN", reply, &len)) {
287- LOGW("triggerScan(%d): Error initiating scan", active);
332+ char *next = reply;
333+ char *s;
334+
335+ if (!(s = strsep(&next, " "))) {
336+ LOGE("Error parsing LINKSPEED");
337+ errno = EIO;
338+ return -1;
339+ }
340+
341+ if (!(s = strsep(&next, " "))) {
342+ LOGE("Error parsing LINKSPEED");
343+ errno = EIO;
344+ return -1;
345+ }
346+ return atoi(s);
347+}
348+
349+int Supplicant::stopDriver() {
350+ char reply[64];
351+ size_t len = sizeof(reply);
352+
353+ LOGD("stopDriver()");
354+
355+ if (sendCommand("DRIVER STOP", reply, &len)) {
356+ LOGW("Failed to stop driver (%s)", strerror(errno));
357+ return -1;
358+ }
359+ return 0;
360+}
361+
362+int Supplicant::startDriver() {
363+ char reply[64];
364+ size_t len = sizeof(reply);
365+
366+ LOGD("startDriver()");
367+ if (sendCommand("DRIVER START", reply, &len)) {
368+ LOGW("Failed to start driver (%s)", strerror(errno));
288369 return -1;
289370 }
290371 return 0;
@@ -301,7 +382,11 @@ WifiNetwork *Supplicant::createNetwork() {
301382 reply[strlen(reply) -1] = '\0';
302383
303384 WifiNetwork *wn = new WifiNetwork(mController, this, atoi(reply));
385+ PropertyManager *pm = NetworkManager::Instance()->getPropMngr();
304386 pthread_mutex_lock(&mNetworksLock);
387+ char new_ns[20];
388+ snprintf(new_ns, sizeof(new_ns), "wifi.net.%d", wn->getNetworkId());
389+ wn->attachProperties(pm, new_ns);
305390 mNetworks->push_back(wn);
306391 pthread_mutex_unlock(&mNetworksLock);
307392 return wn;
@@ -411,8 +496,9 @@ int Supplicant::setNetworkVar(int networkId, const char *var, const char *val) {
411496 char reply[255];
412497 size_t len = sizeof(reply) -1;
413498
499+ LOGD("netid %d, var '%s' = '%s'", networkId, var, val);
414500 char *tmp;
415- asprintf(&tmp, "SET_NETWORK %d %s \"%s\"", networkId, var, val);
501+ asprintf(&tmp, "SET_NETWORK %d %s %s", networkId, var, val);
416502 if (sendCommand(tmp, reply, &len)) {
417503 free(tmp);
418504 return -1;
@@ -457,6 +543,95 @@ int Supplicant::enableNetwork(int networkId, bool enabled) {
457543 return 0;
458544 }
459545
546+int Supplicant::enablePacketFilter() {
547+ char req[128];
548+ char reply[16];
549+ size_t len;
550+ int i;
551+
552+ for (i = 0; i <=3; i++) {
553+ snprintf(req, sizeof(req), "DRIVER RXFILTER-ADD %d", i);
554+ len = sizeof(reply);
555+ if (sendCommand(req, reply, &len))
556+ return -1;
557+ }
558+
559+ len = sizeof(reply);
560+ if (sendCommand("DRIVER RXFILTER-START", reply, &len))
561+ return -1;
562+ return 0;
563+}
564+
565+int Supplicant::disablePacketFilter() {
566+ char req[128];
567+ char reply[16];
568+ size_t len;
569+ int i;
570+
571+ len = sizeof(reply);
572+ if (sendCommand("DRIVER RXFILTER-STOP", reply, &len))
573+ return -1;
574+
575+ for (i = 3; i >=0; i--) {
576+ snprintf(req, sizeof(req), "DRIVER RXFILTER-REMOVE %d", i);
577+ len = sizeof(reply);
578+ if (sendCommand(req, reply, &len))
579+ return -1;
580+ }
581+ return 0;
582+}
583+
584+int Supplicant::enableBluetoothCoexistenceScan() {
585+ char req[128];
586+ char reply[16];
587+ size_t len;
588+ int i;
589+
590+ len = sizeof(reply);
591+ if (sendCommand("DRIVER BTCOEXSCAN-START", reply, &len))
592+ return -1;
593+ return 0;
594+}
595+
596+int Supplicant::disableBluetoothCoexistenceScan() {
597+ char req[128];
598+ char reply[16];
599+ size_t len;
600+ int i;
601+
602+ len = sizeof(reply);
603+ if (sendCommand("DRIVER BTCOEXSCAN-STOP", reply, &len))
604+ return -1;
605+ return 0;
606+}
607+
608+int Supplicant::setBluetoothCoexistenceMode(int mode) {
609+ char req[64];
610+
611+ sprintf(req, "DRIVER BTCOEXMODE %d", mode);
612+
613+ char reply[16];
614+ size_t len = sizeof(reply) -1;
615+
616+ if (sendCommand(req, reply, &len))
617+ return -1;
618+ return 0;
619+}
620+
621+int Supplicant::setApScanMode(int mode) {
622+ char req[64];
623+
624+// LOGD("setApScanMode(%d)", mode);
625+ sprintf(req, "AP_SCAN %d", mode);
626+
627+ char reply[16];
628+ size_t len = sizeof(reply) -1;
629+
630+ if (sendCommand(req, reply, &len))
631+ return -1;
632+ return 0;
633+}
634+
460635
461636 int Supplicant::retrieveInterfaceName() {
462637 char reply[255];
@@ -469,3 +644,34 @@ int Supplicant::retrieveInterfaceName() {
469644 mInterfaceName = strdup(reply);
470645 return 0;
471646 }
647+
648+int Supplicant::reconnect() {
649+ char req[128];
650+ char reply[16];
651+ size_t len;
652+ int i;
653+
654+ len = sizeof(reply);
655+ if (sendCommand("RECONNECT", reply, &len))
656+ return -1;
657+ return 0;
658+}
659+
660+int Supplicant::disconnect() {
661+ char req[128];
662+ char reply[16];
663+ size_t len;
664+ int i;
665+
666+ len = sizeof(reply);
667+ if (sendCommand("DISCONNECT", reply, &len))
668+ return -1;
669+ return 0;
670+}
671+
672+int Supplicant::getNetworkCount() {
673+ pthread_mutex_lock(&mNetworksLock);
674+ int cnt = mNetworks->size();
675+ pthread_mutex_unlock(&mNetworksLock);
676+ return cnt;
677+}
--- a/nexus/Supplicant.h
+++ b/nexus/Supplicant.h
@@ -30,7 +30,6 @@ class SupplicantStatus;
3030 #include "ISupplicantEventHandler.h"
3131
3232 class Supplicant {
33-private:
3433 struct wpa_ctrl *mCtrl;
3534 struct wpa_ctrl *mMonitor;
3635 SupplicantListener *mListener;
@@ -50,7 +49,8 @@ public:
5049 int stop();
5150 bool isStarted();
5251
53- int triggerScan(bool active);
52+ int setScanMode(bool active);
53+ int triggerScan();
5454
5555 WifiNetwork *createNetwork();
5656 WifiNetwork *lookupNetwork(int networkId);
@@ -63,6 +63,21 @@ public:
6363 size_t max);
6464 int enableNetwork(int networkId, bool enabled);
6565
66+ int disconnect();
67+ int reconnect();
68+ int reassociate();
69+ int setApScanMode(int mode);
70+ int enablePacketFilter();
71+ int disablePacketFilter();
72+ int setBluetoothCoexistenceMode(int mode);
73+ int enableBluetoothCoexistenceScan();
74+ int disableBluetoothCoexistenceScan();
75+ int stopDriver();
76+ int startDriver();
77+ int getRssi(int *buffer);
78+ int getLinkSpeed();
79+ int getNetworkCount();
80+
6681 SupplicantStatus *getStatus();
6782
6883 Controller *getController() { return (Controller *) mController; }
--- a/nexus/SupplicantState.cpp
+++ b/nexus/SupplicantState.cpp
@@ -23,25 +23,25 @@
2323
2424 char *SupplicantState::toString(int val, char *buffer, int max) {
2525 if (val == SupplicantState::UNKNOWN)
26- strncpy(buffer, "Unknown", max);
26+ strncpy(buffer, "UNKNOWN", max);
2727 else if (val == SupplicantState::DISCONNECTED)
28- strncpy(buffer, "Disconnected", max);
28+ strncpy(buffer, "DISCONNECTED", max);
2929 else if (val == SupplicantState::INACTIVE)
30- strncpy(buffer, "Inactive", max);
30+ strncpy(buffer, "INACTIVE", max);
3131 else if (val == SupplicantState::SCANNING)
32- strncpy(buffer, "Scanning", max);
32+ strncpy(buffer, "SCANNING", max);
3333 else if (val == SupplicantState::ASSOCIATING)
34- strncpy(buffer, "Associating", max);
34+ strncpy(buffer, "ASSOCIATING", max);
3535 else if (val == SupplicantState::ASSOCIATED)
36- strncpy(buffer, "Associated", max);
36+ strncpy(buffer, "ASSOCIATED", max);
3737 else if (val == SupplicantState::FOURWAY_HANDSHAKE)
38- strncpy(buffer, "Fourway Handshake", max);
38+ strncpy(buffer, "FOURWAY_HANDSHAKE", max);
3939 else if (val == SupplicantState::GROUP_HANDSHAKE)
40- strncpy(buffer, "Group Handshake", max);
40+ strncpy(buffer, "GROUP_HANDSHAKE", max);
4141 else if (val == SupplicantState::COMPLETED)
42- strncpy(buffer, "Completed", max);
42+ strncpy(buffer, "COMPLETED", max);
4343 else if (val == SupplicantState::IDLE)
44- strncpy(buffer, "Idle", max);
44+ strncpy(buffer, "IDLE", max);
4545 else
4646 strncpy(buffer, "(internal error)", max);
4747
--- a/nexus/TiwlanWifiController.cpp
+++ b/nexus/TiwlanWifiController.cpp
@@ -51,6 +51,7 @@ int TiwlanWifiController::powerUp() {
5151 int TiwlanWifiController::powerDown() {
5252 if (mEventListener) {
5353 delete mEventListener;
54+ shutdown(mListenerSock, SHUT_RDWR);
5455 close(mListenerSock);
5556 mListenerSock = -1;
5657 mEventListener = NULL;
@@ -77,7 +78,8 @@ int TiwlanWifiController::loadFirmware() {
7778 LOGD("Firmware loaded OK");
7879
7980 if (startDriverEventListener()) {
80- LOGW("Failed to start driver event listener");
81+ LOGW("Failed to start driver event listener (%s)",
82+ strerror(errno));
8183 }
8284
8385 return 0;
@@ -95,32 +97,48 @@ int TiwlanWifiController::loadFirmware() {
9597
9698 int TiwlanWifiController::startDriverEventListener() {
9799 struct sockaddr_in addr;
98- int s;
99100
100- if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
101+ if (mListenerSock != -1) {
102+ LOGE("Listener already started!");
103+ errno = EBUSY;
101104 return -1;
105+ }
106+
107+ if ((mListenerSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
108+ LOGE("socket failed (%s)", strerror(errno));
109+ return -1;
110+ }
102111
103112 memset(&addr, 0, sizeof(addr));
104113 addr.sin_family = AF_INET;
105114 addr.sin_addr.s_addr = htonl(INADDR_ANY);
106115 addr.sin_port = htons(TI_DRIVER_MSG_PORT);
107116
108- if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
109- close(s);
110- return -1;
117+ if (bind(mListenerSock,
118+ (struct sockaddr *) &addr,
119+ sizeof(addr)) < 0) {
120+ LOGE("bind failed (%s)", strerror(errno));
121+ goto out_err;
111122 }
112123
113- mEventListener = new TiwlanEventListener(s);
124+ mEventListener = new TiwlanEventListener(mListenerSock);
114125
115126 if (mEventListener->startListener()) {
116127 LOGE("Error starting driver listener (%s)", strerror(errno));
128+ goto out_err;
129+ }
130+ return 0;
131+out_err:
132+ if (mEventListener) {
117133 delete mEventListener;
118134 mEventListener = NULL;
119- close(s);
120- return -1;
121135 }
122- mListenerSock = s;
123- return 0;
136+ if (mListenerSock != -1) {
137+ shutdown(mListenerSock, SHUT_RDWR);
138+ close(mListenerSock);
139+ mListenerSock = -1;
140+ }
141+ return -1;
124142 }
125143
126144 bool TiwlanWifiController::isFirmwareLoaded() {
--- a/nexus/VpnController.cpp
+++ b/nexus/VpnController.cpp
@@ -27,56 +27,66 @@
2727
2828 VpnController::VpnController(PropertyManager *propmngr,
2929 IControllerHandler *handlers) :
30- Controller("VPN", propmngr, handlers) {
30+ Controller("vpn", propmngr, handlers) {
3131 mEnabled = false;
32+
33+ mStaticProperties.propEnabled = new VpnEnabledProperty(this);
34+ mDynamicProperties.propGateway = new IPV4AddressPropertyHelper("Gateway",
35+ false,
36+ &mGateway);
3237 }
3338
3439 int VpnController::start() {
35- mPropMngr->registerProperty("vpn.enabled", this);
40+ mPropMngr->attachProperty("vpn", mStaticProperties.propEnabled);
3641 return 0;
3742 }
3843
3944 int VpnController::stop() {
40- mPropMngr->unregisterProperty("vpn.enabled");
45+ mPropMngr->detachProperty("vpn", mStaticProperties.propEnabled);
4146 return 0;
4247 }
4348
44-int VpnController::set(const char *name, const char *value) {
45- if (!strcmp(name, "vpn.enabled")) {
46- int en = atoi(value);
47- int rc;
48-
49- if (en == mEnabled)
50- return 0;
51- rc = (en ? enable() : disable());
49+VpnController::VpnIntegerProperty::VpnIntegerProperty(VpnController *c,
50+ const char *name,
51+ bool ro,
52+ int elements) :
53+ IntegerProperty(name, ro, elements) {
54+ mVc = c;
55+}
5256
53- if (!rc) {
54- mEnabled = en;
55- if (en)
56- mPropMngr->unregisterProperty("vpn.gateway");
57- else
58- mPropMngr->unregisterProperty("vpn.gateway");
59- }
60- return rc;
61- } if (!strcmp(name, "vpn.gateway")) {
62- if (!inet_aton(value, &mVpnGateway)) {
63- errno = EINVAL;
64- return -1;
65- }
66- return 0;
67- }
57+VpnController::VpnStringProperty::VpnStringProperty(VpnController *c,
58+ const char *name,
59+ bool ro, int elements) :
60+ StringProperty(name, ro, elements) {
61+ mVc = c;
62+}
6863
69- return Controller::set(name, value);
64+VpnController::VpnIPV4AddressProperty::VpnIPV4AddressProperty(VpnController *c,
65+ const char *name,
66+ bool ro, int elements) :
67+ IPV4AddressProperty(name, ro, elements) {
68+ mVc = c;
7069 }
7170
72-const char *VpnController::get(const char *name, char *buffer, size_t maxsize) {
73- if (!strcmp(name, "vpn.enabled")) {
74- snprintf(buffer, maxsize, "%d", mEnabled);
75- return buffer;
76- } if (!strcmp(name, "vpn.gateway")) {
77- snprintf(buffer, maxsize, "%s", inet_ntoa(mVpnGateway));
78- return buffer;
71+VpnController::VpnEnabledProperty::VpnEnabledProperty(VpnController *c) :
72+ VpnIntegerProperty(c, "Enabled", false, 1) {
73+}
74+int VpnController::VpnEnabledProperty::get(int idx, int *buffer) {
75+ *buffer = mVc->mEnabled;
76+ return 0;
77+}
78+int VpnController::VpnEnabledProperty::set(int idx, int value) {
79+ int rc;
80+ if (!value) {
81+ mVc->mPropMngr->detachProperty("vpn", mVc->mDynamicProperties.propGateway);
82+ rc = mVc->disable();
83+ } else {
84+ rc = mVc->enable();
85+ if (!rc) {
86+ mVc->mPropMngr->attachProperty("vpn", mVc->mDynamicProperties.propGateway);
87+ }
7988 }
80-
81- return Controller::get(name, buffer, maxsize);
89+ if (!rc)
90+ mVc->mEnabled = value;
91+ return rc;
8292 }
--- a/nexus/VpnController.h
+++ b/nexus/VpnController.h
@@ -24,11 +24,63 @@
2424 class IControllerHandler;
2525
2626 class VpnController : public Controller {
27+ class VpnIntegerProperty : public IntegerProperty {
28+ protected:
29+ VpnController *mVc;
30+ public:
31+ VpnIntegerProperty(VpnController *c, const char *name, bool ro,
32+ int elements);
33+ virtual ~VpnIntegerProperty() {}
34+ virtual int set(int idx, int value) = 0;
35+ virtual int get(int idx, int *buffer) = 0;
36+ };
37+ friend class VpnController::VpnIntegerProperty;
38+
39+ class VpnStringProperty : public StringProperty {
40+ protected:
41+ VpnController *mVc;
42+ public:
43+ VpnStringProperty(VpnController *c, const char *name, bool ro,
44+ int elements);
45+ virtual ~VpnStringProperty() {}
46+ virtual int set(int idx, const char *value) = 0;
47+ virtual int get(int idx, char *buffer, size_t max) = 0;
48+ };
49+ friend class VpnController::VpnStringProperty;
50+
51+ class VpnIPV4AddressProperty : public IPV4AddressProperty {
52+ protected:
53+ VpnController *mVc;
54+ public:
55+ VpnIPV4AddressProperty(VpnController *c, const char *name, bool ro,
56+ int elements);
57+ virtual ~VpnIPV4AddressProperty() {}
58+ virtual int set(int idx, struct in_addr *value) = 0;
59+ virtual int get(int idx, struct in_addr *buffer) = 0;
60+ };
61+ friend class VpnController::VpnIPV4AddressProperty;
62+
63+ class VpnEnabledProperty : public VpnIntegerProperty {
64+ public:
65+ VpnEnabledProperty(VpnController *c);
66+ virtual ~VpnEnabledProperty() {};
67+ int set(int idx, int value);
68+ int get(int idx, int *buffer);
69+ };
70+
2771 bool mEnabled;
2872 /*
2973 * Gateway of the VPN server to connect to
3074 */
31- struct in_addr mVpnGateway;
75+ struct in_addr mGateway;
76+
77+ struct {
78+ VpnEnabledProperty *propEnabled;
79+ } mStaticProperties;
80+
81+ struct {
82+ IPV4AddressPropertyHelper *propGateway;
83+ } mDynamicProperties;
3284
3385 public:
3486 VpnController(PropertyManager *propmngr, IControllerHandler *handlers);
@@ -37,13 +89,9 @@ public:
3789 virtual int start();
3890 virtual int stop();
3991
40- virtual int set(const char *name, const char *value);
41- virtual const char *get(const char *name, char *buffer, size_t maxlen);
42-
4392 protected:
4493 virtual int enable() = 0;
4594 virtual int disable() = 0;
46-
4795 };
4896
4997 #endif
--- a/nexus/WifiController.cpp
+++ b/nexus/WifiController.cpp
@@ -23,9 +23,8 @@
2323
2424 #include "Supplicant.h"
2525 #include "WifiController.h"
26-#include "WifiScanner.h"
2726 #include "NetworkManager.h"
28-#include "ErrorCode.h"
27+#include "ResponseCode.h"
2928 #include "WifiNetwork.h"
3029 #include "ISupplicantEventHandler.h"
3130 #include "SupplicantState.h"
@@ -37,11 +36,12 @@
3736 #include "SupplicantStateChangeEvent.h"
3837 #include "SupplicantConnectionTimeoutEvent.h"
3938 #include "SupplicantDisconnectedEvent.h"
39+#include "WifiStatusPoller.h"
4040
4141 WifiController::WifiController(PropertyManager *mPropMngr,
4242 IControllerHandler *handlers,
4343 char *modpath, char *modname, char *modargs) :
44- Controller("WIFI", mPropMngr, handlers) {
44+ Controller("wifi", mPropMngr, handlers) {
4545 strncpy(mModulePath, modpath, sizeof(mModulePath));
4646 strncpy(mModuleName, modname, sizeof(mModuleName));
4747 strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
@@ -49,22 +49,59 @@ WifiController::WifiController(PropertyManager *mPropMngr,
4949 mLatestScanResults = new ScanResultCollection();
5050 pthread_mutex_init(&mLatestScanResultsLock, NULL);
5151
52- mSupplicant = new Supplicant(this, this);
53- mScanner = new WifiScanner(mSupplicant, 10);
54- mCurrentScanMode = 0;
52+ pthread_mutex_init(&mLock, NULL);
5553
54+ mSupplicant = new Supplicant(this, this);
55+ mActiveScan = false;
5656 mEnabled = false;
57+ mScanOnly = false;
58+ mPacketFilter = false;
59+ mBluetoothCoexScan = false;
60+ mBluetoothCoexMode = 0;
61+ mCurrentlyConnectedNetworkId = -1;
62+ mStatusPoller = new WifiStatusPoller(this);
63+ mRssiEventThreshold = 5;
64+ mLastLinkSpeed = 0;
5765
5866 mSupplicantState = SupplicantState::UNKNOWN;
67+
68+ mStaticProperties.propEnabled = new WifiEnabledProperty(this);
69+ mStaticProperties.propScanOnly = new WifiScanOnlyProperty(this);
70+ mStaticProperties.propAllowedChannels = new WifiAllowedChannelsProperty(this);
71+
72+ mStaticProperties.propRssiEventThreshold =
73+ new IntegerPropertyHelper("RssiEventThreshold", false, &mRssiEventThreshold);
74+
75+ mDynamicProperties.propSupplicantState = new WifiSupplicantStateProperty(this);
76+ mDynamicProperties.propActiveScan = new WifiActiveScanProperty(this);
77+ mDynamicProperties.propInterface = new WifiInterfaceProperty(this);
78+ mDynamicProperties.propSearching = new WifiSearchingProperty(this);
79+ mDynamicProperties.propPacketFilter = new WifiPacketFilterProperty(this);
80+ mDynamicProperties.propBluetoothCoexScan = new WifiBluetoothCoexScanProperty(this);
81+ mDynamicProperties.propBluetoothCoexMode = new WifiBluetoothCoexModeProperty(this);
82+ mDynamicProperties.propCurrentNetwork = new WifiCurrentNetworkProperty(this);
83+
84+ mDynamicProperties.propRssi = new IntegerPropertyHelper("Rssi", true, &mLastRssi);
85+ mDynamicProperties.propLinkSpeed = new IntegerPropertyHelper("LinkSpeed", true, &mLastLinkSpeed);
86+
87+ mDynamicProperties.propSuspended = new WifiSuspendedProperty(this);
88+ mDynamicProperties.propNetCount = new WifiNetCountProperty(this);
89+ mDynamicProperties.propTriggerScan = new WifiTriggerScanProperty(this);
5990 }
6091
6192 int WifiController::start() {
62- mPropMngr->registerProperty("wifi.enabled", this);
93+ mPropMngr->attachProperty("wifi", mStaticProperties.propEnabled);
94+ mPropMngr->attachProperty("wifi", mStaticProperties.propScanOnly);
95+ mPropMngr->attachProperty("wifi", mStaticProperties.propAllowedChannels);
96+ mPropMngr->attachProperty("wifi", mStaticProperties.propRssiEventThreshold);
6397 return 0;
6498 }
6599
66100 int WifiController::stop() {
67- mPropMngr->unregisterProperty("wifi.enabled");
101+ mPropMngr->detachProperty("wifi", mStaticProperties.propEnabled);
102+ mPropMngr->detachProperty("wifi", mStaticProperties.propScanOnly);
103+ mPropMngr->detachProperty("wifi", mStaticProperties.propAllowedChannels);
104+ mPropMngr->detachProperty("wifi", mStaticProperties.propRssiEventThreshold);
68105 return 0;
69106 }
70107
@@ -114,9 +151,21 @@ int WifiController::enable() {
114151 if (mSupplicant->refreshNetworkList())
115152 LOGW("Error getting list of networks (%s)", strerror(errno));
116153
117- mPropMngr->registerProperty("wifi.supplicant.state", this);
118- mPropMngr->registerProperty("wifi.scanmode", this);
119- mPropMngr->registerProperty("wifi.interface", this);
154+ LOGW("TODO: Set # of allowed regulatory channels!");
155+
156+ mPropMngr->attachProperty("wifi", mDynamicProperties.propSupplicantState);
157+ mPropMngr->attachProperty("wifi", mDynamicProperties.propActiveScan);
158+ mPropMngr->attachProperty("wifi", mDynamicProperties.propInterface);
159+ mPropMngr->attachProperty("wifi", mDynamicProperties.propSearching);
160+ mPropMngr->attachProperty("wifi", mDynamicProperties.propPacketFilter);
161+ mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
162+ mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
163+ mPropMngr->attachProperty("wifi", mDynamicProperties.propCurrentNetwork);
164+ mPropMngr->attachProperty("wifi", mDynamicProperties.propRssi);
165+ mPropMngr->attachProperty("wifi", mDynamicProperties.propLinkSpeed);
166+ mPropMngr->attachProperty("wifi", mDynamicProperties.propSuspended);
167+ mPropMngr->attachProperty("wifi", mDynamicProperties.propNetCount);
168+ mPropMngr->attachProperty("wifi", mDynamicProperties.propTriggerScan);
120169
121170 LOGI("Enabled successfully");
122171 return 0;
@@ -135,17 +184,87 @@ out_powerdown:
135184 return -1;
136185 }
137186
187+bool WifiController::getSuspended() {
188+ pthread_mutex_lock(&mLock);
189+ bool r = mSuspended;
190+ pthread_mutex_unlock(&mLock);
191+ return r;
192+}
193+
194+int WifiController::setSuspend(bool suspend) {
195+
196+ pthread_mutex_lock(&mLock);
197+ if (suspend == mSuspended) {
198+ LOGW("Suspended state already = %d", suspend);
199+ pthread_mutex_unlock(&mLock);
200+ return 0;
201+ }
202+
203+ if (suspend) {
204+ mHandlers->onControllerSuspending(this);
205+
206+ char tmp[80];
207+ LOGD("Suspending from supplicant state %s",
208+ SupplicantState::toString(mSupplicantState,
209+ tmp,
210+ sizeof(tmp)));
211+
212+ if (mSupplicantState != SupplicantState::IDLE) {
213+ LOGD("Forcing Supplicant disconnect");
214+ if (mSupplicant->disconnect()) {
215+ LOGW("Error disconnecting (%s)", strerror(errno));
216+ }
217+ }
218+
219+ LOGD("Stopping Supplicant driver");
220+ if (mSupplicant->stopDriver()) {
221+ LOGE("Error stopping driver (%s)", strerror(errno));
222+ pthread_mutex_unlock(&mLock);
223+ return -1;
224+ }
225+ } else {
226+ LOGD("Resuming");
227+
228+ if (mSupplicant->startDriver()) {
229+ LOGE("Error resuming driver (%s)", strerror(errno));
230+ pthread_mutex_unlock(&mLock);
231+ return -1;
232+ }
233+ // XXX: set regulatory max channels
234+ if (mScanOnly)
235+ mSupplicant->triggerScan();
236+ else
237+ mSupplicant->reconnect();
238+
239+ mHandlers->onControllerResumed(this);
240+ }
241+
242+ mSuspended = suspend;
243+ pthread_mutex_unlock(&mLock);
244+ LOGD("Suspend / Resume completed");
245+ return 0;
246+}
247+
138248 void WifiController::sendStatusBroadcast(const char *msg) {
139249 NetworkManager::Instance()->
140250 getBroadcaster()->
141- sendBroadcast(ErrorCode::UnsolicitedInformational, msg, false);
251+ sendBroadcast(ResponseCode::UnsolicitedInformational, msg, false);
142252 }
143253
144254 int WifiController::disable() {
145255
146- mPropMngr->unregisterProperty("wifi.scanmode");
147- mPropMngr->unregisterProperty("wifi.supplicant.state");
148- mPropMngr->unregisterProperty("wifi.scanmode");
256+ mPropMngr->detachProperty("wifi", mDynamicProperties.propSupplicantState);
257+ mPropMngr->detachProperty("wifi", mDynamicProperties.propActiveScan);
258+ mPropMngr->detachProperty("wifi", mDynamicProperties.propInterface);
259+ mPropMngr->detachProperty("wifi", mDynamicProperties.propSearching);
260+ mPropMngr->detachProperty("wifi", mDynamicProperties.propPacketFilter);
261+ mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
262+ mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
263+ mPropMngr->detachProperty("wifi", mDynamicProperties.propCurrentNetwork);
264+ mPropMngr->detachProperty("wifi", mDynamicProperties.propRssi);
265+ mPropMngr->detachProperty("wifi", mDynamicProperties.propLinkSpeed);
266+ mPropMngr->detachProperty("wifi", mDynamicProperties.propSuspended);
267+ mPropMngr->detachProperty("wifi", mDynamicProperties.propNetCount);
149268
150269 if (mSupplicant->isStarted()) {
151270 sendStatusBroadcast("Stopping WPA Supplicant");
@@ -178,35 +297,61 @@ int WifiController::loadFirmware() {
178297 return 0;
179298 }
180299
181-int WifiController::setScanMode(uint32_t mode) {
182- int rc = 0;
300+int WifiController::triggerScan() {
301+ pthread_mutex_lock(&mLock);
302+ if (verifyNotSuspended()) {
303+ pthread_mutex_unlock(&mLock);
304+ return -1;
305+ }
183306
184- if (mCurrentScanMode == mode)
185- return 0;
307+ switch (mSupplicantState) {
308+ case SupplicantState::DISCONNECTED:
309+ case SupplicantState::INACTIVE:
310+ case SupplicantState::SCANNING:
311+ case SupplicantState::IDLE:
312+ break;
313+ default:
314+ // Switch to scan only mode
315+ mSupplicant->setApScanMode(2);
316+ break;
317+ }
186318
187- if (!(mode & SCAN_ENABLE_MASK)) {
188- if (mCurrentScanMode & SCAN_REPEAT_MASK)
189- mScanner->stop();
190- } else if (mode & SCAN_REPEAT_MASK)
191- rc = mScanner->start(mode & SCAN_ACTIVE_MASK);
192- else
193- rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
319+ int rc = mSupplicant->triggerScan();
320+ pthread_mutex_unlock(&mLock);
321+ return rc;
322+}
194323
195- mCurrentScanMode = mode;
324+int WifiController::setActiveScan(bool active) {
325+ pthread_mutex_lock(&mLock);
326+ if (mActiveScan == active) {
327+ pthread_mutex_unlock(&mLock);
328+ return 0;
329+ }
330+ mActiveScan = active;
331+
332+ int rc = mSupplicant->setScanMode(active);
333+ pthread_mutex_unlock(&mLock);
196334 return rc;
197335 }
198336
199337 WifiNetwork *WifiController::createNetwork() {
338+ pthread_mutex_lock(&mLock);
200339 WifiNetwork *wn = mSupplicant->createNetwork();
340+ pthread_mutex_unlock(&mLock);
201341 return wn;
202342 }
203343
204344 int WifiController::removeNetwork(int networkId) {
345+ pthread_mutex_lock(&mLock);
205346 WifiNetwork *wn = mSupplicant->lookupNetwork(networkId);
206347
207- if (!wn)
348+ if (!wn) {
349+ pthread_mutex_unlock(&mLock);
208350 return -1;
209- return mSupplicant->removeNetwork(wn);
351+ }
352+ int rc = mSupplicant->removeNetwork(wn);
353+ pthread_mutex_unlock(&mLock);
354+ return rc;
210355 }
211356
212357 ScanResultCollection *WifiController::createScanResults() {
@@ -225,45 +370,59 @@ WifiNetworkCollection *WifiController::createNetworkList() {
225370 return mSupplicant->createNetworkList();
226371 }
227372
228-int WifiController::set(const char *name, const char *value) {
373+int WifiController::setPacketFilter(bool enable) {
229374 int rc;
230375
231- if (!strcmp(name, "wifi.enabled")) {
232- int en = atoi(value);
376+ pthread_mutex_lock(&mLock);
377+ if (enable)
378+ rc = mSupplicant->enablePacketFilter();
379+ else
380+ rc = mSupplicant->disablePacketFilter();
233381
234- if (en == mEnabled)
235- return 0;
236- rc = (en ? enable() : disable());
237- if (!rc)
238- mEnabled = en;
239- } else if (!strcmp(name, "wifi.interface")) {
240- errno = EROFS;
241- return -1;
242- } else if (!strcmp(name, "wifi.scanmode"))
243- return setScanMode((uint32_t) strtoul(value, NULL, 0));
244- else if (!strcmp(name, "wifi.supplicant.state")) {
245- errno = EROFS;
246- return -1;
247- } else
248- return Controller::set(name, value);
382+ if (!rc)
383+ mPacketFilter = enable;
384+ pthread_mutex_unlock(&mLock);
249385 return rc;
250386 }
251387
252-const char *WifiController::get(const char *name, char *buffer, size_t maxsize) {
388+int WifiController::setBluetoothCoexistenceScan(bool enable) {
389+ int rc;
390+
391+ pthread_mutex_lock(&mLock);
253392
254- if (!strcmp(name, "wifi.enabled"))
255- snprintf(buffer, maxsize, "%d", mEnabled);
256- else if (!strcmp(name, "wifi.interface")) {
257- snprintf(buffer, maxsize, "%s",
258- (getBoundInterface() ? getBoundInterface() : "none"));
259- } else if (!strcmp(name, "wifi.scanmode"))
260- snprintf(buffer, maxsize, "0x%.8x", mCurrentScanMode);
261- else if (!strcmp(name, "wifi.supplicant.state"))
262- return SupplicantState::toString(mSupplicantState, buffer, maxsize);
393+ if (enable)
394+ rc = mSupplicant->enableBluetoothCoexistenceScan();
263395 else
264- return Controller::get(name, buffer, maxsize);
396+ rc = mSupplicant->disableBluetoothCoexistenceScan();
397+
398+ if (!rc)
399+ mBluetoothCoexScan = enable;
400+ pthread_mutex_unlock(&mLock);
401+ return rc;
402+}
265403
266- return buffer;
404+int WifiController::setScanOnly(bool scanOnly) {
405+ pthread_mutex_lock(&mLock);
406+ int rc = mSupplicant->setApScanMode((scanOnly ? 2 : 1));
407+ if (!rc)
408+ mScanOnly = scanOnly;
409+ if (!mSuspended) {
410+ if (scanOnly)
411+ mSupplicant->disconnect();
412+ else
413+ mSupplicant->reconnect();
414+ }
415+ pthread_mutex_unlock(&mLock);
416+ return rc;
417+}
418+
419+int WifiController::setBluetoothCoexistenceMode(int mode) {
420+ pthread_mutex_lock(&mLock);
421+ int rc = mSupplicant->setBluetoothCoexistenceMode(mode);
422+ if (!rc)
423+ mBluetoothCoexMode = mode;
424+ pthread_mutex_unlock(&mLock);
425+ return rc;
267426 }
268427
269428 void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) {
@@ -296,6 +455,7 @@ void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
296455 return;
297456 }
298457
458+ mCurrentlyConnectedNetworkId = ss->getId();
299459 if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) {
300460 LOGW("Error looking up connected network id %d (%s)",
301461 ss->getId(), strerror(errno));
@@ -303,7 +463,7 @@ void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
303463 }
304464
305465 delete ss;
306- mHandlers->onInterfaceConnected(this, wn->getIfaceCfg());
466+ mHandlers->onInterfaceConnected(this);
307467 }
308468
309469 void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
@@ -314,6 +474,10 @@ void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
314474 return;
315475 }
316476
477+ mNumScanResultsSinceLastStateChange++;
478+ if (mNumScanResultsSinceLastStateChange >= 3)
479+ mIsSupplicantSearching = false;
480+
317481 size_t len = 4096;
318482
319483 if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
@@ -346,10 +510,14 @@ void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
346510 while((linep = strtok_r(NULL, "\n", &linep_next)))
347511 mLatestScanResults->push_back(new ScanResult(linep));
348512
513+ // Switch handling of scan results back to normal mode
514+ mSupplicant->setApScanMode(1);
515+
349516 char *tmp;
350517 asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size());
351518 NetworkManager::Instance()->getBroadcaster()->
352- sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false);
519+ sendBroadcast(ResponseCode::ScanResultsReady,
520+ tmp, false);
353521 free(tmp);
354522 pthread_mutex_unlock(&mLatestScanResultsLock);
355523 free(reply);
@@ -359,11 +527,35 @@ void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) {
359527 char tmp[32];
360528 char tmp2[32];
361529
530+ if (evt->getState() == mSupplicantState)
531+ return;
532+
362533 LOGD("onStateChangeEvent(%s -> %s)",
363534 SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)),
364535 SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2)));
365536
537+ if (evt->getState() != SupplicantState::SCANNING) {
538+ mIsSupplicantSearching = true;
539+ mNumScanResultsSinceLastStateChange = 0;
540+ }
541+
542+ char *tmp3;
543+ asprintf(&tmp3,
544+ "Supplicant state changed from %d (%s) -> %d (%s)",
545+ mSupplicantState, tmp, evt->getState(), tmp2);
546+
366547 mSupplicantState = evt->getState();
548+
549+ if (mSupplicantState == SupplicantState::COMPLETED) {
550+ mStatusPoller->start();
551+ } else if (mStatusPoller->isStarted()) {
552+ mStatusPoller->stop();
553+ }
554+
555+ NetworkManager::Instance()->getBroadcaster()->
556+ sendBroadcast(ResponseCode::SupplicantStateChange,
557+ tmp3, false);
558+ free(tmp3);
367559 }
368560
369561 void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
@@ -371,7 +563,8 @@ void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *
371563 }
372564
373565 void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
374- mHandlers->onInterfaceDisconnected(this, getBoundInterface());
566+ mCurrentlyConnectedNetworkId = -1;
567+ mHandlers->onInterfaceDisconnected(this);
375568 }
376569
377570 #if 0
@@ -411,3 +604,216 @@ void WifiController::onDriverStateEvent(SupplicantEvent *evt) {
411604 LOGD("onDriverStateEvent(%s)", evt->getEvent());
412605 }
413606 #endif
607+
608+void WifiController::onStatusPollInterval() {
609+ pthread_mutex_lock(&mLock);
610+ int rssi;
611+ if (mSupplicant->getRssi(&rssi)) {
612+ LOGE("Failed to get rssi (%s)", strerror(errno));
613+ pthread_mutex_unlock(&mLock);
614+ return;
615+ }
616+
617+ if (abs(mLastRssi - rssi) > mRssiEventThreshold) {
618+ char *tmp3;
619+ asprintf(&tmp3, "RSSI changed from %d -> %d",
620+ mLastRssi, rssi);
621+ mLastRssi = rssi;
622+ NetworkManager::Instance()->getBroadcaster()->
623+ sendBroadcast(ResponseCode::RssiChange,
624+ tmp3, false);
625+ free(tmp3);
626+ }
627+
628+ int linkspeed = mSupplicant->getLinkSpeed();
629+ if (linkspeed != mLastLinkSpeed) {
630+ char *tmp3;
631+ asprintf(&tmp3, "Link speed changed from %d -> %d",
632+ mLastLinkSpeed, linkspeed);
633+ mLastLinkSpeed = linkspeed;
634+ NetworkManager::Instance()->getBroadcaster()->
635+ sendBroadcast(ResponseCode::LinkSpeedChange,
636+ tmp3, false);
637+ free(tmp3);
638+
639+ }
640+ pthread_mutex_unlock(&mLock);
641+}
642+
643+int WifiController::verifyNotSuspended() {
644+ if (mSuspended) {
645+ errno = ESHUTDOWN;
646+ return -1;
647+ }
648+ return 0;
649+}
650+
651+/*
652+ * Property inner classes
653+ */
654+
655+WifiController::WifiIntegerProperty::WifiIntegerProperty(WifiController *c,
656+ const char *name,
657+ bool ro,
658+ int elements) :
659+ IntegerProperty(name, ro, elements) {
660+ mWc = c;
661+}
662+
663+WifiController::WifiStringProperty::WifiStringProperty(WifiController *c,
664+ const char *name,
665+ bool ro, int elements) :
666+ StringProperty(name, ro, elements) {
667+ mWc = c;
668+}
669+
670+WifiController::WifiEnabledProperty::WifiEnabledProperty(WifiController *c) :
671+ WifiIntegerProperty(c, "Enabled", false, 1) {
672+}
673+
674+int WifiController::WifiEnabledProperty::get(int idx, int *buffer) {
675+ *buffer = mWc->mEnabled;
676+ return 0;
677+}
678+int WifiController::WifiEnabledProperty::set(int idx, int value) {
679+ int rc = (value ? mWc->enable() : mWc->disable());
680+ if (!rc)
681+ mWc->mEnabled = value;
682+ return rc;
683+}
684+
685+WifiController::WifiScanOnlyProperty::WifiScanOnlyProperty(WifiController *c) :
686+ WifiIntegerProperty(c, "ScanOnly", false, 1) {
687+}
688+int WifiController::WifiScanOnlyProperty::get(int idx, int *buffer) {
689+ *buffer = mWc->mScanOnly;
690+ return 0;
691+}
692+int WifiController::WifiScanOnlyProperty::set(int idx, int value) {
693+ return mWc->setScanOnly(value == 1);
694+}
695+
696+WifiController::WifiAllowedChannelsProperty::WifiAllowedChannelsProperty(WifiController *c) :
697+ WifiIntegerProperty(c, "AllowedChannels", false, 1) {
698+}
699+int WifiController::WifiAllowedChannelsProperty::get(int idx, int *buffer) {
700+ *buffer = mWc->mNumAllowedChannels;
701+ return 0;
702+}
703+int WifiController::WifiAllowedChannelsProperty::set(int idx, int value) {
704+ // XXX: IMPL
705+ errno = ENOSYS;
706+ return -1;
707+}
708+
709+WifiController::WifiSupplicantStateProperty::WifiSupplicantStateProperty(WifiController *c) :
710+ WifiStringProperty(c, "SupplicantState", true, 1) {
711+}
712+int WifiController::WifiSupplicantStateProperty::get(int idx, char *buffer, size_t max) {
713+ if (!SupplicantState::toString(mWc->mSupplicantState, buffer, max))
714+ return -1;
715+ return 0;
716+}
717+
718+WifiController::WifiActiveScanProperty::WifiActiveScanProperty(WifiController *c) :
719+ WifiIntegerProperty(c, "ActiveScan", false, 1) {
720+}
721+int WifiController::WifiActiveScanProperty::get(int idx, int *buffer) {
722+ *buffer = mWc->mActiveScan;
723+ return 0;
724+}
725+int WifiController::WifiActiveScanProperty::set(int idx, int value) {
726+ return mWc->setActiveScan(value);
727+}
728+
729+WifiController::WifiInterfaceProperty::WifiInterfaceProperty(WifiController *c) :
730+ WifiStringProperty(c, "Interface", true, 1) {
731+}
732+int WifiController::WifiInterfaceProperty::get(int idx, char *buffer, size_t max) {
733+ strncpy(buffer, (mWc->getBoundInterface() ? mWc->getBoundInterface() : "none"), max);
734+ return 0;
735+}
736+
737+WifiController::WifiSearchingProperty::WifiSearchingProperty(WifiController *c) :
738+ WifiIntegerProperty(c, "Searching", true, 1) {
739+}
740+int WifiController::WifiSearchingProperty::get(int idx, int *buffer) {
741+ *buffer = mWc->mIsSupplicantSearching;
742+ return 0;
743+}
744+
745+WifiController::WifiPacketFilterProperty::WifiPacketFilterProperty(WifiController *c) :
746+ WifiIntegerProperty(c, "PacketFilter", false, 1) {
747+}
748+int WifiController::WifiPacketFilterProperty::get(int idx, int *buffer) {
749+ *buffer = mWc->mPacketFilter;
750+ return 0;
751+}
752+int WifiController::WifiPacketFilterProperty::set(int idx, int value) {
753+ return mWc->setPacketFilter(value);
754+}
755+
756+WifiController::WifiBluetoothCoexScanProperty::WifiBluetoothCoexScanProperty(WifiController *c) :
757+ WifiIntegerProperty(c, "BluetoothCoexScan", false, 1) {
758+}
759+int WifiController::WifiBluetoothCoexScanProperty::get(int idx, int *buffer) {
760+ *buffer = mWc->mBluetoothCoexScan;
761+ return 0;
762+}
763+int WifiController::WifiBluetoothCoexScanProperty::set(int idx, int value) {
764+ return mWc->setBluetoothCoexistenceScan(value == 1);
765+}
766+
767+WifiController::WifiBluetoothCoexModeProperty::WifiBluetoothCoexModeProperty(WifiController *c) :
768+ WifiIntegerProperty(c, "BluetoothCoexMode", false, 1) {
769+}
770+int WifiController::WifiBluetoothCoexModeProperty::get(int idx, int *buffer) {
771+ *buffer = mWc->mBluetoothCoexMode;
772+ return 0;
773+}
774+int WifiController::WifiBluetoothCoexModeProperty::set(int idx, int value) {
775+ return mWc->setBluetoothCoexistenceMode(value);
776+}
777+
778+WifiController::WifiCurrentNetworkProperty::WifiCurrentNetworkProperty(WifiController *c) :
779+ WifiIntegerProperty(c, "CurrentlyConnectedNetworkId", true, 1) {
780+}
781+int WifiController::WifiCurrentNetworkProperty::get(int idx, int *buffer) {
782+ *buffer = mWc->mCurrentlyConnectedNetworkId;
783+ return 0;
784+}
785+
786+WifiController::WifiSuspendedProperty::WifiSuspendedProperty(WifiController *c) :
787+ WifiIntegerProperty(c, "Suspended", false, 1) {
788+}
789+int WifiController::WifiSuspendedProperty::get(int idx, int *buffer) {
790+ *buffer = mWc->getSuspended();
791+ return 0;
792+}
793+int WifiController::WifiSuspendedProperty::set(int idx, int value) {
794+ return mWc->setSuspend(value == 1);
795+}
796+
797+WifiController::WifiNetCountProperty::WifiNetCountProperty(WifiController *c) :
798+ WifiIntegerProperty(c, "NetCount", true, 1) {
799+}
800+int WifiController::WifiNetCountProperty::get(int idx, int *buffer) {
801+ pthread_mutex_lock(&mWc->mLock);
802+ *buffer = mWc->mSupplicant->getNetworkCount();
803+ pthread_mutex_unlock(&mWc->mLock);
804+ return 0;
805+}
806+
807+WifiController::WifiTriggerScanProperty::WifiTriggerScanProperty(WifiController *c) :
808+ WifiIntegerProperty(c, "TriggerScan", false, 1) {
809+}
810+int WifiController::WifiTriggerScanProperty::get(int idx, int *buffer) {
811+ // XXX: Need action type
812+ *buffer = 0;
813+ return 0;
814+}
815+
816+int WifiController::WifiTriggerScanProperty::set(int idx, int value) {
817+ return mWc->triggerScan();
818+}
819+
--- a/nexus/WifiController.h
+++ b/nexus/WifiController.h
@@ -23,41 +23,207 @@
2323 #include "ScanResult.h"
2424 #include "WifiNetwork.h"
2525 #include "ISupplicantEventHandler.h"
26+#include "IWifiStatusPollerHandler.h"
2627
2728 class NetInterface;
2829 class Supplicant;
29-class WifiScanner;
3030 class SupplicantAssociatingEvent;
3131 class SupplicantAssociatedEvent;
3232 class SupplicantConnectedEvent;
3333 class SupplicantScanResultsEvent;
3434 class SupplicantStateChangeEvent;
3535 class SupplicantDisconnectedEvent;
36+class WifiStatusPoller;
3637
37-class WifiController : public Controller, public ISupplicantEventHandler {
38-public:
39- static const uint32_t SCAN_ENABLE_MASK = 0x01;
40- static const uint32_t SCAN_ACTIVE_MASK = 0x02;
41- static const uint32_t SCAN_REPEAT_MASK = 0x04;
38+class WifiController : public Controller,
39+ public ISupplicantEventHandler,
40+ public IWifiStatusPollerHandler {
4241
43- static const uint32_t SCANMODE_NONE = 0;
44- static const uint32_t SCANMODE_PASSIVE_ONESHOT = SCAN_ENABLE_MASK;
45- static const uint32_t SCANMODE_PASSIVE_CONTINUOUS = SCAN_ENABLE_MASK | SCAN_REPEAT_MASK;
46- static const uint32_t SCANMODE_ACTIVE_ONESHOT = SCAN_ENABLE_MASK | SCAN_ACTIVE_MASK;
47- static const uint32_t SCANMODE_ACTIVE_CONTINUOUS = SCAN_ENABLE_MASK | SCAN_ACTIVE_MASK | SCAN_REPEAT_MASK;
42+ class WifiIntegerProperty : public IntegerProperty {
43+ protected:
44+ WifiController *mWc;
45+ public:
46+ WifiIntegerProperty(WifiController *c, const char *name, bool ro,
47+ int elements);
48+ virtual ~WifiIntegerProperty() {}
49+ virtual int set(int idx, int value) = 0;
50+ virtual int get(int idx, int *buffer) = 0;
51+ };
52+ friend class WifiController::WifiIntegerProperty;
53+
54+ class WifiStringProperty : public StringProperty {
55+ protected:
56+ WifiController *mWc;
57+ public:
58+ WifiStringProperty(WifiController *c, const char *name, bool ro,
59+ int elements);
60+ virtual ~WifiStringProperty() {}
61+ virtual int set(int idx, const char *value) = 0;
62+ virtual int get(int idx, char *buffer, size_t max) = 0;
63+ };
64+ friend class WifiController::WifiStringProperty;
65+
66+ class WifiEnabledProperty : public WifiIntegerProperty {
67+ public:
68+ WifiEnabledProperty(WifiController *c);
69+ virtual ~WifiEnabledProperty() {}
70+ int set(int idx, int value);
71+ int get(int idx, int *buffer);
72+ };
73+
74+ class WifiScanOnlyProperty : public WifiIntegerProperty {
75+ public:
76+ WifiScanOnlyProperty(WifiController *c);
77+ virtual ~WifiScanOnlyProperty() {}
78+ int set(int idx, int value);
79+ int get(int idx, int *buffer);
80+ };
81+
82+ class WifiAllowedChannelsProperty : public WifiIntegerProperty {
83+ public:
84+ WifiAllowedChannelsProperty(WifiController *c);
85+ virtual ~WifiAllowedChannelsProperty() {}
86+ int set(int idx, int value);
87+ int get(int idx, int *buffer);
88+ };
89+
90+ class WifiActiveScanProperty : public WifiIntegerProperty {
91+ public:
92+ WifiActiveScanProperty(WifiController *c);
93+ virtual ~WifiActiveScanProperty() {}
94+ int set(int idx, int value);
95+ int get(int idx, int *buffer);
96+ };
97+
98+ class WifiSearchingProperty : public WifiIntegerProperty {
99+ public:
100+ WifiSearchingProperty(WifiController *c);
101+ virtual ~WifiSearchingProperty() {}
102+ int set(int idx, int value) { return -1; }
103+ int get(int idx, int *buffer);
104+ };
105+
106+ class WifiPacketFilterProperty : public WifiIntegerProperty {
107+ public:
108+ WifiPacketFilterProperty(WifiController *c);
109+ virtual ~WifiPacketFilterProperty() {}
110+ int set(int idx, int value);
111+ int get(int idx, int *buffer);
112+ };
113+
114+ class WifiBluetoothCoexScanProperty : public WifiIntegerProperty {
115+ public:
116+ WifiBluetoothCoexScanProperty(WifiController *c);
117+ virtual ~WifiBluetoothCoexScanProperty() {}
118+ int set(int idx, int value);
119+ int get(int idx, int *buffer);
120+ };
121+
122+ class WifiBluetoothCoexModeProperty : public WifiIntegerProperty {
123+ public:
124+ WifiBluetoothCoexModeProperty(WifiController *c);
125+ virtual ~WifiBluetoothCoexModeProperty() {}
126+ int set(int idx, int value);
127+ int get(int idx, int *buffer);
128+ };
129+
130+ class WifiCurrentNetworkProperty : public WifiIntegerProperty {
131+ public:
132+ WifiCurrentNetworkProperty(WifiController *c);
133+ virtual ~WifiCurrentNetworkProperty() {}
134+ int set(int idx, int value) { return -1; }
135+ int get(int idx, int *buffer);
136+ };
137+
138+ class WifiSuspendedProperty : public WifiIntegerProperty {
139+ public:
140+ WifiSuspendedProperty(WifiController *c);
141+ virtual ~WifiSuspendedProperty() {}
142+ int set(int idx, int value);
143+ int get(int idx, int *buffer);
144+ };
145+
146+ class WifiNetCountProperty : public WifiIntegerProperty {
147+ public:
148+ WifiNetCountProperty(WifiController *c);
149+ virtual ~WifiNetCountProperty() {}
150+ int set(int idx, int value) { return -1; }
151+ int get(int idx, int *buffer);
152+ };
153+
154+ class WifiTriggerScanProperty : public WifiIntegerProperty {
155+ public:
156+ WifiTriggerScanProperty(WifiController *c);
157+ virtual ~WifiTriggerScanProperty() {}
158+ int set(int idx, int value);
159+ int get(int idx, int *buffer);
160+ };
161+
162+ class WifiSupplicantStateProperty : public WifiStringProperty {
163+ public:
164+ WifiSupplicantStateProperty(WifiController *c);
165+ virtual ~WifiSupplicantStateProperty() {}
166+ int set(int idx, const char *value) { return -1; }
167+ int get(int idx, char *buffer, size_t max);
168+ };
169+
170+ class WifiInterfaceProperty : public WifiStringProperty {
171+ public:
172+ WifiInterfaceProperty(WifiController *c);
173+ virtual ~WifiInterfaceProperty() {}
174+ int set(int idx, const char *value) { return -1; }
175+ int get(int idx, char *buffer, size_t max);
176+ };
48177
49-private:
50178 Supplicant *mSupplicant;
51179 char mModulePath[255];
52180 char mModuleName[64];
53181 char mModuleArgs[255];
54182
55- uint32_t mCurrentScanMode;
56- WifiScanner *mScanner;
57183 int mSupplicantState;
184+ bool mActiveScan;
185+ bool mScanOnly;
186+ bool mPacketFilter;
187+ bool mBluetoothCoexScan;
188+ int mBluetoothCoexMode;
189+ int mCurrentlyConnectedNetworkId;
190+ bool mSuspended;
191+ int mLastRssi;
192+ int mRssiEventThreshold;
193+ int mLastLinkSpeed;
194+ int mNumAllowedChannels;
58195
59196 ScanResultCollection *mLatestScanResults;
60197 pthread_mutex_t mLatestScanResultsLock;
198+ pthread_mutex_t mLock;
199+ WifiStatusPoller *mStatusPoller;
200+
201+ struct {
202+ WifiEnabledProperty *propEnabled;
203+ WifiScanOnlyProperty *propScanOnly;
204+ WifiAllowedChannelsProperty *propAllowedChannels;
205+ IntegerPropertyHelper *propRssiEventThreshold;
206+ } mStaticProperties;
207+
208+ struct {
209+ WifiActiveScanProperty *propActiveScan;
210+ WifiSearchingProperty *propSearching;
211+ WifiPacketFilterProperty *propPacketFilter;
212+ WifiBluetoothCoexScanProperty *propBluetoothCoexScan;
213+ WifiBluetoothCoexModeProperty *propBluetoothCoexMode;
214+ WifiCurrentNetworkProperty *propCurrentNetwork;
215+ IntegerPropertyHelper *propRssi;
216+ IntegerPropertyHelper *propLinkSpeed;
217+ WifiSuspendedProperty *propSuspended;
218+ WifiNetCountProperty *propNetCount;
219+ WifiSupplicantStateProperty *propSupplicantState;
220+ WifiInterfaceProperty *propInterface;
221+ WifiTriggerScanProperty *propTriggerScan;
222+ } mDynamicProperties;
223+
224+ // True if supplicant is currently searching for a network
225+ bool mIsSupplicantSearching;
226+ int mNumScanResultsSinceLastStateChange;
61227
62228 bool mEnabled;
63229
@@ -72,9 +238,6 @@ public:
72238 int removeNetwork(int networkId);
73239 WifiNetworkCollection *createNetworkList();
74240
75- virtual int set(const char *name, const char *value);
76- virtual const char *get(const char *name, char *buffer, size_t maxlen);
77-
78241 ScanResultCollection *createScanResults();
79242
80243 char *getModulePath() { return mModulePath; }
@@ -94,18 +257,25 @@ protected:
94257
95258 private:
96259 void sendStatusBroadcast(const char *msg);
97- int setScanMode(uint32_t mode);
260+ int setActiveScan(bool active);
261+ int triggerScan();
98262 int enable();
99263 int disable();
264+ int setSuspend(bool suspend);
265+ bool getSuspended();
266+ int setBluetoothCoexistenceScan(bool enable);
267+ int setBluetoothCoexistenceMode(int mode);
268+ int setPacketFilter(bool enable);
269+ int setScanOnly(bool scanOnly);
100270
101271 // 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);
272+ void onAssociatingEvent(SupplicantAssociatingEvent *evt);
273+ void onAssociatedEvent(SupplicantAssociatedEvent *evt);
274+ void onConnectedEvent(SupplicantConnectedEvent *evt);
275+ void onScanResultsEvent(SupplicantScanResultsEvent *evt);
276+ void onStateChangeEvent(SupplicantStateChangeEvent *evt);
277+ void onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt);
278+ void onDisconnectedEvent(SupplicantDisconnectedEvent *evt);
109279 #if 0
110280 virtual void onTerminatingEvent(SupplicantEvent *evt);
111281 virtual void onPasswordChangedEvent(SupplicantEvent *evt);
@@ -118,6 +288,9 @@ private:
118288 virtual void onDriverStateEvent(SupplicantEvent *evt);
119289 #endif
120290
291+ void onStatusPollInterval();
292+
293+ int verifyNotSuspended();
121294 };
122295
123296 #endif
--- a/nexus/WifiNetwork.cpp
+++ b/nexus/WifiNetwork.cpp
@@ -26,17 +26,7 @@
2626 #include "WifiNetwork.h"
2727 #include "Supplicant.h"
2828 #include "WifiController.h"
29-#include "InterfaceConfig.h"
30-
31-const char *WifiNetwork::PropertyNames[] = { "ssid", "bssid", "psk", "wepkey.1",
32- "wepkey.2", "wepkey.3", "wepkey.4",
33- "defkeyidx", "pri", "hiddenssid",
34- "AllowedKeyManagement",
35- "AllowedProtocols",
36- "AllowedAuthAlgorithms",
37- "AllowedPairwiseCiphers",
38- "AllowedGroupCiphers",
39- "enabled", '\0' };
29+
4030 WifiNetwork::WifiNetwork() {
4131 // This is private to restrict copy constructors
4232 }
@@ -76,11 +66,11 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data)
7666 mDefaultKeyIndex = -1;
7767 mPriority = -1;
7868 mHiddenSsid = NULL;
79- mAllowedKeyManagement = KeyManagementMask::UNKNOWN;
80- mAllowedProtocols = 0;
81- mAllowedAuthAlgorithms = 0;
82- mAllowedPairwiseCiphers = 0;
83- mAllowedGroupCiphers = 0;
69+ mKeyManagement = KeyManagementMask::UNKNOWN;
70+ mProtocols = 0;
71+ mAuthAlgorithms = 0;
72+ mPairwiseCiphers = 0;
73+ mGroupCiphers = 0;
8474 mEnabled = true;
8575
8676 if (flags && flags[0] != '\0') {
@@ -90,11 +80,8 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data)
9080 LOGW("Unsupported flags '%s'", flags);
9181 }
9282
93- char *tmp2;
94- asprintf(&tmp2, "wifi.net.%d", mNetid);
95- mIfaceCfg = new InterfaceConfig(tmp2);
96- free(tmp2);
9783 free(tmp);
84+ createProperties();
9885 }
9986
10087 WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, int networkId) {
@@ -108,17 +95,13 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, int networkId) {
10895 mDefaultKeyIndex = -1;
10996 mPriority = -1;
11097 mHiddenSsid = NULL;
111- mAllowedKeyManagement = 0;
112- mAllowedProtocols = 0;
113- mAllowedAuthAlgorithms = 0;
114- mAllowedPairwiseCiphers = 0;
115- mAllowedGroupCiphers = 0;
98+ mKeyManagement = 0;
99+ mProtocols = 0;
100+ mAuthAlgorithms = 0;
101+ mPairwiseCiphers = 0;
102+ mGroupCiphers = 0;
116103 mEnabled = false;
117-
118- char *tmp2;
119- asprintf(&tmp2, "wifi.net.%d", mNetid);
120- mIfaceCfg = new InterfaceConfig(tmp2);
121- free(tmp2);
104+ createProperties();
122105 }
123106
124107 WifiNetwork *WifiNetwork::clone() {
@@ -140,15 +123,35 @@ WifiNetwork *WifiNetwork::clone() {
140123 r->mPriority = mPriority;
141124 if (mHiddenSsid)
142125 r->mHiddenSsid = strdup(mHiddenSsid);
143- r->mAllowedKeyManagement = mAllowedKeyManagement;
144- r->mAllowedProtocols = mAllowedProtocols;
145- r->mAllowedAuthAlgorithms = mAllowedAuthAlgorithms;
146- r->mAllowedPairwiseCiphers = mAllowedPairwiseCiphers;
147- r->mAllowedGroupCiphers = mAllowedGroupCiphers;
126+ r->mKeyManagement = mKeyManagement;
127+ r->mProtocols = mProtocols;
128+ r->mAuthAlgorithms = mAuthAlgorithms;
129+ r->mPairwiseCiphers = mPairwiseCiphers;
130+ r->mGroupCiphers = mGroupCiphers;
148131 return r;
149132 }
150133
134+void WifiNetwork::createProperties() {
135+ asprintf(&mPropNamespace, "wifi.net.%d", mNetid);
136+
137+ mStaticProperties.propEnabled = new WifiNetworkEnabledProperty(this);
138+ mStaticProperties.propSsid = new WifiNetworkSsidProperty(this);
139+ mStaticProperties.propBssid = new WifiNetworkBssidProperty(this);
140+ mStaticProperties.propPsk = new WifiNetworkPskProperty(this);
141+ mStaticProperties.propWepKey = new WifiNetworkWepKeyProperty(this);
142+ mStaticProperties.propDefKeyIdx = new WifiNetworkDefaultKeyIndexProperty(this);
143+ mStaticProperties.propPriority = new WifiNetworkPriorityProperty(this);
144+ mStaticProperties.propKeyManagement = new WifiNetworkKeyManagementProperty(this);
145+ mStaticProperties.propProtocols = new WifiNetworkProtocolsProperty(this);
146+ mStaticProperties.propAuthAlgorithms = new WifiNetworkAuthAlgorithmsProperty(this);
147+ mStaticProperties.propPairwiseCiphers = new WifiNetworkPairwiseCiphersProperty(this);
148+ mStaticProperties.propGroupCiphers = new WifiNetworkGroupCiphersProperty(this);
149+ mStaticProperties.propHiddenSsid = new WifiNetworkHiddenSsidProperty(this);
150+}
151+
151152 WifiNetwork::~WifiNetwork() {
153+ if (mPropNamespace)
154+ free(mPropNamespace);
152155 if (mSsid)
153156 free(mSsid);
154157 if (mBssid)
@@ -162,13 +165,26 @@ WifiNetwork::~WifiNetwork() {
162165
163166 if (mHiddenSsid)
164167 free(mHiddenSsid);
165- if (mIfaceCfg)
166- delete(mIfaceCfg);
168+
169+ delete mStaticProperties.propEnabled;
170+ delete mStaticProperties.propSsid;
171+ delete mStaticProperties.propBssid;
172+ delete mStaticProperties.propPsk;
173+ delete mStaticProperties.propWepKey;
174+ delete mStaticProperties.propDefKeyIdx;
175+ delete mStaticProperties.propPriority;
176+ delete mStaticProperties.propKeyManagement;
177+ delete mStaticProperties.propProtocols;
178+ delete mStaticProperties.propAuthAlgorithms;
179+ delete mStaticProperties.propPairwiseCiphers;
180+ delete mStaticProperties.propGroupCiphers;
181+ delete mStaticProperties.propHiddenSsid;
167182 }
168183
169184 int WifiNetwork::refresh() {
170185 char buffer[255];
171186 size_t len;
187+ uint32_t mask;
172188
173189 len = sizeof(buffer);
174190 if (mSuppl->getNetworkVar(mNetid, "psk", buffer, len))
@@ -198,46 +214,47 @@ int WifiNetwork::refresh() {
198214
199215 len = sizeof(buffer);
200216 if (mSuppl->getNetworkVar(mNetid, "key_mgmt", buffer, len)) {
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);
217+ if (WifiNetwork::parseKeyManagementMask(buffer, &mask)) {
218+ LOGE("Error parsing key_mgmt (%s)", strerror(errno));
219+ } else {
220+ mKeyManagement = mask;
221+ }
221222 }
222223
223224 len = sizeof(buffer);
224225 if (mSuppl->getNetworkVar(mNetid, "proto", buffer, len)) {
225- // TODO
226+ if (WifiNetwork::parseProtocolsMask(buffer, &mask)) {
227+ LOGE("Error parsing proto (%s)", strerror(errno));
228+ } else {
229+ mProtocols = mask;
230+ }
226231 }
227232
228233 len = sizeof(buffer);
229234 if (mSuppl->getNetworkVar(mNetid, "auth_alg", buffer, len)) {
230- // TODO
235+ if (WifiNetwork::parseAuthAlgorithmsMask(buffer, &mask)) {
236+ LOGE("Error parsing auth_alg (%s)", strerror(errno));
237+ } else {
238+ mAuthAlgorithms = mask;
239+ }
231240 }
232241
233242 len = sizeof(buffer);
234243 if (mSuppl->getNetworkVar(mNetid, "pairwise", buffer, len)) {
235- // TODO
244+ if (WifiNetwork::parsePairwiseCiphersMask(buffer, &mask)) {
245+ LOGE("Error parsing pairwise (%s)", strerror(errno));
246+ } else {
247+ mPairwiseCiphers = mask;
248+ }
236249 }
237250
238251 len = sizeof(buffer);
239252 if (mSuppl->getNetworkVar(mNetid, "group", buffer, len)) {
240- // TODO
253+ if (WifiNetwork::parseGroupCiphersMask(buffer, &mask)) {
254+ LOGE("Error parsing group (%s)", strerror(errno));
255+ } else {
256+ mGroupCiphers = mask;
257+ }
241258 }
242259
243260 return 0;
@@ -246,179 +263,10 @@ out_err:
246263 return -1;
247264 }
248265
249-int WifiNetwork::set(const char *name, const char *value) {
250- char *n_tmp = strdup(name + strlen("wifi.net."));
251- char *n_next = n_tmp;
252- char *n_local;
253- char *n_rest;
254- int rc = 0;
255-
256- if (!strsep(&n_next, ".")) // skip net id
257- goto out_inval;
258-
259- if (!(n_local = strsep(&n_next, ".")))
260- goto out_inval;
261-
262- n_rest = n_next;
263-
264-// LOGD("set(): var '%s'(%s / %s) = %s", name, n_local, n_rest, value);
265- if (!strcasecmp(n_local, "enabled"))
266- rc = setEnabled(atoi(value));
267- else if (!strcmp(n_local, "ssid"))
268- rc = setSsid(value);
269- else if (!strcasecmp(n_local, "bssid"))
270- rc = setBssid(value);
271- else if (!strcasecmp(n_local, "psk"))
272- rc = setPsk(value);
273- else if (!strcasecmp(n_local, "wepkey"))
274- rc = setWepKey(atoi(n_rest) -1, value);
275- else if (!strcasecmp(n_local, "defkeyidx"))
276- rc = setDefaultKeyIndex(atoi(value));
277- else if (!strcasecmp(n_local, "pri"))
278- rc = setPriority(atoi(value));
279- else if (!strcasecmp(n_local, "hiddenssid"))
280- rc = setHiddenSsid(value);
281- else if (!strcasecmp(n_local, "AllowedKeyManagement")) {
282- uint32_t mask = 0;
283- bool none = false;
284- char *v_tmp = strdup(value);
285- char *v_next = v_tmp;
286- char *v_token;
287-
288- while((v_token = strsep(&v_next, " "))) {
289- if (!strcasecmp(v_token, "NONE")) {
290- mask = KeyManagementMask::NONE;
291- none = true;
292- } else if (!none) {
293- if (!strcasecmp(v_token, "WPA_PSK"))
294- mask |= KeyManagementMask::WPA_PSK;
295- else if (!strcasecmp(v_token, "WPA_EAP"))
296- mask |= KeyManagementMask::WPA_EAP;
297- else if (!strcasecmp(v_token, "IEEE8021X"))
298- mask |= KeyManagementMask::IEEE8021X;
299- else {
300- errno = EINVAL;
301- rc = -1;
302- free(v_tmp);
303- goto out;
304- }
305- } else {
306- errno = EINVAL;
307- rc = -1;
308- free(v_tmp);
309- goto out;
310- }
311- }
312- free(v_tmp);
313- } else if (!strcasecmp(n_local, "AllowedProtocols")) {
314- // TODO
315- } else if (!strcasecmp(n_local, "AllowedPairwiseCiphers")) {
316- // TODO
317- } else if (!strcasecmp(n_local, "AllowedAuthAlgorithms")) {
318- // TODO
319- } else if (!strcasecmp(n_local, "AllowedGroupCiphers")) {
320- // TODO
321- } else {
322- errno = ENOENT;
323- free(n_tmp);
324- return -1;
325- }
326-
327-out:
328- free(n_tmp);
329- return rc;
330-
331-out_inval:
332- errno = EINVAL;
333- free(n_tmp);
334- return -1;
335-}
336-
337-const char *WifiNetwork::get(const char *name, char *buffer, size_t maxsize) {
338- char *n_tmp = strdup(name + strlen("wifi.net."));
339- char *n_next = n_tmp;
340- char *n_local;
341- char fc[64];
342- char rc[128];
343-
344- if (!strsep(&n_next, ".")) // skip net id
345- goto out_inval;
346-
347- if (!(n_local = strsep(&n_next, ".")))
348- goto out_inval;
349-
350-
351- strncpy(fc, n_local, sizeof(fc));
352- rc[0] = '\0';
353- if (n_next)
354- strncpy(rc, n_next, sizeof(rc));
355-
356- free(n_tmp);
357-
358- if (!strcasecmp(fc, "enabled"))
359- snprintf(buffer, maxsize, "%d", getEnabled());
360- else if (!strcasecmp(fc, "ssid")) {
361- strncpy(buffer,
362- getSsid() ? getSsid() : "none",
363- maxsize);
364- } else if (!strcasecmp(fc, "bssid")) {
365- strncpy(buffer,
366- getBssid() ? getBssid() : "none",
367- maxsize);
368- } else if (!strcasecmp(fc, "psk")) {
369- strncpy(buffer,
370- getPsk() ? getPsk() : "none",
371- maxsize);
372- } else if (!strcasecmp(fc, "wepkey")) {
373- strncpy(buffer,
374- getWepKey(atoi(rc)-1) ? getWepKey(atoi(rc)-1) : "none",
375- maxsize);
376- } else if (!strcasecmp(fc, "defkeyidx"))
377- snprintf(buffer, maxsize, "%d", getDefaultKeyIndex());
378- else if (!strcasecmp(fc, "pri"))
379- snprintf(buffer, maxsize, "%d", getPriority());
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")) {
403- strncpy(buffer,
404- getHiddenSsid() ? getHiddenSsid() : "none",
405- maxsize);
406- } else {
407- strncpy(buffer, "(internal error)", maxsize);
408- errno = ENOENT;
409- return NULL;
410- }
411-
412- return buffer;
413-
414-out_inval:
415- errno = EINVAL;
416- free(n_tmp);
417- return NULL;
418-}
419-
420266 int WifiNetwork::setSsid(const char *ssid) {
421- if (mSuppl->setNetworkVar(mNetid, "ssid", ssid))
267+ char tmp[255];
268+ snprintf(tmp, sizeof(tmp), "\"%s\"", ssid);
269+ if (mSuppl->setNetworkVar(mNetid, "ssid", tmp))
422270 return -1;
423271 if (mSsid)
424272 free(mSsid);
@@ -436,7 +284,9 @@ int WifiNetwork::setBssid(const char *bssid) {
436284 }
437285
438286 int WifiNetwork::setPsk(const char *psk) {
439- if (mSuppl->setNetworkVar(mNetid, "psk", psk))
287+ char tmp[255];
288+ snprintf(tmp, sizeof(tmp), "\"%s\"", psk);
289+ if (mSuppl->setNetworkVar(mNetid, "psk", tmp))
440290 return -1;
441291
442292 if (mPsk)
@@ -491,28 +341,34 @@ int WifiNetwork::setHiddenSsid(const char *ssid) {
491341 return 0;
492342 }
493343
494-int WifiNetwork::setAllowedKeyManagement(uint32_t mask) {
495- char accum[255];
344+int WifiNetwork::setKeyManagement(uint32_t mask) {
345+ char accum[64] = {'\0'};
496346
497347 if (mask == KeyManagementMask::NONE)
498348 strcpy(accum, "NONE");
499349 else {
500- if (mask & KeyManagementMask::WPA_PSK)
501- strcat(accum, "WPA_PSK ");
502- if (mask & KeyManagementMask::WPA_EAP)
503- strcat(accum, "WPA_EAP ");
504- if (mask & KeyManagementMask::IEEE8021X)
505- strcat(accum, "IEEE8021X ");
350+ if (mask & KeyManagementMask::WPA_PSK)
351+ strcat(accum, "WPA-PSK");
352+ if (mask & KeyManagementMask::WPA_EAP) {
353+ if (accum[0] != '\0')
354+ strcat(accum, " ");
355+ strcat(accum, "WPA-EAP");
356+ }
357+ if (mask & KeyManagementMask::IEEE8021X) {
358+ if (accum[0] != '\0')
359+ strcat(accum, " ");
360+ strcat(accum, "IEEE8021X");
361+ }
506362 }
507363
508364 if (mSuppl->setNetworkVar(mNetid, "key_mgmt", accum))
509365 return -1;
510- mAllowedKeyManagement = mask;
366+ mKeyManagement = mask;
511367 return 0;
512368 }
513369
514-int WifiNetwork::setAllowedProtocols(uint32_t mask) {
515- char accum[255];
370+int WifiNetwork::setProtocols(uint32_t mask) {
371+ char accum[64];
516372
517373 accum[0] = '\0';
518374
@@ -524,15 +380,18 @@ int WifiNetwork::setAllowedProtocols(uint32_t mask) {
524380
525381 if (mSuppl->setNetworkVar(mNetid, "proto", accum))
526382 return -1;
527- mAllowedProtocols = mask;
383+ mProtocols = mask;
528384 return 0;
529385 }
530386
531-int WifiNetwork::setAllowedAuthAlgorithms(uint32_t mask) {
532- char accum[255];
387+int WifiNetwork::setAuthAlgorithms(uint32_t mask) {
388+ char accum[64];
533389
534390 accum[0] = '\0';
535391
392+ if (mask == 0)
393+ strcpy(accum, "");
394+
536395 if (mask & AuthenticationAlgorithmMask::OPEN)
537396 strcpy(accum, "OPEN ");
538397
@@ -545,12 +404,14 @@ int WifiNetwork::setAllowedAuthAlgorithms(uint32_t mask) {
545404 if (mSuppl->setNetworkVar(mNetid, "auth_alg", accum))
546405 return -1;
547406
548- mAllowedAuthAlgorithms = mask;
407+ mAuthAlgorithms = mask;
549408 return 0;
550409 }
551410
552-int WifiNetwork::setAllowedPairwiseCiphers(uint32_t mask) {
553- char accum[255];
411+int WifiNetwork::setPairwiseCiphers(uint32_t mask) {
412+ char accum[64];
413+
414+ accum[0] = '\0';
554415
555416 if (mask == PairwiseCiphersMask::NONE)
556417 strcpy(accum, "NONE");
@@ -564,12 +425,14 @@ int WifiNetwork::setAllowedPairwiseCiphers(uint32_t mask) {
564425 if (mSuppl->setNetworkVar(mNetid, "pairwise", accum))
565426 return -1;
566427
567- mAllowedPairwiseCiphers = mask;
428+ mPairwiseCiphers = mask;
568429 return 0;
569430 }
570431
571-int WifiNetwork::setAllowedGroupCiphers(uint32_t mask) {
572- char accum[255];
432+int WifiNetwork::setGroupCiphers(uint32_t mask) {
433+ char accum[64];
434+
435+ accum[0] = '\0';
573436
574437 if (mask & GroupCiphersMask::WEP40)
575438 strcat(accum, "WEP40 ");
@@ -582,7 +445,7 @@ int WifiNetwork::setAllowedGroupCiphers(uint32_t mask) {
582445
583446 if (mSuppl->setNetworkVar(mNetid, "group", accum))
584447 return -1;
585- mAllowedGroupCiphers = mask;
448+ mGroupCiphers = mask;
586449 return 0;
587450 }
588451
@@ -594,7 +457,7 @@ int WifiNetwork::setEnabled(bool enabled) {
594457 errno = EAGAIN;
595458 return -1;
596459 }
597- if (getAllowedKeyManagement() == KeyManagementMask::UNKNOWN) {
460+ if (getKeyManagement() == KeyManagementMask::UNKNOWN) {
598461 LOGE("Cannot enable network when KeyManagement is not set");
599462 errno = EAGAIN;
600463 return -1;
@@ -608,29 +471,500 @@ int WifiNetwork::setEnabled(bool enabled) {
608471 return 0;
609472 }
610473
611-int WifiNetwork::registerProperties() {
612- for (const char **p = WifiNetwork::PropertyNames; *p != '\0'; p++) {
613- char *tmp;
614- asprintf(&tmp, "wifi.net.%d.%s", mNetid, *p);
474+int WifiNetwork::attachProperties(PropertyManager *pm, const char *nsName) {
475+ pm->attachProperty(nsName, mStaticProperties.propSsid);
476+ pm->attachProperty(nsName, mStaticProperties.propBssid);
477+ pm->attachProperty(nsName, mStaticProperties.propPsk);
478+ pm->attachProperty(nsName, mStaticProperties.propWepKey);
479+ pm->attachProperty(nsName, mStaticProperties.propDefKeyIdx);
480+ pm->attachProperty(nsName, mStaticProperties.propPriority);
481+ pm->attachProperty(nsName, mStaticProperties.propKeyManagement);
482+ pm->attachProperty(nsName, mStaticProperties.propProtocols);
483+ pm->attachProperty(nsName, mStaticProperties.propAuthAlgorithms);
484+ pm->attachProperty(nsName, mStaticProperties.propPairwiseCiphers);
485+ pm->attachProperty(nsName, mStaticProperties.propGroupCiphers);
486+ pm->attachProperty(nsName, mStaticProperties.propHiddenSsid);
487+ pm->attachProperty(nsName, mStaticProperties.propEnabled);
488+ return 0;
489+}
490+
491+int WifiNetwork::detachProperties(PropertyManager *pm, const char *nsName) {
492+ pm->detachProperty(nsName, mStaticProperties.propEnabled);
493+ pm->detachProperty(nsName, mStaticProperties.propSsid);
494+ pm->detachProperty(nsName, mStaticProperties.propBssid);
495+ pm->detachProperty(nsName, mStaticProperties.propPsk);
496+ pm->detachProperty(nsName, mStaticProperties.propWepKey);
497+ pm->detachProperty(nsName, mStaticProperties.propDefKeyIdx);
498+ pm->detachProperty(nsName, mStaticProperties.propPriority);
499+ pm->detachProperty(nsName, mStaticProperties.propKeyManagement);
500+ pm->detachProperty(nsName, mStaticProperties.propProtocols);
501+ pm->detachProperty(nsName, mStaticProperties.propAuthAlgorithms);
502+ pm->detachProperty(nsName, mStaticProperties.propPairwiseCiphers);
503+ pm->detachProperty(nsName, mStaticProperties.propGroupCiphers);
504+ pm->detachProperty(nsName, mStaticProperties.propHiddenSsid);
505+ return 0;
506+}
507+
508+int WifiNetwork::parseKeyManagementMask(const char *buffer, uint32_t *mask) {
509+ bool none = false;
510+ char *v_tmp = strdup(buffer);
511+ char *v_next = v_tmp;
512+ char *v_token;
513+
514+// LOGD("parseKeyManagementMask(%s)", buffer);
515+ *mask = 0;
516+
517+ while((v_token = strsep(&v_next, " "))) {
518+ if (!strcasecmp(v_token, "NONE")) {
519+ *mask = KeyManagementMask::NONE;
520+ none = true;
521+ } else if (!none) {
522+ if (!strcasecmp(v_token, "WPA-PSK"))
523+ *mask |= KeyManagementMask::WPA_PSK;
524+ else if (!strcasecmp(v_token, "WPA-EAP"))
525+ *mask |= KeyManagementMask::WPA_EAP;
526+ else if (!strcasecmp(v_token, "IEEE8021X"))
527+ *mask |= KeyManagementMask::IEEE8021X;
528+ else {
529+ LOGW("Invalid KeyManagementMask value '%s'", v_token);
530+ errno = EINVAL;
531+ free(v_tmp);
532+ return -1;
533+ }
534+ } else {
535+ LOGW("KeyManagementMask value '%s' when NONE", v_token);
536+ errno = EINVAL;
537+ free(v_tmp);
538+ return -1;
539+ }
540+ }
541+ free(v_tmp);
542+ return 0;
543+}
544+
545+int WifiNetwork::parseProtocolsMask(const char *buffer, uint32_t *mask) {
546+ bool none = false;
547+ char *v_tmp = strdup(buffer);
548+ char *v_next = v_tmp;
549+ char *v_token;
550+
551+// LOGD("parseProtocolsMask(%s)", buffer);
552+ *mask = 0;
553+ while((v_token = strsep(&v_next, " "))) {
554+ if (!strcasecmp(v_token, "WPA"))
555+ *mask |= SecurityProtocolMask::WPA;
556+ else if (!strcasecmp(v_token, "RSN"))
557+ *mask |= SecurityProtocolMask::RSN;
558+ else {
559+ LOGW("Invalid ProtocolsMask value '%s'", v_token);
560+ errno = EINVAL;
561+ free(v_tmp);
562+ return -1;
563+ }
564+ }
565+
566+ free(v_tmp);
567+ return 0;
568+}
615569
616- if (NetworkManager::Instance()->getPropMngr()->registerProperty(tmp,
617- this)) {
618- free(tmp);
570+int WifiNetwork::parseAuthAlgorithmsMask(const char *buffer, uint32_t *mask) {
571+ bool none = false;
572+ char *v_tmp = strdup(buffer);
573+ char *v_next = v_tmp;
574+ char *v_token;
575+
576+// LOGD("parseAuthAlgorithmsMask(%s)", buffer);
577+
578+ *mask = 0;
579+ if (buffer[0] == '\0')
580+ return 0;
581+
582+ while((v_token = strsep(&v_next, " "))) {
583+ if (!strcasecmp(v_token, "OPEN"))
584+ *mask |= AuthenticationAlgorithmMask::OPEN;
585+ else if (!strcasecmp(v_token, "SHARED"))
586+ *mask |= AuthenticationAlgorithmMask::SHARED;
587+ else if (!strcasecmp(v_token, "LEAP"))
588+ *mask |= AuthenticationAlgorithmMask::LEAP;
589+ else {
590+ LOGW("Invalid AuthAlgorithmsMask value '%s'", v_token);
591+ errno = EINVAL;
592+ free(v_tmp);
619593 return -1;
620594 }
621- free(tmp);
622595 }
596+ free(v_tmp);
623597 return 0;
624598 }
625599
626-int WifiNetwork::unregisterProperties() {
627- for (const char **p = WifiNetwork::PropertyNames; *p != '\0'; p++) {
628- char *tmp;
629- asprintf(&tmp, "wifi.net.%d.%s", mNetid, *p);
600+int WifiNetwork::parsePairwiseCiphersMask(const char *buffer, uint32_t *mask) {
601+ bool none = false;
602+ char *v_tmp = strdup(buffer);
603+ char *v_next = v_tmp;
604+ char *v_token;
605+
606+// LOGD("parsePairwiseCiphersMask(%s)", buffer);
607+
608+ *mask = 0;
609+ while((v_token = strsep(&v_next, " "))) {
610+ if (!strcasecmp(v_token, "NONE")) {
611+ *mask = PairwiseCiphersMask::NONE;
612+ none = true;
613+ } else if (!none) {
614+ if (!strcasecmp(v_token, "TKIP"))
615+ *mask |= PairwiseCiphersMask::TKIP;
616+ else if (!strcasecmp(v_token, "CCMP"))
617+ *mask |= PairwiseCiphersMask::CCMP;
618+ else {
619+ LOGW("PairwiseCiphersMask value '%s' when NONE", v_token);
620+ errno = EINVAL;
621+ free(v_tmp);
622+ return -1;
623+ }
624+ } else {
625+ LOGW("Invalid PairwiseCiphersMask value '%s'", v_token);
626+ errno = EINVAL;
627+ free(v_tmp);
628+ return -1;
629+ }
630+ }
631+ free(v_tmp);
632+ return 0;
633+}
630634
631- if (NetworkManager::Instance()->getPropMngr()->unregisterProperty(tmp))
632- LOGW("Unable to remove property '%s' (%s)", tmp, strerror(errno));
633- free(tmp);
635+int WifiNetwork::parseGroupCiphersMask(const char *buffer, uint32_t *mask) {
636+ bool none = false;
637+ char *v_tmp = strdup(buffer);
638+ char *v_next = v_tmp;
639+ char *v_token;
640+
641+// LOGD("parseGroupCiphersMask(%s)", buffer);
642+
643+ *mask = 0;
644+ while((v_token = strsep(&v_next, " "))) {
645+ if (!strcasecmp(v_token, "WEP40"))
646+ *mask |= GroupCiphersMask::WEP40;
647+ else if (!strcasecmp(v_token, "WEP104"))
648+ *mask |= GroupCiphersMask::WEP104;
649+ else if (!strcasecmp(v_token, "TKIP"))
650+ *mask |= GroupCiphersMask::TKIP;
651+ else if (!strcasecmp(v_token, "CCMP"))
652+ *mask |= GroupCiphersMask::CCMP;
653+ else {
654+ LOGW("Invalid GroupCiphersMask value '%s'", v_token);
655+ errno = EINVAL;
656+ free(v_tmp);
657+ return -1;
658+ }
634659 }
660+ free(v_tmp);
661+ return 0;
662+}
663+
664+WifiNetwork::WifiNetworkIntegerProperty::WifiNetworkIntegerProperty(WifiNetwork *wn,
665+ const char *name,
666+ bool ro,
667+ int elements) :
668+ IntegerProperty(name, ro, elements) {
669+ mWn = wn;
670+}
671+
672+WifiNetwork::WifiNetworkStringProperty::WifiNetworkStringProperty(WifiNetwork *wn,
673+ const char *name,
674+ bool ro, int elements) :
675+ StringProperty(name, ro, elements) {
676+ mWn = wn;
677+}
678+
679+WifiNetwork::WifiNetworkEnabledProperty::WifiNetworkEnabledProperty(WifiNetwork *wn) :
680+ WifiNetworkIntegerProperty(wn, "Enabled", false, 1) {
681+}
682+
683+int WifiNetwork::WifiNetworkEnabledProperty::get(int idx, int *buffer) {
684+ *buffer = mWn->mEnabled;
685+ return 0;
686+}
687+int WifiNetwork::WifiNetworkEnabledProperty::set(int idx, int value) {
688+ return mWn->setEnabled(value == 1);
689+}
690+
691+WifiNetwork::WifiNetworkSsidProperty::WifiNetworkSsidProperty(WifiNetwork *wn) :
692+ WifiNetworkStringProperty(wn, "Ssid", false, 1) {
693+}
694+
695+int WifiNetwork::WifiNetworkSsidProperty::get(int idx, char *buffer, size_t max) {
696+ strncpy(buffer,
697+ mWn->getSsid() ? mWn->getSsid() : "none",
698+ max);
699+ return 0;
700+}
701+int WifiNetwork::WifiNetworkSsidProperty::set(int idx, const char *value) {
702+ return mWn->setSsid(value);
703+}
704+
705+WifiNetwork::WifiNetworkBssidProperty::WifiNetworkBssidProperty(WifiNetwork *wn) :
706+ WifiNetworkStringProperty(wn, "Bssid", false, 1) {
707+}
708+int WifiNetwork::WifiNetworkBssidProperty::get(int idx, char *buffer, size_t max) {
709+ strncpy(buffer,
710+ mWn->getBssid() ? mWn->getBssid() : "none",
711+ max);
635712 return 0;
636713 }
714+int WifiNetwork::WifiNetworkBssidProperty::set(int idx, const char *value) {
715+ return mWn->setBssid(value);
716+}
717+
718+WifiNetwork::WifiNetworkPskProperty::WifiNetworkPskProperty(WifiNetwork *wn) :
719+ WifiNetworkStringProperty(wn, "Psk", false, 1) {
720+}
721+int WifiNetwork::WifiNetworkPskProperty::get(int idx, char *buffer, size_t max) {
722+ strncpy(buffer,
723+ mWn->getPsk() ? mWn->getPsk() : "none",
724+ max);
725+ return 0;
726+}
727+int WifiNetwork::WifiNetworkPskProperty::set(int idx, const char *value) {
728+ return mWn->setPsk(value);
729+}
730+
731+WifiNetwork::WifiNetworkWepKeyProperty::WifiNetworkWepKeyProperty(WifiNetwork *wn) :
732+ WifiNetworkStringProperty(wn, "WepKey", false, 4) {
733+}
734+
735+int WifiNetwork::WifiNetworkWepKeyProperty::get(int idx, char *buffer, size_t max) {
736+ const char *key = mWn->getWepKey(idx);
737+
738+ strncpy(buffer, (key ? key : "none"), max);
739+ return 0;
740+}
741+int WifiNetwork::WifiNetworkWepKeyProperty::set(int idx, const char *value) {
742+ return mWn->setWepKey(idx, value);
743+}
744+
745+WifiNetwork::WifiNetworkDefaultKeyIndexProperty::WifiNetworkDefaultKeyIndexProperty(WifiNetwork *wn) :
746+ WifiNetworkIntegerProperty(wn, "DefaultKeyIndex", false, 1) {
747+}
748+int WifiNetwork::WifiNetworkDefaultKeyIndexProperty::get(int idx, int *buffer) {
749+ *buffer = mWn->getDefaultKeyIndex();
750+ return 0;
751+}
752+int WifiNetwork::WifiNetworkDefaultKeyIndexProperty::set(int idx, int value) {
753+ return mWn->setDefaultKeyIndex(value);
754+}
755+
756+WifiNetwork::WifiNetworkPriorityProperty::WifiNetworkPriorityProperty(WifiNetwork *wn) :
757+ WifiNetworkIntegerProperty(wn, "Priority", false, 1) {
758+}
759+int WifiNetwork::WifiNetworkPriorityProperty::get(int idx, int *buffer) {
760+ *buffer = mWn->getPriority();
761+ return 0;
762+}
763+int WifiNetwork::WifiNetworkPriorityProperty::set(int idx, int value) {
764+ return mWn->setPriority(value);
765+}
766+
767+WifiNetwork::WifiNetworkKeyManagementProperty::WifiNetworkKeyManagementProperty(WifiNetwork *wn) :
768+ WifiNetworkStringProperty(wn, "KeyManagement", false, 1) {
769+}
770+int WifiNetwork::WifiNetworkKeyManagementProperty::get(int idx, char *buffer, size_t max) {
771+
772+ if (mWn->getKeyManagement() == KeyManagementMask::NONE)
773+ strncpy(buffer, "NONE", max);
774+ else {
775+ char tmp[80] = { '\0' };
776+
777+ if (mWn->getKeyManagement() & KeyManagementMask::WPA_PSK)
778+ strcat(tmp, "WPA-PSK");
779+ if (mWn->getKeyManagement() & KeyManagementMask::WPA_EAP) {
780+ if (tmp[0] != '\0')
781+ strcat(tmp, " ");
782+ strcat(tmp, "WPA-EAP");
783+ }
784+ if (mWn->getKeyManagement() & KeyManagementMask::IEEE8021X) {
785+ if (tmp[0] != '\0')
786+ strcat(tmp, " ");
787+ strcat(tmp, "IEEE8021X");
788+ }
789+ if (tmp[0] == '\0') {
790+ strncpy(buffer, "(internal error)", max);
791+ errno = ENOENT;
792+ return -1;
793+ }
794+ if (tmp[strlen(tmp)] == ' ')
795+ tmp[strlen(tmp)] = '\0';
796+
797+ strncpy(buffer, tmp, max);
798+ }
799+ return 0;
800+}
801+int WifiNetwork::WifiNetworkKeyManagementProperty::set(int idx, const char *value) {
802+ uint32_t mask;
803+ if (mWn->parseKeyManagementMask(value, &mask))
804+ return -1;
805+ return mWn->setKeyManagement(mask);
806+}
807+
808+WifiNetwork::WifiNetworkProtocolsProperty::WifiNetworkProtocolsProperty(WifiNetwork *wn) :
809+ WifiNetworkStringProperty(wn, "Protocols", false, 1) {
810+}
811+int WifiNetwork::WifiNetworkProtocolsProperty::get(int idx, char *buffer, size_t max) {
812+ char tmp[80] = { '\0' };
813+
814+ if (mWn->getProtocols() & SecurityProtocolMask::WPA)
815+ strcat(tmp, "WPA");
816+ if (mWn->getProtocols() & SecurityProtocolMask::RSN) {
817+ if (tmp[0] != '\0')
818+ strcat(tmp, " ");
819+ strcat(tmp, "RSN");
820+ }
821+
822+ if (tmp[0] == '\0') {
823+ strncpy(buffer, "(internal error)", max);
824+ errno = ENOENT;
825+ return NULL;
826+ }
827+ if (tmp[strlen(tmp)] == ' ')
828+ tmp[strlen(tmp)] = '\0';
829+
830+ strncpy(buffer, tmp, max);
831+ return 0;
832+}
833+int WifiNetwork::WifiNetworkProtocolsProperty::set(int idx, const char *value) {
834+ uint32_t mask;
835+ if (mWn->parseProtocolsMask(value, &mask))
836+ return -1;
837+ return mWn->setProtocols(mask);
838+}
839+
840+WifiNetwork::WifiNetworkAuthAlgorithmsProperty::WifiNetworkAuthAlgorithmsProperty(WifiNetwork *wn) :
841+ WifiNetworkStringProperty(wn, "AuthAlgorithms", false, 1) {
842+}
843+int WifiNetwork::WifiNetworkAuthAlgorithmsProperty::get(int idx, char *buffer, size_t max) {
844+ char tmp[80] = { '\0' };
845+
846+ if (mWn->getAuthAlgorithms() == 0) {
847+ strncpy(buffer, "NONE", max);
848+ return 0;
849+ }
850+
851+ if (mWn->getAuthAlgorithms() & AuthenticationAlgorithmMask::OPEN)
852+ strcat(tmp, "OPEN");
853+ if (mWn->getAuthAlgorithms() & AuthenticationAlgorithmMask::SHARED) {
854+ if (tmp[0] != '\0')
855+ strcat(tmp, " ");
856+ strcat(tmp, "SHARED");
857+ }
858+ if (mWn->getAuthAlgorithms() & AuthenticationAlgorithmMask::LEAP) {
859+ if (tmp[0] != '\0')
860+ strcat(tmp, " ");
861+ strcat(tmp, "LEAP");
862+ }
863+
864+ if (tmp[0] == '\0') {
865+ strncpy(buffer, "(internal error)", max);
866+ errno = ENOENT;
867+ return NULL;
868+ }
869+ if (tmp[strlen(tmp)] == ' ')
870+ tmp[strlen(tmp)] = '\0';
871+
872+ strncpy(buffer, tmp, max);
873+ return 0;
874+}
875+int WifiNetwork::WifiNetworkAuthAlgorithmsProperty::set(int idx, const char *value) {
876+ uint32_t mask;
877+ if (mWn->parseAuthAlgorithmsMask(value, &mask))
878+ return -1;
879+ return mWn->setAuthAlgorithms(mask);
880+}
881+
882+WifiNetwork::WifiNetworkPairwiseCiphersProperty::WifiNetworkPairwiseCiphersProperty(WifiNetwork *wn) :
883+ WifiNetworkStringProperty(wn, "PairwiseCiphers", false, 1) {
884+}
885+int WifiNetwork::WifiNetworkPairwiseCiphersProperty::get(int idx, char *buffer, size_t max) {
886+ if (mWn->getPairwiseCiphers() == PairwiseCiphersMask::NONE)
887+ strncpy(buffer, "NONE", max);
888+ else {
889+ char tmp[80] = { '\0' };
890+
891+ if (mWn->getPairwiseCiphers() & PairwiseCiphersMask::TKIP)
892+ strcat(tmp, "TKIP");
893+ if (mWn->getPairwiseCiphers() & PairwiseCiphersMask::CCMP) {
894+ if (tmp[0] != '\0')
895+ strcat(tmp, " ");
896+ strcat(tmp, "CCMP");
897+ }
898+ if (tmp[0] == '\0') {
899+ strncpy(buffer, "(internal error)", max);
900+ errno = ENOENT;
901+ return NULL;
902+ }
903+ if (tmp[strlen(tmp)] == ' ')
904+ tmp[strlen(tmp)] = '\0';
905+
906+ strncpy(buffer, tmp, max);
907+ }
908+ return 0;
909+}
910+int WifiNetwork::WifiNetworkPairwiseCiphersProperty::set(int idx, const char *value) {
911+ uint32_t mask;
912+ if (mWn->parsePairwiseCiphersMask(value, &mask))
913+ return -1;
914+ return mWn->setPairwiseCiphers(mask);
915+}
916+
917+WifiNetwork::WifiNetworkGroupCiphersProperty::WifiNetworkGroupCiphersProperty(WifiNetwork *wn) :
918+ WifiNetworkStringProperty(wn, "GroupCiphers", false, 1) {
919+}
920+int WifiNetwork::WifiNetworkGroupCiphersProperty::get(int idx, char *buffer, size_t max) {
921+ char tmp[80] = { '\0' };
922+
923+ if (mWn->getGroupCiphers() & GroupCiphersMask::WEP40)
924+ strcat(tmp, "WEP40");
925+ if (mWn->getGroupCiphers() & GroupCiphersMask::WEP104) {
926+ if (tmp[0] != '\0')
927+ strcat(tmp, " ");
928+ strcat(tmp, "WEP104");
929+ }
930+ if (mWn->getGroupCiphers() & GroupCiphersMask::TKIP) {
931+ if (tmp[0] != '\0')
932+ strcat(tmp, " ");
933+ strcat(tmp, "TKIP");
934+ }
935+ if (mWn->getGroupCiphers() & GroupCiphersMask::CCMP) {
936+ if (tmp[0] != '\0')
937+ strcat(tmp, " ");
938+ strcat(tmp, "CCMP");
939+ }
940+
941+ if (tmp[0] == '\0') {
942+ strncpy(buffer, "(internal error)", max);
943+ errno = ENOENT;
944+ return -1;
945+ }
946+ if (tmp[strlen(tmp)] == ' ')
947+ tmp[strlen(tmp)] = '\0';
948+
949+ strncpy(buffer, tmp, max);
950+ return 0;
951+}
952+int WifiNetwork::WifiNetworkGroupCiphersProperty::set(int idx, const char *value) {
953+ uint32_t mask;
954+ if (mWn->parseGroupCiphersMask(value, &mask))
955+ return -1;
956+ return mWn->setGroupCiphers(mask);
957+}
958+
959+WifiNetwork::WifiNetworkHiddenSsidProperty::WifiNetworkHiddenSsidProperty(WifiNetwork *wn) :
960+ WifiNetworkStringProperty(wn, "HiddenSsid", false, 1) {
961+}
962+int WifiNetwork::WifiNetworkHiddenSsidProperty::get(int idx, char *buffer, size_t max) {
963+ const char *scan_ssid = mWn->getHiddenSsid();
964+
965+ strncpy(buffer, (scan_ssid ? scan_ssid : "none"), max);
966+ return 0;
967+}
968+int WifiNetwork::WifiNetworkHiddenSsidProperty::set(int idx, const char *value) {
969+ return mWn->setHiddenSsid(value);
970+}
--- a/nexus/WifiNetwork.h
+++ b/nexus/WifiNetwork.h
@@ -21,6 +21,10 @@
2121
2222 #include <utils/List.h>
2323
24+#include "Property.h"
25+
26+class PropertyManager;
27+
2428 class KeyManagementMask {
2529 public:
2630 static const uint32_t UNKNOWN = 0;
@@ -60,19 +64,140 @@ public:
6064 };
6165
6266 class Supplicant;
63-class InterfaceConfig;
6467 class Controller;
6568 class WifiController;
6669
67-#include "IPropertyProvider.h"
68-
69-class WifiNetwork : public IPropertyProvider{
70-public:
71- static const char *PropertyNames[];
70+class WifiNetwork {
71+ class WifiNetworkIntegerProperty : public IntegerProperty {
72+ protected:
73+ WifiNetwork *mWn;
74+ public:
75+ WifiNetworkIntegerProperty(WifiNetwork *wn, const char *name, bool ro,
76+ int elements);
77+ virtual ~WifiNetworkIntegerProperty() {}
78+ virtual int set(int idx, int value) = 0;
79+ virtual int get(int idx, int *buffer) = 0;
80+ };
81+ friend class WifiNetwork::WifiNetworkIntegerProperty;
82+
83+ class WifiNetworkStringProperty : public StringProperty {
84+ protected:
85+ WifiNetwork *mWn;
86+ public:
87+ WifiNetworkStringProperty(WifiNetwork *wn, const char *name, bool ro,
88+ int elements);
89+ virtual ~WifiNetworkStringProperty() {}
90+ virtual int set(int idx, const char *value) = 0;
91+ virtual int get(int idx, char *buffer, size_t max) = 0;
92+ };
93+ friend class WifiNetwork::WifiNetworkStringProperty;
94+
95+ class WifiNetworkEnabledProperty : public WifiNetworkIntegerProperty {
96+ public:
97+ WifiNetworkEnabledProperty(WifiNetwork *wn);
98+ virtual ~WifiNetworkEnabledProperty() {};
99+ int set(int idx, int value);
100+ int get(int idx, int *buffer);
101+ };
102+
103+ class WifiNetworkPriorityProperty : public WifiNetworkIntegerProperty {
104+ public:
105+ WifiNetworkPriorityProperty(WifiNetwork *wn);
106+ virtual ~WifiNetworkPriorityProperty() {};
107+ int set(int idx, int value);
108+ int get(int idx, int *buffer);
109+ };
110+
111+ class WifiNetworkDefaultKeyIndexProperty : public WifiNetworkIntegerProperty {
112+ public:
113+ WifiNetworkDefaultKeyIndexProperty(WifiNetwork *wn);
114+ virtual ~WifiNetworkDefaultKeyIndexProperty() {};
115+ int set(int idx, int value);
116+ int get(int idx, int *buffer);
117+ };
118+
119+ class WifiNetworkSsidProperty : public WifiNetworkStringProperty {
120+ public:
121+ WifiNetworkSsidProperty(WifiNetwork *wn);
122+ virtual ~WifiNetworkSsidProperty() {};
123+ int set(int idx, const char *value);
124+ int get(int idx, char *buffer, size_t max);
125+ };
126+
127+ class WifiNetworkBssidProperty : public WifiNetworkStringProperty {
128+ public:
129+ WifiNetworkBssidProperty(WifiNetwork *wn);
130+ virtual ~WifiNetworkBssidProperty() {};
131+ int set(int idx, const char *value);
132+ int get(int idx, char *buffer, size_t max);
133+ };
134+
135+ class WifiNetworkPskProperty : public WifiNetworkStringProperty {
136+ public:
137+ WifiNetworkPskProperty(WifiNetwork *wn);
138+ virtual ~WifiNetworkPskProperty() {};
139+ int set(int idx, const char *value);
140+ int get(int idx, char *buffer, size_t max);
141+ };
142+
143+ class WifiNetworkKeyManagementProperty : public WifiNetworkStringProperty {
144+ public:
145+ WifiNetworkKeyManagementProperty(WifiNetwork *wn);
146+ virtual ~WifiNetworkKeyManagementProperty() {};
147+ int set(int idx, const char *value);
148+ int get(int idx, char *buffer, size_t max);
149+ };
150+
151+ class WifiNetworkAuthAlgorithmsProperty : public WifiNetworkStringProperty {
152+ public:
153+ WifiNetworkAuthAlgorithmsProperty(WifiNetwork *wn);
154+ virtual ~WifiNetworkAuthAlgorithmsProperty() {};
155+ int set(int idx, const char *value);
156+ int get(int idx, char *buffer, size_t max);
157+ };
158+
159+ class WifiNetworkProtocolsProperty : public WifiNetworkStringProperty {
160+ public:
161+ WifiNetworkProtocolsProperty(WifiNetwork *wn);
162+ virtual ~WifiNetworkProtocolsProperty() {};
163+ int set(int idx, const char *value);
164+ int get(int idx, char *buffer, size_t max);
165+ };
166+
167+ class WifiNetworkWepKeyProperty : public WifiNetworkStringProperty {
168+ public:
169+ WifiNetworkWepKeyProperty(WifiNetwork *wn);
170+ virtual ~WifiNetworkWepKeyProperty() {};
171+ int set(int idx, const char *value);
172+ int get(int idx, char *buffer, size_t max);
173+ };
174+
175+ class WifiNetworkPairwiseCiphersProperty : public WifiNetworkStringProperty {
176+ public:
177+ WifiNetworkPairwiseCiphersProperty(WifiNetwork *wn);
178+ virtual ~WifiNetworkPairwiseCiphersProperty() {};
179+ int set(int idx, const char *value);
180+ int get(int idx, char *buffer, size_t max);
181+ };
182+
183+ class WifiNetworkGroupCiphersProperty : public WifiNetworkStringProperty {
184+ public:
185+ WifiNetworkGroupCiphersProperty(WifiNetwork *wn);
186+ virtual ~WifiNetworkGroupCiphersProperty() {};
187+ int set(int idx, const char *value);
188+ int get(int idx, char *buffer, size_t max);
189+ };
190+
191+ class WifiNetworkHiddenSsidProperty : public WifiNetworkStringProperty {
192+ public:
193+ WifiNetworkHiddenSsidProperty(WifiNetwork *wn);
194+ virtual ~WifiNetworkHiddenSsidProperty() {};
195+ int set(int idx, const char *value);
196+ int get(int idx, char *buffer, size_t max);
197+ };
72198
73199 private:
74200 Supplicant *mSuppl;
75- InterfaceConfig *mIfaceCfg;
76201 WifiController *mController;
77202
78203 /*
@@ -128,33 +253,49 @@ private:
128253 /*
129254 * The set of key management protocols supported by this configuration.
130255 */
131- uint32_t mAllowedKeyManagement;
256+ uint32_t mKeyManagement;
132257
133258 /*
134259 * The set of security protocols supported by this configuration.
135260 */
136- uint32_t mAllowedProtocols;
261+ uint32_t mProtocols;
137262
138263 /*
139264 * The set of authentication protocols supported by this configuration.
140265 */
141- uint32_t mAllowedAuthAlgorithms;
266+ uint32_t mAuthAlgorithms;
142267
143268 /*
144269 * The set of pairwise ciphers for WPA supported by this configuration.
145270 */
146- uint32_t mAllowedPairwiseCiphers;
271+ uint32_t mPairwiseCiphers;
147272
148273 /*
149274 * The set of group ciphers for WPA supported by this configuration.
150275 */
151- uint32_t mAllowedGroupCiphers;
276+ uint32_t mGroupCiphers;
152277
153278 /*
154279 * Set if this Network is enabled
155280 */
156281 bool mEnabled;
157282
283+ char *mPropNamespace;
284+ struct {
285+ WifiNetworkEnabledProperty *propEnabled;
286+ WifiNetworkSsidProperty *propSsid;
287+ WifiNetworkBssidProperty *propBssid;
288+ WifiNetworkPskProperty *propPsk;
289+ WifiNetworkWepKeyProperty *propWepKey;
290+ WifiNetworkDefaultKeyIndexProperty *propDefKeyIdx;
291+ WifiNetworkPriorityProperty *propPriority;
292+ WifiNetworkKeyManagementProperty *propKeyManagement;
293+ WifiNetworkProtocolsProperty *propProtocols;
294+ WifiNetworkAuthAlgorithmsProperty *propAuthAlgorithms;
295+ WifiNetworkPairwiseCiphersProperty *propPairwiseCiphers;
296+ WifiNetworkGroupCiphersProperty *propGroupCiphers;
297+ WifiNetworkHiddenSsidProperty *propHiddenSsid;
298+ } mStaticProperties;
158299 private:
159300 WifiNetwork();
160301
@@ -165,8 +306,8 @@ public:
165306 virtual ~WifiNetwork();
166307
167308 WifiNetwork *clone();
168- int registerProperties();
169- int unregisterProperties();
309+ int attachProperties(PropertyManager *pm, const char *nsName);
310+ int detachProperties(PropertyManager *pm, const char *nsName);
170311
171312 int getNetworkId() { return mNetid; }
172313 const char *getSsid() { return mSsid; }
@@ -176,19 +317,14 @@ public:
176317 int getDefaultKeyIndex() { return mDefaultKeyIndex; }
177318 int getPriority() { return mPriority; }
178319 const char *getHiddenSsid() { return mHiddenSsid; }
179- uint32_t getAllowedKeyManagement() { return mAllowedKeyManagement; }
180- uint32_t getAllowedProtocols() { return mAllowedProtocols; }
181- uint32_t getAllowedAuthAlgorithms() { return mAllowedAuthAlgorithms; }
182- uint32_t getAllowedPairwiseCiphers() { return mAllowedPairwiseCiphers; }
183- uint32_t getAllowedGroupCiphers() { return mAllowedGroupCiphers; }
320+ uint32_t getKeyManagement() { return mKeyManagement; }
321+ uint32_t getProtocols() { return mProtocols; }
322+ uint32_t getAuthAlgorithms() { return mAuthAlgorithms; }
323+ uint32_t getPairwiseCiphers() { return mPairwiseCiphers; }
324+ uint32_t getGroupCiphers() { return mGroupCiphers; }
184325 bool getEnabled() { return mEnabled; }
185326 Controller *getController() { return (Controller *) mController; }
186327
187- int set(const char *name, const char *value);
188- const char *get(const char *name, char *buffer, size_t maxsize);
189-
190- InterfaceConfig *getIfaceCfg() { return mIfaceCfg; }
191-
192328 int setEnabled(bool enabled);
193329 int setSsid(const char *ssid);
194330 int setBssid(const char *bssid);
@@ -197,14 +333,22 @@ public:
197333 int setDefaultKeyIndex(int idx);
198334 int setPriority(int pri);
199335 int setHiddenSsid(const char *ssid);
200- int setAllowedKeyManagement(uint32_t mask);
201- int setAllowedProtocols(uint32_t mask);
202- int setAllowedAuthAlgorithms(uint32_t mask);
203- int setAllowedPairwiseCiphers(uint32_t mask);
204- int setAllowedGroupCiphers(uint32_t mask);
336+ int setKeyManagement(uint32_t mask);
337+ int setProtocols(uint32_t mask);
338+ int setAuthAlgorithms(uint32_t mask);
339+ int setPairwiseCiphers(uint32_t mask);
340+ int setGroupCiphers(uint32_t mask);
205341
206342 // XXX:Should this really be exposed?.. meh
207343 int refresh();
344+
345+private:
346+ int parseKeyManagementMask(const char *buffer, uint32_t *mask);
347+ int parseProtocolsMask(const char *buffer, uint32_t *mask);
348+ int parseAuthAlgorithmsMask(const char *buffer, uint32_t *mask);
349+ int parsePairwiseCiphersMask(const char *buffer, uint32_t *mask);
350+ int parseGroupCiphersMask(const char *buffer, uint32_t *mask);
351+ void createProperties();
208352 };
209353
210354 typedef android::List<WifiNetwork *> WifiNetworkCollection;
--- /dev/null
+++ b/nexus/WifiStatusPoller.cpp
@@ -0,0 +1,104 @@
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+#include <stdio.h>
17+#include <errno.h>
18+#include <stdlib.h>
19+#include <sys/socket.h>
20+#include <sys/select.h>
21+#include <sys/time.h>
22+#include <sys/types.h>
23+#include <sys/un.h>
24+
25+#define LOG_TAG "WifiStatusPoller"
26+#include <cutils/log.h>
27+
28+#include "WifiStatusPoller.h"
29+#include "IWifiStatusPollerHandler.h"
30+
31+
32+WifiStatusPoller::WifiStatusPoller(IWifiStatusPollerHandler *handler) :
33+ mHandlers(handler) {
34+ mPollingInterval = 5;
35+ mStarted = false;
36+}
37+
38+int WifiStatusPoller::start() {
39+
40+ if (pipe(mCtrlPipe))
41+ return -1;
42+
43+ if (pthread_create(&mThread, NULL, WifiStatusPoller::threadStart, this))
44+ return -1;
45+
46+ return 0;
47+}
48+
49+int WifiStatusPoller::stop() {
50+ char c = 0;
51+
52+ if (write(mCtrlPipe[1], &c, 1) != 1) {
53+ LOGE("Error writing to control pipe (%s)", strerror(errno));
54+ return -1;
55+ }
56+
57+ void *ret;
58+ if (pthread_join(mThread, &ret)) {
59+ LOGE("Error joining to listener thread (%s)", strerror(errno));
60+ return -1;
61+ }
62+ close(mCtrlPipe[0]);
63+ close(mCtrlPipe[1]);
64+ return 0;
65+}
66+
67+void *WifiStatusPoller::threadStart(void *obj) {
68+ WifiStatusPoller *me = reinterpret_cast<WifiStatusPoller *>(obj);
69+
70+ me->mStarted = true;
71+ LOGD("Starting");
72+ me->run();
73+ me->mStarted = false;
74+ LOGD("Stopping");
75+ pthread_exit(NULL);
76+ return NULL;
77+}
78+
79+void WifiStatusPoller::run() {
80+
81+ while(1) {
82+ struct timeval to;
83+ fd_set read_fds;
84+ int rc = 0;
85+ int max = 0;
86+
87+ FD_ZERO(&read_fds);
88+ to.tv_usec = 0;
89+ to.tv_sec = mPollingInterval;
90+
91+ FD_SET(mCtrlPipe[0], &read_fds);
92+ max = mCtrlPipe[0];
93+
94+ if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) {
95+ LOGE("select failed (%s)", strerror(errno));
96+ sleep(1);
97+ continue;
98+ } else if (!rc) {
99+ mHandlers->onStatusPollInterval();
100+ }
101+ if (FD_ISSET(mCtrlPipe[0], &read_fds))
102+ break;
103+ }
104+}
--- /dev/null
+++ b/nexus/WifiStatusPoller.h
@@ -0,0 +1,47 @@
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 _WIFI_STATUS_POLLER_H
18+#define _WIFI_STATUS_POLLER_H
19+
20+#include <pthread.h>
21+
22+class IWifiStatusPollerHandler;
23+
24+class WifiStatusPoller {
25+ pthread_t mThread;
26+ int mCtrlPipe[2];
27+ int mPollingInterval;
28+ IWifiStatusPollerHandler *mHandlers;
29+ bool mStarted;
30+
31+public:
32+ WifiStatusPoller(IWifiStatusPollerHandler *handler);
33+ virtual ~WifiStatusPoller() {}
34+
35+ int start();
36+ int stop();
37+ bool isStarted() { return mStarted; }
38+
39+ void setPollingInterval(int interval);
40+ int getPollingInterval() { return mPollingInterval; }
41+
42+private:
43+ static void *threadStart(void *obj);
44+ void run();
45+};
46+
47+#endif