system/corennnnn
Revisión | c4a895b7094461c98101924cf096680bfb7856f1 (tree) |
---|---|
Tiempo | 2009-07-11 06:23:51 |
Autor | San Mehat <san@goog...> |
Commiter | San Mehat |
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:
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>
@@ -33,7 +33,7 @@ public: | ||
33 | 33 | SocketListener(const char *socketNames, bool listen); |
34 | 34 | SocketListener(int socketFd, bool listen); |
35 | 35 | |
36 | - virtual ~SocketListener() {} | |
36 | + virtual ~SocketListener(); | |
37 | 37 | int startListener(); |
38 | 38 | int stopListener(); |
39 | 39 |
@@ -56,24 +56,73 @@ void FrameworkListener::registerCmd(FrameworkCommand *cmd) { | ||
56 | 56 | } |
57 | 57 | |
58 | 58 | void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { |
59 | - int argc; | |
59 | + FrameworkCommandCollection::iterator i; | |
60 | + int argc = 0; | |
60 | 61 | 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 | + } | |
61 | 102 | |
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++; | |
73 | 112 | } |
74 | 113 | |
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 | |
76 | 120 | |
121 | + if (quote) { | |
122 | + cli->sendMsg(500, "Unclosed quotes error", false); | |
123 | + goto out; | |
124 | + } | |
125 | + | |
77 | 126 | for (i = mCommands->begin(); i != mCommands->end(); ++i) { |
78 | 127 | FrameworkCommand *c = *i; |
79 | 128 |
@@ -81,10 +130,14 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { | ||
81 | 130 | if (c->runCommand(cli, argc, argv)) { |
82 | 131 | LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno)); |
83 | 132 | } |
84 | - return; | |
133 | + goto out; | |
85 | 134 | } |
86 | 135 | } |
87 | 136 | |
88 | 137 | cli->sendMsg(500, "Command not recognized", false); |
138 | +out: | |
139 | + int j; | |
140 | + for (j = 0; j < argc; j++) | |
141 | + free(argv[j]); | |
89 | 142 | return; |
90 | 143 | } |
@@ -45,9 +45,26 @@ SocketListener::SocketListener(int socketFd, bool listen) { | ||
45 | 45 | mClients = new SocketClientCollection(); |
46 | 46 | } |
47 | 47 | |
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 | + | |
48 | 64 | int SocketListener::startListener() { |
49 | 65 | |
50 | 66 | if (!mSocketName && mSock == -1) { |
67 | + LOGE("Failed to start unbound listener"); | |
51 | 68 | errno = EINVAL; |
52 | 69 | return -1; |
53 | 70 | } else if (mSocketName) { |
@@ -64,11 +81,15 @@ int SocketListener::startListener() { | ||
64 | 81 | } else if (!mListen) |
65 | 82 | mClients->push_back(new SocketClient(mSock)); |
66 | 83 | |
67 | - if (pipe(mCtrlPipe)) | |
84 | + if (pipe(mCtrlPipe)) { | |
85 | + LOGE("pipe failed (%s)", strerror(errno)); | |
68 | 86 | return -1; |
87 | + } | |
69 | 88 | |
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)); | |
71 | 91 | return -1; |
92 | + } | |
72 | 93 | |
73 | 94 | return 0; |
74 | 95 | } |
@@ -88,6 +109,19 @@ int SocketListener::stopListener() { | ||
88 | 109 | } |
89 | 110 | close(mCtrlPipe[0]); |
90 | 111 | 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 | + } | |
91 | 125 | return 0; |
92 | 126 | } |
93 | 127 |
@@ -7,23 +7,22 @@ include $(CLEAR_VARS) | ||
7 | 7 | |
8 | 8 | LOCAL_SRC_FILES:= \ |
9 | 9 | main.cpp \ |
10 | - NetworkManager.cpp \ | |
10 | + NexusCommand.cpp \ | |
11 | 11 | CommandListener.cpp \ |
12 | + Property.cpp \ | |
13 | + PropertyManager.cpp \ | |
14 | + InterfaceConfig.cpp \ | |
15 | + NetworkManager.cpp \ | |
12 | 16 | Controller.cpp \ |
13 | 17 | WifiController.cpp \ |
14 | - LoopController.cpp \ | |
15 | - NexusCommand.cpp \ | |
16 | 18 | TiwlanWifiController.cpp \ |
19 | + TiwlanEventListener.cpp \ | |
20 | + WifiNetwork.cpp \ | |
21 | + WifiStatusPoller.cpp \ | |
22 | + ScanResult.cpp \ | |
17 | 23 | Supplicant.cpp \ |
18 | 24 | SupplicantEvent.cpp \ |
19 | 25 | SupplicantListener.cpp \ |
20 | - VpnController.cpp \ | |
21 | - ScanResult.cpp \ | |
22 | - WifiScanner.cpp \ | |
23 | - WifiNetwork.cpp \ | |
24 | - OpenVpnController.cpp \ | |
25 | - InterfaceConfig.cpp \ | |
26 | - PropertyManager.cpp \ | |
27 | 26 | SupplicantState.cpp \ |
28 | 27 | SupplicantEventFactory.cpp \ |
29 | 28 | SupplicantConnectedEvent.cpp \ |
@@ -34,8 +33,11 @@ LOCAL_SRC_FILES:= \ | ||
34 | 33 | SupplicantConnectionTimeoutEvent.cpp \ |
35 | 34 | SupplicantDisconnectedEvent.cpp \ |
36 | 35 | SupplicantStatus.cpp \ |
37 | - TiwlanEventListener.cpp \ | |
36 | + OpenVpnController.cpp \ | |
37 | + VpnController.cpp \ | |
38 | + LoopController.cpp \ | |
38 | 39 | DhcpClient.cpp DhcpListener.cpp \ |
40 | + DhcpState.cpp DhcpEvent.cpp \ | |
39 | 41 | |
40 | 42 | LOCAL_MODULE:= nexus |
41 | 43 |
@@ -31,7 +31,7 @@ | ||
31 | 31 | #include "NetworkManager.h" |
32 | 32 | #include "WifiController.h" |
33 | 33 | #include "VpnController.h" |
34 | -#include "ErrorCode.h" | |
34 | +#include "ResponseCode.h" | |
35 | 35 | |
36 | 36 | CommandListener::CommandListener() : |
37 | 37 | FrameworkListener("nexus") { |
@@ -60,11 +60,11 @@ int CommandListener::WifiCreateNetworkCmd::runCommand(SocketClient *cli, | ||
60 | 60 | WifiNetwork *wn; |
61 | 61 | |
62 | 62 | if (!(wn = wc->createNetwork())) |
63 | - cli->sendMsg(ErrorCode::OperationFailed, "Failed to create network", true); | |
63 | + cli->sendMsg(ResponseCode::OperationFailed, "Failed to create network", true); | |
64 | 64 | else { |
65 | 65 | char tmp[128]; |
66 | 66 | sprintf(tmp, "Created network id %d.", wn->getNetworkId()); |
67 | - cli->sendMsg(ErrorCode::CommandOkay, tmp, false); | |
67 | + cli->sendMsg(ResponseCode::CommandOkay, tmp, false); | |
68 | 68 | } |
69 | 69 | return 0; |
70 | 70 | } |
@@ -79,9 +79,9 @@ int CommandListener::WifiRemoveNetworkCmd::runCommand(SocketClient *cli, | ||
79 | 79 | WifiController *wc = (WifiController *) nm->findController("WIFI"); |
80 | 80 | |
81 | 81 | 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); | |
83 | 83 | else { |
84 | - cli->sendMsg(ErrorCode::CommandOkay, "Network removed.", false); | |
84 | + cli->sendMsg(ResponseCode::CommandOkay, "Network removed.", false); | |
85 | 85 | } |
86 | 86 | return 0; |
87 | 87 | } |
@@ -100,16 +100,16 @@ int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, | ||
100 | 100 | char buffer[256]; |
101 | 101 | |
102 | 102 | for(it = src->begin(); it != src->end(); ++it) { |
103 | - sprintf(buffer, "%s:%u:%d:%s:%s", | |
103 | + sprintf(buffer, "%s %u %d %s %s", | |
104 | 104 | (*it)->getBssid(), (*it)->getFreq(), (*it)->getLevel(), |
105 | 105 | (*it)->getFlags(), (*it)->getSsid()); |
106 | - cli->sendMsg(ErrorCode::WifiScanResult, buffer, false); | |
106 | + cli->sendMsg(ResponseCode::WifiScanResult, buffer, false); | |
107 | 107 | delete (*it); |
108 | 108 | it = src->erase(it); |
109 | 109 | } |
110 | 110 | |
111 | 111 | delete src; |
112 | - cli->sendMsg(ErrorCode::CommandOkay, "Scan results complete.", false); | |
112 | + cli->sendMsg(ResponseCode::CommandOkay, "Scan results complete.", false); | |
113 | 113 | return 0; |
114 | 114 | } |
115 | 115 |
@@ -128,12 +128,12 @@ int CommandListener::WifiListNetworksCmd::runCommand(SocketClient *cli, | ||
128 | 128 | |
129 | 129 | for(it = src->begin(); it != src->end(); ++it) { |
130 | 130 | sprintf(buffer, "%d:%s", (*it)->getNetworkId(), (*it)->getSsid()); |
131 | - cli->sendMsg(ErrorCode::WifiNetworkList, buffer, false); | |
131 | + cli->sendMsg(ResponseCode::WifiNetworkList, buffer, false); | |
132 | 132 | delete (*it); |
133 | 133 | } |
134 | 134 | |
135 | 135 | delete src; |
136 | - cli->sendMsg(ErrorCode::CommandOkay, "Network listing complete.", false); | |
136 | + cli->sendMsg(ResponseCode::CommandOkay, "Network listing complete.", false); | |
137 | 137 | return 0; |
138 | 138 | } |
139 | 139 |
@@ -159,14 +159,14 @@ int CommandListener::GetCmd::runCommand(SocketClient *cli, int argc, char **argv | ||
159 | 159 | |
160 | 160 | char *tmp; |
161 | 161 | asprintf(&tmp, "%s %s", argv[1], val); |
162 | - cli->sendMsg(ErrorCode::PropertyRead, tmp, false); | |
162 | + cli->sendMsg(ResponseCode::PropertyRead, tmp, false); | |
163 | 163 | free(tmp); |
164 | 164 | |
165 | - cli->sendMsg(ErrorCode::CommandOkay, "Property read.", false); | |
165 | + cli->sendMsg(ResponseCode::CommandOkay, "Property read.", false); | |
166 | 166 | return 0; |
167 | 167 | out_inval: |
168 | 168 | errno = EINVAL; |
169 | - cli->sendMsg(ErrorCode::CommandParameterError, "Failed to read property.", true); | |
169 | + cli->sendMsg(ResponseCode::CommandParameterError, "Failed to read property.", true); | |
170 | 170 | return 0; |
171 | 171 | } |
172 | 172 |
@@ -179,12 +179,12 @@ int CommandListener::SetCmd::runCommand(SocketClient *cli, int argc, | ||
179 | 179 | if (NetworkManager::Instance()->getPropMngr()->set(argv[1], argv[2])) |
180 | 180 | goto out_inval; |
181 | 181 | |
182 | - cli->sendMsg(ErrorCode::CommandOkay, "Property set.", false); | |
182 | + cli->sendMsg(ResponseCode::CommandOkay, "Property set.", false); | |
183 | 183 | return 0; |
184 | 184 | |
185 | 185 | out_inval: |
186 | 186 | errno = EINVAL; |
187 | - cli->sendMsg(ErrorCode::CommandParameterError, "Failed to set property.", true); | |
187 | + cli->sendMsg(ResponseCode::CommandParameterError, "Failed to set property.", true); | |
188 | 188 | return 0; |
189 | 189 | } |
190 | 190 |
@@ -194,10 +194,14 @@ CommandListener::ListCmd::ListCmd() : | ||
194 | 194 | |
195 | 195 | int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **argv) { |
196 | 196 | android::List<char *> *pc; |
197 | + char *prefix = NULL; | |
197 | 198 | |
198 | - if (!(pc = NetworkManager::Instance()->getPropMngr()->createPropertyList())) { | |
199 | + if (argc > 1) | |
200 | + prefix = argv[1]; | |
201 | + | |
202 | + if (!(pc = NetworkManager::Instance()->getPropMngr()->createPropertyList(prefix))) { | |
199 | 203 | errno = ENODATA; |
200 | - cli->sendMsg(ErrorCode::CommandParameterError, "Failed to list properties.", true); | |
204 | + cli->sendMsg(ResponseCode::CommandParameterError, "Failed to list properties.", true); | |
201 | 205 | return 0; |
202 | 206 | } |
203 | 207 |
@@ -218,7 +222,7 @@ int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **arg | ||
218 | 222 | free((*it)); |
219 | 223 | continue; |
220 | 224 | } |
221 | - cli->sendMsg(ErrorCode::PropertyList, buf, false); | |
225 | + cli->sendMsg(ResponseCode::PropertyList, buf, false); | |
222 | 226 | free(buf); |
223 | 227 | |
224 | 228 | free((*it)); |
@@ -226,6 +230,6 @@ int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **arg | ||
226 | 230 | |
227 | 231 | delete pc; |
228 | 232 | |
229 | - cli->sendMsg(ErrorCode::CommandOkay, "Properties list complete.", false); | |
233 | + cli->sendMsg(ResponseCode::CommandOkay, "Properties list complete.", false); | |
230 | 234 | return 0; |
231 | 235 | } |
@@ -30,6 +30,7 @@ | ||
30 | 30 | #include <cutils/log.h> |
31 | 31 | |
32 | 32 | #include "Controller.h" |
33 | +#include "InterfaceConfig.h" | |
33 | 34 | |
34 | 35 | extern "C" int init_module(void *, unsigned int, const char *); |
35 | 36 | extern "C" int delete_module(const char *, unsigned int); |
@@ -57,16 +58,6 @@ int Controller::stop() { | ||
57 | 58 | return 0; |
58 | 59 | } |
59 | 60 | |
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 | - | |
70 | 61 | int Controller::loadKernelModule(char *modpath, const char *args) { |
71 | 62 | void *module; |
72 | 63 | unsigned int size; |
@@ -164,13 +155,11 @@ bail: | ||
164 | 155 | |
165 | 156 | int Controller::bindInterface(const char *ifname) { |
166 | 157 | mBoundInterface = strdup(ifname); |
167 | - LOGD("Controller %s bound to %s", mName, ifname); | |
168 | 158 | return 0; |
169 | 159 | } |
170 | 160 | |
171 | 161 | int Controller::unbindInterface(const char *ifname) { |
172 | 162 | free(mBoundInterface); |
173 | 163 | mBoundInterface = NULL; |
174 | - LOGD("Controller %s unbound from %s", mName, ifname); | |
175 | 164 | return 0; |
176 | 165 | } |
@@ -26,9 +26,8 @@ class PropertyManager; | ||
26 | 26 | class IControllerHandler; |
27 | 27 | |
28 | 28 | #include "PropertyManager.h" |
29 | -#include "IPropertyProvider.h" | |
30 | 29 | |
31 | -class Controller : public IPropertyProvider { | |
30 | +class Controller { | |
32 | 31 | /* |
33 | 32 | * Name of this controller - WIFI/VPN/USBNET/BTNET/BTDUN/LOOP/etc |
34 | 33 | */ |
@@ -54,11 +53,7 @@ public: | ||
54 | 53 | |
55 | 54 | const char *getName() { return mName; } |
56 | 55 | 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 | + | |
62 | 57 | protected: |
63 | 58 | int loadKernelModule(char *modpath, const char *args); |
64 | 59 | bool isKernelModuleLoaded(const char *modtag); |
@@ -17,7 +17,9 @@ | ||
17 | 17 | #include <stdio.h> |
18 | 18 | #include <errno.h> |
19 | 19 | #include <sys/types.h> |
20 | +#include <sys/socket.h> | |
20 | 21 | #include <arpa/inet.h> |
22 | +#include <pthread.h> | |
21 | 23 | |
22 | 24 | #define LOG_TAG "DhcpClient" |
23 | 25 | #include <cutils/log.h> |
@@ -29,6 +31,7 @@ | ||
29 | 31 | #include "DhcpState.h" |
30 | 32 | #include "DhcpListener.h" |
31 | 33 | #include "IDhcpEventHandlers.h" |
34 | +#include "Controller.h" | |
32 | 35 | |
33 | 36 | extern "C" { |
34 | 37 | int ifc_disable(const char *ifname); |
@@ -54,9 +57,13 @@ char *dhcp_get_errmsg(); | ||
54 | 57 | } |
55 | 58 | |
56 | 59 | DhcpClient::DhcpClient(IDhcpEventHandlers *handlers) : |
57 | - mState(DhcpState::STOPPED), mHandlers(handlers) { | |
60 | + mState(DhcpState::INIT), mHandlers(handlers) { | |
58 | 61 | mServiceManager = new ServiceManager(); |
59 | 62 | mListener = NULL; |
63 | + mListenerSocket = NULL; | |
64 | + mController = NULL; | |
65 | + mDoArpProbe = false; | |
66 | + pthread_mutex_init(&mLock, NULL); | |
60 | 67 | } |
61 | 68 | |
62 | 69 | DhcpClient::~DhcpClient() { |
@@ -65,41 +72,89 @@ DhcpClient::~DhcpClient() { | ||
65 | 72 | delete mListener; |
66 | 73 | } |
67 | 74 | |
68 | -int DhcpClient::start(const char *interface) { | |
69 | - | |
75 | +int DhcpClient::start(Controller *c) { | |
76 | + LOGD("Starting DHCP service (arp probe = %d)", mDoArpProbe); | |
70 | 77 | 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 | + } | |
72 | 111 | |
73 | 112 | if (mServiceManager->start(svc)) { |
74 | 113 | LOGE("Failed to start dhcp service"); |
114 | + pthread_mutex_unlock(&mLock); | |
75 | 115 | return -1; |
76 | 116 | } |
77 | 117 | |
78 | - mListener = new DhcpListener(mHandlers); | |
118 | + mListener = new DhcpListener(mController, mListenerSocket, mHandlers); | |
79 | 119 | if (mListener->startListener()) { |
80 | 120 | LOGE("Failed to start listener"); |
81 | 121 | #if 0 |
82 | - mServiceManager->stop("dhcpcd_ng"); | |
122 | + mServiceManager->stop("dhcpcd"); | |
83 | 123 | return -1; |
84 | 124 | #endif |
85 | 125 | delete mListener; |
86 | 126 | mListener = NULL; |
127 | + pthread_mutex_unlock(&mLock); | |
87 | 128 | } |
88 | 129 | |
89 | - mState = DhcpState::STARTED; | |
90 | - | |
130 | + pthread_mutex_unlock(&mLock); | |
91 | 131 | return 0; |
92 | 132 | } |
93 | 133 | |
94 | 134 | int DhcpClient::stop() { |
135 | + pthread_mutex_lock(&mLock); | |
136 | + if (!mController) { | |
137 | + pthread_mutex_unlock(&mLock); | |
138 | + return 0; | |
139 | + } | |
140 | + | |
95 | 141 | if (mListener) { |
96 | 142 | mListener->stopListener(); |
97 | 143 | delete mListener; |
98 | 144 | mListener = NULL; |
99 | 145 | } |
146 | + close(mListenerSocket); | |
100 | 147 | |
101 | - if (mServiceManager->stop("dhcpcd_ng")) | |
148 | + if (mServiceManager->stop("dhcpcd")) { | |
102 | 149 | 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); | |
104 | 155 | return 0; |
105 | 156 | } |
157 | + | |
158 | +void DhcpClient::setDoArpProbe(bool probe) { | |
159 | + mDoArpProbe = probe; | |
160 | +} |
@@ -18,23 +18,36 @@ | ||
18 | 18 | #ifndef _DhcpClient_H |
19 | 19 | #define _DhcpClient_H |
20 | 20 | |
21 | +#include <pthread.h> | |
22 | + | |
21 | 23 | class IDhcpEventHandlers; |
22 | 24 | class ServiceManager; |
23 | 25 | class DhcpListener; |
26 | +class Controller; | |
24 | 27 | |
25 | 28 | class DhcpClient { |
29 | +public: | |
30 | + static const int STATUS_MONITOR_PORT = 6666; | |
31 | + | |
32 | +private: | |
26 | 33 | int mState; |
27 | 34 | IDhcpEventHandlers *mHandlers; |
28 | 35 | ServiceManager *mServiceManager; |
29 | 36 | DhcpListener *mListener; |
37 | + int mListenerSocket; | |
38 | + pthread_mutex_t mLock; | |
39 | + Controller *mController; | |
40 | + bool mDoArpProbe; | |
30 | 41 | |
31 | 42 | public: |
32 | 43 | DhcpClient(IDhcpEventHandlers *handlers); |
33 | 44 | virtual ~DhcpClient(); |
34 | 45 | |
35 | 46 | int getState() { return mState; } |
47 | + bool getDoArpProbe() { return mDoArpProbe; } | |
48 | + void setDoArpProbe(bool probe); | |
36 | 49 | |
37 | - int start(const char *interface); | |
50 | + int start(Controller *c); | |
38 | 51 | int stop(); |
39 | 52 | }; |
40 | 53 |
@@ -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 | +} |
@@ -14,20 +14,20 @@ | ||
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 | |
17 | -#ifndef _IPROPERTY_PROVIDER_H | |
18 | -#define _IPROPERTY_PROVIDER_H | |
17 | +#ifndef _DHCP_EVENT_H | |
18 | +#define _DHCP_EVENT_H | |
19 | 19 | |
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; | |
22 | 27 | |
23 | -#include <utils/List.h> | |
28 | + static char *toString(int val, char *buffer, int max); | |
24 | 29 | |
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); | |
29 | 31 | }; |
30 | 32 | |
31 | -typedef android::List<IPropertyProvider *> IPropertyProviderCollection; | |
32 | - | |
33 | 33 | #endif |
@@ -14,21 +14,95 @@ | ||
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 | |
17 | +#include <errno.h> | |
18 | +#include <sys/socket.h> | |
19 | +#include <netinet/in.h> | |
20 | +#include <arpa/inet.h> | |
21 | + | |
17 | 22 | #define LOG_TAG "DhcpListener" |
18 | 23 | #include <cutils/log.h> |
19 | 24 | |
20 | 25 | #include <DhcpListener.h> |
21 | 26 | #include "IDhcpEventHandlers.h" |
27 | +#include "DhcpState.h" | |
28 | +#include "DhcpEvent.h" | |
29 | +#include "Controller.h" | |
22 | 30 | |
23 | -DhcpListener::DhcpListener(IDhcpEventHandlers *handlers) : | |
24 | - SocketListener("dhcp_ng", false) { | |
31 | +DhcpListener::DhcpListener(Controller *c, int socket, IDhcpEventHandlers *handlers) : | |
32 | + SocketListener(socket, false) { | |
25 | 33 | mHandlers = handlers; |
34 | + mController = c; | |
26 | 35 | } |
27 | 36 | |
28 | 37 | DhcpListener::~DhcpListener() { |
29 | 38 | } |
30 | 39 | |
31 | 40 | 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 | + | |
33 | 107 | return true; |
34 | 108 | } |
@@ -20,13 +20,15 @@ | ||
20 | 20 | #include <sysutils/SocketListener.h> |
21 | 21 | |
22 | 22 | class IDhcpEventHandlers; |
23 | +class Controller; | |
23 | 24 | |
24 | 25 | class DhcpListener : public SocketListener { |
25 | 26 | IDhcpEventHandlers *mHandlers; |
27 | + Controller *mController; | |
26 | 28 | |
27 | 29 | public: |
28 | 30 | |
29 | - DhcpListener(IDhcpEventHandlers *handlers); | |
31 | + DhcpListener(Controller *c, int socket, IDhcpEventHandlers *handlers); | |
30 | 32 | virtual ~DhcpListener(); |
31 | 33 | |
32 | 34 | private: |
@@ -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 | +} |
@@ -14,14 +14,26 @@ | ||
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 | |
17 | -#ifndef _DhcpState_H | |
18 | -#define _DhcpState_H | |
17 | +#ifndef _DHCP_STATE_H | |
18 | +#define _DHCP_STATE_H | |
19 | 19 | |
20 | 20 | class DhcpState { |
21 | 21 | 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); | |
25 | 37 | }; |
26 | 38 | |
27 | 39 | #endif |
@@ -22,8 +22,11 @@ class InterfaceConfig; | ||
22 | 22 | |
23 | 23 | class IControllerHandler { |
24 | 24 | 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; | |
27 | 30 | }; |
28 | 31 | |
29 | 32 | #endif |
@@ -20,6 +20,14 @@ | ||
20 | 20 | |
21 | 21 | class IDhcpEventHandlers { |
22 | 22 | 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; | |
23 | 31 | }; |
24 | 32 | |
25 | 33 | #endif |
@@ -27,6 +27,7 @@ class SupplicantDisconnectedEvent; | ||
27 | 27 | |
28 | 28 | class ISupplicantEventHandler { |
29 | 29 | public: |
30 | + virtual ~ISupplicantEventHandler(){} | |
30 | 31 | virtual void onAssociatingEvent(SupplicantAssociatingEvent *evt) = 0; |
31 | 32 | virtual void onAssociatedEvent(SupplicantAssociatedEvent *evt) = 0; |
32 | 33 | virtual void onConnectedEvent(SupplicantConnectedEvent *evt) = 0; |
@@ -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 |
@@ -23,147 +23,72 @@ | ||
23 | 23 | #include "InterfaceConfig.h" |
24 | 24 | #include "NetworkManager.h" |
25 | 25 | |
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); | |
35 | 32 | } |
36 | 33 | |
37 | 34 | 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; | |
40 | 40 | } |
41 | 41 | |
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 | +} | |
48 | 45 | |
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)); | |
62 | 48 | } |
63 | 49 | |
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 | +} | |
71 | 53 | |
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)); | |
79 | 56 | } |
80 | 57 | |
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 | +} | |
85 | 61 | |
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); | |
93 | 68 | return 0; |
94 | 69 | } |
95 | 70 | |
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); | |
105 | 77 | return 0; |
106 | 78 | } |
107 | 79 | |
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 | +} | |
135 | 85 | |
86 | +int InterfaceConfig::InterfaceDnsProperty::set(int idx, struct in_addr *value) { | |
87 | + memcpy(&mCfg->mDns[idx], value, sizeof(struct in_addr)); | |
136 | 88 | return 0; |
137 | - | |
138 | -out_inval: | |
139 | - errno = EINVAL; | |
140 | - return -1; | |
141 | 89 | } |
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; | |
169 | 93 | } |
94 | + |
@@ -22,53 +22,58 @@ | ||
22 | 22 | #include <netinet/in.h> |
23 | 23 | #include <arpa/inet.h> |
24 | 24 | |
25 | -#include "IPropertyProvider.h" | |
26 | - | |
25 | +#include "Property.h" | |
27 | 26 | class PropertyManager; |
28 | 27 | |
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; | |
32 | 39 | |
33 | -private: | |
34 | - char *mPropPrefix; | |
35 | - bool mUseDhcp; | |
36 | 40 | struct in_addr mIp; |
37 | 41 | struct in_addr mNetmask; |
38 | 42 | 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]; | |
42 | 45 | |
43 | 46 | 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); | |
56 | 48 | virtual ~InterfaceConfig(); |
57 | 49 | |
58 | 50 | int set(const char *name, const char *value); |
59 | 51 | const char *get(const char *name, char *buffer, size_t maxsize); |
60 | 52 | |
61 | - bool getUseDhcp() const { return mUseDhcp; } | |
62 | 53 | const struct in_addr &getIp() const { return mIp; } |
63 | 54 | const struct in_addr &getNetmask() const { return mNetmask; } |
64 | 55 | 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); | |
68 | 67 | |
69 | 68 | 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 | + }; | |
72 | 77 | }; |
73 | 78 | |
74 | 79 |
@@ -21,14 +21,5 @@ | ||
21 | 21 | |
22 | 22 | LoopController::LoopController(PropertyManager *propmngr, |
23 | 23 | IControllerHandler *handlers) : |
24 | - Controller("LOOP", propmngr, handlers) { | |
24 | + Controller("loop", propmngr, handlers) { | |
25 | 25 | } |
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 | - |
@@ -24,6 +24,9 @@ | ||
24 | 24 | #include "NetworkManager.h" |
25 | 25 | #include "InterfaceConfig.h" |
26 | 26 | #include "DhcpClient.h" |
27 | +#include "DhcpState.h" | |
28 | +#include "DhcpEvent.h" | |
29 | +#include "ResponseCode.h" | |
27 | 30 | |
28 | 31 | NetworkManager *NetworkManager::sInstance = NULL; |
29 | 32 |
@@ -35,8 +38,9 @@ NetworkManager *NetworkManager::Instance() { | ||
35 | 38 | |
36 | 39 | NetworkManager::NetworkManager(PropertyManager *propMngr) { |
37 | 40 | mBroadcaster = NULL; |
38 | - mControllers = new ControllerCollection(); | |
41 | + mControllerBindings = new ControllerBindingCollection(); | |
39 | 42 | mPropMngr = propMngr; |
43 | + mLastDhcpState = DhcpState::INIT; | |
40 | 44 | mDhcp = new DhcpClient(this); |
41 | 45 | } |
42 | 46 |
@@ -51,17 +55,17 @@ int NetworkManager::run() { | ||
51 | 55 | } |
52 | 56 | |
53 | 57 | int NetworkManager::attachController(Controller *c) { |
54 | - mControllers->push_back(c); | |
58 | + ControllerBinding *cb = new ControllerBinding(c); | |
59 | + mControllerBindings->push_back(cb); | |
55 | 60 | return 0; |
56 | 61 | } |
57 | 62 | |
58 | 63 | int NetworkManager::startControllers() { |
59 | 64 | int rc = 0; |
60 | - ControllerCollection::iterator i; | |
65 | + ControllerBindingCollection::iterator it; | |
61 | 66 | |
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(); | |
65 | 69 | if (irc && !rc) |
66 | 70 | rc = irc; |
67 | 71 | } |
@@ -70,52 +74,132 @@ int NetworkManager::startControllers() { | ||
70 | 74 | |
71 | 75 | int NetworkManager::stopControllers() { |
72 | 76 | int rc = 0; |
73 | - ControllerCollection::iterator i; | |
77 | + ControllerBindingCollection::iterator it; | |
74 | 78 | |
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(); | |
78 | 81 | if (irc && !rc) |
79 | 82 | rc = irc; |
80 | 83 | } |
81 | 84 | return rc; |
82 | 85 | } |
83 | 86 | |
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 | + | |
84 | 98 | 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(); | |
89 | 104 | } |
90 | - LOGW("Controller '%s' not found", name); | |
105 | + errno = ENOENT; | |
91 | 106 | return NULL; |
92 | 107 | } |
93 | 108 | |
94 | -void NetworkManager::onInterfaceConnected(Controller *c, const InterfaceConfig *cfg) { | |
109 | +void NetworkManager::onInterfaceConnected(Controller *c) { | |
95 | 110 | LOGD("Controller %s interface %s connected", c->getName(), c->getBoundInterface()); |
96 | 111 | |
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; | |
100 | 115 | } |
116 | +} | |
101 | 117 | |
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(); | |
112 | 123 | } |
113 | 124 | |
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 | +} | |
116 | 135 | |
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; | |
120 | 152 | } |
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; | |
121 | 200 | } |
201 | + | |
202 | +void NetworkManager::ControllerBinding::setBoundCfg(InterfaceConfig *c) { | |
203 | + mBoundCfg = c; | |
204 | +} | |
205 | + |
@@ -17,6 +17,7 @@ | ||
17 | 17 | #ifndef _NETWORKMANAGER_H |
18 | 18 | #define _NETWORKMANAGER_H |
19 | 19 | |
20 | +#include <utils/List.h> | |
20 | 21 | #include <sysutils/SocketListener.h> |
21 | 22 | |
22 | 23 | #include "Controller.h" |
@@ -28,14 +29,33 @@ class InterfaceConfig; | ||
28 | 29 | class DhcpClient; |
29 | 30 | |
30 | 31 | class NetworkManager : public IControllerHandler, public IDhcpEventHandlers { |
31 | -private: | |
32 | 32 | static NetworkManager *sInstance; |
33 | 33 | |
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 | + | |
34 | 53 | 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; | |
39 | 59 | |
40 | 60 | public: |
41 | 61 | virtual ~NetworkManager(); |
@@ -57,8 +77,19 @@ private: | ||
57 | 77 | int stopControllers(); |
58 | 78 | |
59 | 79 | 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); | |
60 | 86 | |
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); | |
63 | 94 | }; |
64 | 95 | #endif |
@@ -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 | +} |
@@ -14,8 +14,124 @@ | ||
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 | |
17 | +#ifndef _PROPERTY_H | |
18 | +#define _PROPERTY_H | |
19 | + | |
20 | +#include <netinet/in.h> | |
21 | +#include <utils/List.h> | |
22 | + | |
17 | 23 | class Property { |
24 | + const char *mName; | |
25 | + bool mReadOnly; | |
26 | + int mType; | |
27 | + int mNumElements; | |
28 | + | |
18 | 29 | public: |
19 | - static const int NameMaxSize = 128; | |
30 | + static const int NameMaxSize = 128; | |
20 | 31 | 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); | |
21 | 120 | }; |
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 |
@@ -14,6 +14,11 @@ | ||
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 | |
17 | +#include <stdlib.h> | |
18 | +#include <sys/socket.h> | |
19 | +#include <netinet/in.h> | |
20 | +#include <arpa/inet.h> | |
21 | + | |
17 | 22 | #define LOG_TAG "PropertyManager" |
18 | 23 | |
19 | 24 | #include <cutils/log.h> |
@@ -21,103 +26,255 @@ | ||
21 | 26 | #include "PropertyManager.h" |
22 | 27 | |
23 | 28 | PropertyManager::PropertyManager() { |
24 | - mPropertyPairs = new PropertyPairCollection(); | |
29 | + mNamespaces = new PropertyNamespaceCollection(); | |
25 | 30 | pthread_mutex_init(&mLock, NULL); |
26 | 31 | } |
27 | 32 | |
28 | 33 | 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; | |
30 | 52 | } |
31 | 53 | |
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; | |
34 | 56 | |
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); | |
36 | 70 | 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; | |
45 | 83 | } |
46 | - mPropertyPairs->push_back(new PropertyPair(name, pp)); | |
84 | + | |
85 | + ns->getProperties()->push_back(p); | |
47 | 86 | pthread_mutex_unlock(&mLock); |
48 | 87 | return 0; |
49 | 88 | } |
50 | 89 | |
51 | -int PropertyManager::unregisterProperty(const char *name) { | |
52 | - PropertyPairCollection::iterator it; | |
90 | +int PropertyManager::detachProperty(const char *ns_name, Property *p) { | |
91 | + PropertyNamespace *ns; | |
53 | 92 | |
54 | -// LOGD("unregisterProperty(%s)", name); | |
93 | + LOGD("Detaching property %s from namespace %s", p->getName(), ns_name); | |
55 | 94 | 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())) { | |
58 | 106 | delete ((*it)); |
59 | - mPropertyPairs->erase(it); | |
107 | + ns->getProperties()->erase(it); | |
60 | 108 | pthread_mutex_unlock(&mLock); |
61 | 109 | return 0; |
62 | 110 | } |
63 | 111 | } |
112 | + | |
113 | + LOGE("Property %s.%s not found", ns_name, p->getName()); | |
64 | 114 | pthread_mutex_unlock(&mLock); |
65 | 115 | errno = ENOENT; |
66 | 116 | return -1; |
67 | 117 | } |
68 | 118 | |
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 | + | |
69 | 190 | /* |
70 | 191 | * IPropertyManager methods |
71 | 192 | */ |
72 | 193 | |
73 | 194 | int PropertyManager::set(const char *name, const char *value) { |
74 | - PropertyPairCollection::iterator it; | |
75 | 195 | |
196 | + LOGD("set %s = '%s'", name, value); | |
76 | 197 | 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 | + } | |
81 | 215 | } |
82 | 216 | } |
217 | + | |
218 | + LOGE("Property %s not found", name); | |
83 | 219 | pthread_mutex_unlock(&mLock); |
84 | 220 | errno = ENOENT; |
85 | 221 | return -1; |
86 | 222 | } |
87 | 223 | |
88 | 224 | const char *PropertyManager::get(const char *name, char *buffer, size_t max) { |
89 | - PropertyPairCollection::iterator it; | |
90 | - | |
91 | - memset(buffer, 0, max); | |
92 | 225 | 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 | + } | |
97 | 245 | } |
246 | + } | |
98 | 247 | } |
248 | + | |
249 | + LOGE("Property %s not found", name); | |
99 | 250 | pthread_mutex_unlock(&mLock); |
100 | 251 | errno = ENOENT; |
101 | 252 | return NULL; |
102 | 253 | } |
103 | 254 | |
104 | -android::List<char *> *PropertyManager::createPropertyList() { | |
255 | +android::List<char *> *PropertyManager::createPropertyList(const char *prefix) { | |
105 | 256 | android::List<char *> *c = new android::List<char *>(); |
106 | 257 | |
107 | - PropertyPairCollection::iterator it; | |
108 | - | |
109 | 258 | 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 | + } | |
112 | 278 | pthread_mutex_unlock(&mLock); |
113 | 279 | return c; |
114 | 280 | } |
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 | -} |
@@ -22,36 +22,28 @@ | ||
22 | 22 | |
23 | 23 | #include <utils/List.h> |
24 | 24 | |
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" | |
41 | 26 | |
42 | 27 | class PropertyManager { |
43 | - PropertyPairCollection *mPropertyPairs; | |
44 | - pthread_mutex_t mLock; | |
28 | + PropertyNamespaceCollection *mNamespaces; | |
29 | + pthread_mutex_t mLock; | |
45 | 30 | |
46 | 31 | public: |
47 | 32 | 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); | |
52 | 38 | |
53 | 39 | int set(const char *name, const char *value); |
54 | 40 | 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); | |
55 | 47 | }; |
56 | 48 | |
57 | 49 | #endif |
@@ -14,10 +14,10 @@ | ||
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 | |
17 | -#ifndef _ERRORCODE_H | |
18 | -#define _ERRORCODE_H | |
17 | +#ifndef _RESPONSECODE_H | |
18 | +#define _RESPONSECODE_H | |
19 | 19 | |
20 | -class ErrorCode { | |
20 | +class ResponseCode { | |
21 | 21 | public: |
22 | 22 | // 100 series - Requestion action was initiated; expect another reply |
23 | 23 | // before proceeding with a new command. |
@@ -44,5 +44,10 @@ public: | ||
44 | 44 | |
45 | 45 | // 600 series - Unsolicited broadcasts |
46 | 46 | 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; | |
47 | 52 | }; |
48 | 53 | #endif |
@@ -30,7 +30,6 @@ | ||
30 | 30 | #include "Supplicant.h" |
31 | 31 | #include "SupplicantListener.h" |
32 | 32 | #include "NetworkManager.h" |
33 | -#include "ErrorCode.h" | |
34 | 33 | #include "WifiController.h" |
35 | 34 | #include "SupplicantStatus.h" |
36 | 35 |
@@ -114,6 +113,29 @@ bool Supplicant::isStarted() { | ||
114 | 113 | return mServiceManager->isRunning(SUPPLICANT_SERVICE_NAME); |
115 | 114 | } |
116 | 115 | |
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 | +} | |
117 | 139 | SupplicantStatus *Supplicant::getStatus() { |
118 | 140 | char *reply; |
119 | 141 | size_t len = 4096; |
@@ -162,6 +184,7 @@ int Supplicant::refreshNetworkList() { | ||
162 | 184 | return -1; |
163 | 185 | } |
164 | 186 | |
187 | + PropertyManager *pm = NetworkManager::Instance()->getPropMngr(); | |
165 | 188 | pthread_mutex_lock(&mNetworksLock); |
166 | 189 | |
167 | 190 | int num_added = 0; |
@@ -182,7 +205,9 @@ int Supplicant::refreshNetworkList() { | ||
182 | 205 | delete new_wn; |
183 | 206 | } else { |
184 | 207 | 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); | |
186 | 211 | mNetworks->push_back(new_wn); |
187 | 212 | if (new_wn->refresh()) { |
188 | 213 | LOGW("Unable to refresh network id %d (%s)", |
@@ -198,7 +223,9 @@ int Supplicant::refreshNetworkList() { | ||
198 | 223 | for (i = mNetworks->begin(); i != mNetworks->end(); ++i) { |
199 | 224 | if (0) { |
200 | 225 | 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); | |
202 | 229 | delete (*i); |
203 | 230 | i = mNetworks->erase(i); |
204 | 231 | } |
@@ -247,44 +274,98 @@ int Supplicant::connectToSupplicant() { | ||
247 | 274 | return 0; |
248 | 275 | } |
249 | 276 | |
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)); | |
254 | 285 | return -1; |
255 | 286 | } |
287 | + return 0; | |
288 | +} | |
256 | 289 | |
257 | -// LOGD("sendCommand(): -> '%s'", cmd); | |
290 | +int Supplicant::triggerScan() { | |
291 | + char reply[255]; | |
292 | + size_t len = sizeof(reply); | |
258 | 293 | |
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"); | |
263 | 296 | 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)); | |
267 | 307 | return -1; |
268 | 308 | } |
269 | 309 | |
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); | |
271 | 320 | return 0; |
272 | 321 | } |
273 | 322 | |
274 | -int Supplicant::triggerScan(bool active) { | |
275 | - char reply[255]; | |
323 | +int Supplicant::getLinkSpeed() { | |
324 | + char reply[64]; | |
276 | 325 | size_t len = sizeof(reply); |
277 | 326 | |
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)); | |
282 | 329 | return -1; |
283 | 330 | } |
284 | - len = sizeof(reply); | |
285 | 331 | |
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)); | |
288 | 369 | return -1; |
289 | 370 | } |
290 | 371 | return 0; |
@@ -301,7 +382,11 @@ WifiNetwork *Supplicant::createNetwork() { | ||
301 | 382 | reply[strlen(reply) -1] = '\0'; |
302 | 383 | |
303 | 384 | WifiNetwork *wn = new WifiNetwork(mController, this, atoi(reply)); |
385 | + PropertyManager *pm = NetworkManager::Instance()->getPropMngr(); | |
304 | 386 | 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); | |
305 | 390 | mNetworks->push_back(wn); |
306 | 391 | pthread_mutex_unlock(&mNetworksLock); |
307 | 392 | return wn; |
@@ -411,8 +496,9 @@ int Supplicant::setNetworkVar(int networkId, const char *var, const char *val) { | ||
411 | 496 | char reply[255]; |
412 | 497 | size_t len = sizeof(reply) -1; |
413 | 498 | |
499 | + LOGD("netid %d, var '%s' = '%s'", networkId, var, val); | |
414 | 500 | char *tmp; |
415 | - asprintf(&tmp, "SET_NETWORK %d %s \"%s\"", networkId, var, val); | |
501 | + asprintf(&tmp, "SET_NETWORK %d %s %s", networkId, var, val); | |
416 | 502 | if (sendCommand(tmp, reply, &len)) { |
417 | 503 | free(tmp); |
418 | 504 | return -1; |
@@ -457,6 +543,95 @@ int Supplicant::enableNetwork(int networkId, bool enabled) { | ||
457 | 543 | return 0; |
458 | 544 | } |
459 | 545 | |
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 | + | |
460 | 635 | |
461 | 636 | int Supplicant::retrieveInterfaceName() { |
462 | 637 | char reply[255]; |
@@ -469,3 +644,34 @@ int Supplicant::retrieveInterfaceName() { | ||
469 | 644 | mInterfaceName = strdup(reply); |
470 | 645 | return 0; |
471 | 646 | } |
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 | +} |
@@ -30,7 +30,6 @@ class SupplicantStatus; | ||
30 | 30 | #include "ISupplicantEventHandler.h" |
31 | 31 | |
32 | 32 | class Supplicant { |
33 | -private: | |
34 | 33 | struct wpa_ctrl *mCtrl; |
35 | 34 | struct wpa_ctrl *mMonitor; |
36 | 35 | SupplicantListener *mListener; |
@@ -50,7 +49,8 @@ public: | ||
50 | 49 | int stop(); |
51 | 50 | bool isStarted(); |
52 | 51 | |
53 | - int triggerScan(bool active); | |
52 | + int setScanMode(bool active); | |
53 | + int triggerScan(); | |
54 | 54 | |
55 | 55 | WifiNetwork *createNetwork(); |
56 | 56 | WifiNetwork *lookupNetwork(int networkId); |
@@ -63,6 +63,21 @@ public: | ||
63 | 63 | size_t max); |
64 | 64 | int enableNetwork(int networkId, bool enabled); |
65 | 65 | |
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 | + | |
66 | 81 | SupplicantStatus *getStatus(); |
67 | 82 | |
68 | 83 | Controller *getController() { return (Controller *) mController; } |
@@ -23,25 +23,25 @@ | ||
23 | 23 | |
24 | 24 | char *SupplicantState::toString(int val, char *buffer, int max) { |
25 | 25 | if (val == SupplicantState::UNKNOWN) |
26 | - strncpy(buffer, "Unknown", max); | |
26 | + strncpy(buffer, "UNKNOWN", max); | |
27 | 27 | else if (val == SupplicantState::DISCONNECTED) |
28 | - strncpy(buffer, "Disconnected", max); | |
28 | + strncpy(buffer, "DISCONNECTED", max); | |
29 | 29 | else if (val == SupplicantState::INACTIVE) |
30 | - strncpy(buffer, "Inactive", max); | |
30 | + strncpy(buffer, "INACTIVE", max); | |
31 | 31 | else if (val == SupplicantState::SCANNING) |
32 | - strncpy(buffer, "Scanning", max); | |
32 | + strncpy(buffer, "SCANNING", max); | |
33 | 33 | else if (val == SupplicantState::ASSOCIATING) |
34 | - strncpy(buffer, "Associating", max); | |
34 | + strncpy(buffer, "ASSOCIATING", max); | |
35 | 35 | else if (val == SupplicantState::ASSOCIATED) |
36 | - strncpy(buffer, "Associated", max); | |
36 | + strncpy(buffer, "ASSOCIATED", max); | |
37 | 37 | else if (val == SupplicantState::FOURWAY_HANDSHAKE) |
38 | - strncpy(buffer, "Fourway Handshake", max); | |
38 | + strncpy(buffer, "FOURWAY_HANDSHAKE", max); | |
39 | 39 | else if (val == SupplicantState::GROUP_HANDSHAKE) |
40 | - strncpy(buffer, "Group Handshake", max); | |
40 | + strncpy(buffer, "GROUP_HANDSHAKE", max); | |
41 | 41 | else if (val == SupplicantState::COMPLETED) |
42 | - strncpy(buffer, "Completed", max); | |
42 | + strncpy(buffer, "COMPLETED", max); | |
43 | 43 | else if (val == SupplicantState::IDLE) |
44 | - strncpy(buffer, "Idle", max); | |
44 | + strncpy(buffer, "IDLE", max); | |
45 | 45 | else |
46 | 46 | strncpy(buffer, "(internal error)", max); |
47 | 47 |
@@ -51,6 +51,7 @@ int TiwlanWifiController::powerUp() { | ||
51 | 51 | int TiwlanWifiController::powerDown() { |
52 | 52 | if (mEventListener) { |
53 | 53 | delete mEventListener; |
54 | + shutdown(mListenerSock, SHUT_RDWR); | |
54 | 55 | close(mListenerSock); |
55 | 56 | mListenerSock = -1; |
56 | 57 | mEventListener = NULL; |
@@ -77,7 +78,8 @@ int TiwlanWifiController::loadFirmware() { | ||
77 | 78 | LOGD("Firmware loaded OK"); |
78 | 79 | |
79 | 80 | if (startDriverEventListener()) { |
80 | - LOGW("Failed to start driver event listener"); | |
81 | + LOGW("Failed to start driver event listener (%s)", | |
82 | + strerror(errno)); | |
81 | 83 | } |
82 | 84 | |
83 | 85 | return 0; |
@@ -95,32 +97,48 @@ int TiwlanWifiController::loadFirmware() { | ||
95 | 97 | |
96 | 98 | int TiwlanWifiController::startDriverEventListener() { |
97 | 99 | struct sockaddr_in addr; |
98 | - int s; | |
99 | 100 | |
100 | - if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) | |
101 | + if (mListenerSock != -1) { | |
102 | + LOGE("Listener already started!"); | |
103 | + errno = EBUSY; | |
101 | 104 | 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 | + } | |
102 | 111 | |
103 | 112 | memset(&addr, 0, sizeof(addr)); |
104 | 113 | addr.sin_family = AF_INET; |
105 | 114 | addr.sin_addr.s_addr = htonl(INADDR_ANY); |
106 | 115 | addr.sin_port = htons(TI_DRIVER_MSG_PORT); |
107 | 116 | |
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; | |
111 | 122 | } |
112 | 123 | |
113 | - mEventListener = new TiwlanEventListener(s); | |
124 | + mEventListener = new TiwlanEventListener(mListenerSock); | |
114 | 125 | |
115 | 126 | if (mEventListener->startListener()) { |
116 | 127 | LOGE("Error starting driver listener (%s)", strerror(errno)); |
128 | + goto out_err; | |
129 | + } | |
130 | + return 0; | |
131 | +out_err: | |
132 | + if (mEventListener) { | |
117 | 133 | delete mEventListener; |
118 | 134 | mEventListener = NULL; |
119 | - close(s); | |
120 | - return -1; | |
121 | 135 | } |
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; | |
124 | 142 | } |
125 | 143 | |
126 | 144 | bool TiwlanWifiController::isFirmwareLoaded() { |
@@ -27,56 +27,66 @@ | ||
27 | 27 | |
28 | 28 | VpnController::VpnController(PropertyManager *propmngr, |
29 | 29 | IControllerHandler *handlers) : |
30 | - Controller("VPN", propmngr, handlers) { | |
30 | + Controller("vpn", propmngr, handlers) { | |
31 | 31 | mEnabled = false; |
32 | + | |
33 | + mStaticProperties.propEnabled = new VpnEnabledProperty(this); | |
34 | + mDynamicProperties.propGateway = new IPV4AddressPropertyHelper("Gateway", | |
35 | + false, | |
36 | + &mGateway); | |
32 | 37 | } |
33 | 38 | |
34 | 39 | int VpnController::start() { |
35 | - mPropMngr->registerProperty("vpn.enabled", this); | |
40 | + mPropMngr->attachProperty("vpn", mStaticProperties.propEnabled); | |
36 | 41 | return 0; |
37 | 42 | } |
38 | 43 | |
39 | 44 | int VpnController::stop() { |
40 | - mPropMngr->unregisterProperty("vpn.enabled"); | |
45 | + mPropMngr->detachProperty("vpn", mStaticProperties.propEnabled); | |
41 | 46 | return 0; |
42 | 47 | } |
43 | 48 | |
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 | +} | |
52 | 56 | |
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 | +} | |
68 | 63 | |
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; | |
70 | 69 | } |
71 | 70 | |
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 | + } | |
79 | 88 | } |
80 | - | |
81 | - return Controller::get(name, buffer, maxsize); | |
89 | + if (!rc) | |
90 | + mVc->mEnabled = value; | |
91 | + return rc; | |
82 | 92 | } |
@@ -24,11 +24,63 @@ | ||
24 | 24 | class IControllerHandler; |
25 | 25 | |
26 | 26 | 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 | + | |
27 | 71 | bool mEnabled; |
28 | 72 | /* |
29 | 73 | * Gateway of the VPN server to connect to |
30 | 74 | */ |
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; | |
32 | 84 | |
33 | 85 | public: |
34 | 86 | VpnController(PropertyManager *propmngr, IControllerHandler *handlers); |
@@ -37,13 +89,9 @@ public: | ||
37 | 89 | virtual int start(); |
38 | 90 | virtual int stop(); |
39 | 91 | |
40 | - virtual int set(const char *name, const char *value); | |
41 | - virtual const char *get(const char *name, char *buffer, size_t maxlen); | |
42 | - | |
43 | 92 | protected: |
44 | 93 | virtual int enable() = 0; |
45 | 94 | virtual int disable() = 0; |
46 | - | |
47 | 95 | }; |
48 | 96 | |
49 | 97 | #endif |
@@ -23,9 +23,8 @@ | ||
23 | 23 | |
24 | 24 | #include "Supplicant.h" |
25 | 25 | #include "WifiController.h" |
26 | -#include "WifiScanner.h" | |
27 | 26 | #include "NetworkManager.h" |
28 | -#include "ErrorCode.h" | |
27 | +#include "ResponseCode.h" | |
29 | 28 | #include "WifiNetwork.h" |
30 | 29 | #include "ISupplicantEventHandler.h" |
31 | 30 | #include "SupplicantState.h" |
@@ -37,11 +36,12 @@ | ||
37 | 36 | #include "SupplicantStateChangeEvent.h" |
38 | 37 | #include "SupplicantConnectionTimeoutEvent.h" |
39 | 38 | #include "SupplicantDisconnectedEvent.h" |
39 | +#include "WifiStatusPoller.h" | |
40 | 40 | |
41 | 41 | WifiController::WifiController(PropertyManager *mPropMngr, |
42 | 42 | IControllerHandler *handlers, |
43 | 43 | char *modpath, char *modname, char *modargs) : |
44 | - Controller("WIFI", mPropMngr, handlers) { | |
44 | + Controller("wifi", mPropMngr, handlers) { | |
45 | 45 | strncpy(mModulePath, modpath, sizeof(mModulePath)); |
46 | 46 | strncpy(mModuleName, modname, sizeof(mModuleName)); |
47 | 47 | strncpy(mModuleArgs, modargs, sizeof(mModuleArgs)); |
@@ -49,22 +49,59 @@ WifiController::WifiController(PropertyManager *mPropMngr, | ||
49 | 49 | mLatestScanResults = new ScanResultCollection(); |
50 | 50 | pthread_mutex_init(&mLatestScanResultsLock, NULL); |
51 | 51 | |
52 | - mSupplicant = new Supplicant(this, this); | |
53 | - mScanner = new WifiScanner(mSupplicant, 10); | |
54 | - mCurrentScanMode = 0; | |
52 | + pthread_mutex_init(&mLock, NULL); | |
55 | 53 | |
54 | + mSupplicant = new Supplicant(this, this); | |
55 | + mActiveScan = false; | |
56 | 56 | 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; | |
57 | 65 | |
58 | 66 | 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); | |
59 | 90 | } |
60 | 91 | |
61 | 92 | 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); | |
63 | 97 | return 0; |
64 | 98 | } |
65 | 99 | |
66 | 100 | 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); | |
68 | 105 | return 0; |
69 | 106 | } |
70 | 107 |
@@ -114,9 +151,21 @@ int WifiController::enable() { | ||
114 | 151 | if (mSupplicant->refreshNetworkList()) |
115 | 152 | LOGW("Error getting list of networks (%s)", strerror(errno)); |
116 | 153 | |
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); | |
120 | 169 | |
121 | 170 | LOGI("Enabled successfully"); |
122 | 171 | return 0; |
@@ -135,17 +184,87 @@ out_powerdown: | ||
135 | 184 | return -1; |
136 | 185 | } |
137 | 186 | |
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 | + | |
138 | 248 | void WifiController::sendStatusBroadcast(const char *msg) { |
139 | 249 | NetworkManager::Instance()-> |
140 | 250 | getBroadcaster()-> |
141 | - sendBroadcast(ErrorCode::UnsolicitedInformational, msg, false); | |
251 | + sendBroadcast(ResponseCode::UnsolicitedInformational, msg, false); | |
142 | 252 | } |
143 | 253 | |
144 | 254 | int WifiController::disable() { |
145 | 255 | |
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); | |
149 | 268 | |
150 | 269 | if (mSupplicant->isStarted()) { |
151 | 270 | sendStatusBroadcast("Stopping WPA Supplicant"); |
@@ -178,35 +297,61 @@ int WifiController::loadFirmware() { | ||
178 | 297 | return 0; |
179 | 298 | } |
180 | 299 | |
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 | + } | |
183 | 306 | |
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 | + } | |
186 | 318 | |
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 | +} | |
194 | 323 | |
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); | |
196 | 334 | return rc; |
197 | 335 | } |
198 | 336 | |
199 | 337 | WifiNetwork *WifiController::createNetwork() { |
338 | + pthread_mutex_lock(&mLock); | |
200 | 339 | WifiNetwork *wn = mSupplicant->createNetwork(); |
340 | + pthread_mutex_unlock(&mLock); | |
201 | 341 | return wn; |
202 | 342 | } |
203 | 343 | |
204 | 344 | int WifiController::removeNetwork(int networkId) { |
345 | + pthread_mutex_lock(&mLock); | |
205 | 346 | WifiNetwork *wn = mSupplicant->lookupNetwork(networkId); |
206 | 347 | |
207 | - if (!wn) | |
348 | + if (!wn) { | |
349 | + pthread_mutex_unlock(&mLock); | |
208 | 350 | return -1; |
209 | - return mSupplicant->removeNetwork(wn); | |
351 | + } | |
352 | + int rc = mSupplicant->removeNetwork(wn); | |
353 | + pthread_mutex_unlock(&mLock); | |
354 | + return rc; | |
210 | 355 | } |
211 | 356 | |
212 | 357 | ScanResultCollection *WifiController::createScanResults() { |
@@ -225,45 +370,59 @@ WifiNetworkCollection *WifiController::createNetworkList() { | ||
225 | 370 | return mSupplicant->createNetworkList(); |
226 | 371 | } |
227 | 372 | |
228 | -int WifiController::set(const char *name, const char *value) { | |
373 | +int WifiController::setPacketFilter(bool enable) { | |
229 | 374 | int rc; |
230 | 375 | |
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(); | |
233 | 381 | |
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); | |
249 | 385 | return rc; |
250 | 386 | } |
251 | 387 | |
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); | |
253 | 392 | |
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(); | |
263 | 395 | 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 | +} | |
265 | 403 | |
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; | |
267 | 426 | } |
268 | 427 | |
269 | 428 | void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) { |
@@ -296,6 +455,7 @@ void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) { | ||
296 | 455 | return; |
297 | 456 | } |
298 | 457 | |
458 | + mCurrentlyConnectedNetworkId = ss->getId(); | |
299 | 459 | if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) { |
300 | 460 | LOGW("Error looking up connected network id %d (%s)", |
301 | 461 | ss->getId(), strerror(errno)); |
@@ -303,7 +463,7 @@ void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) { | ||
303 | 463 | } |
304 | 464 | |
305 | 465 | delete ss; |
306 | - mHandlers->onInterfaceConnected(this, wn->getIfaceCfg()); | |
466 | + mHandlers->onInterfaceConnected(this); | |
307 | 467 | } |
308 | 468 | |
309 | 469 | void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) { |
@@ -314,6 +474,10 @@ void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) { | ||
314 | 474 | return; |
315 | 475 | } |
316 | 476 | |
477 | + mNumScanResultsSinceLastStateChange++; | |
478 | + if (mNumScanResultsSinceLastStateChange >= 3) | |
479 | + mIsSupplicantSearching = false; | |
480 | + | |
317 | 481 | size_t len = 4096; |
318 | 482 | |
319 | 483 | if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) { |
@@ -346,10 +510,14 @@ void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) { | ||
346 | 510 | while((linep = strtok_r(NULL, "\n", &linep_next))) |
347 | 511 | mLatestScanResults->push_back(new ScanResult(linep)); |
348 | 512 | |
513 | + // Switch handling of scan results back to normal mode | |
514 | + mSupplicant->setApScanMode(1); | |
515 | + | |
349 | 516 | char *tmp; |
350 | 517 | asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size()); |
351 | 518 | NetworkManager::Instance()->getBroadcaster()-> |
352 | - sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false); | |
519 | + sendBroadcast(ResponseCode::ScanResultsReady, | |
520 | + tmp, false); | |
353 | 521 | free(tmp); |
354 | 522 | pthread_mutex_unlock(&mLatestScanResultsLock); |
355 | 523 | free(reply); |
@@ -359,11 +527,35 @@ void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) { | ||
359 | 527 | char tmp[32]; |
360 | 528 | char tmp2[32]; |
361 | 529 | |
530 | + if (evt->getState() == mSupplicantState) | |
531 | + return; | |
532 | + | |
362 | 533 | LOGD("onStateChangeEvent(%s -> %s)", |
363 | 534 | SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)), |
364 | 535 | SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2))); |
365 | 536 | |
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 | + | |
366 | 547 | 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); | |
367 | 559 | } |
368 | 560 | |
369 | 561 | void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) { |
@@ -371,7 +563,8 @@ void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent * | ||
371 | 563 | } |
372 | 564 | |
373 | 565 | void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) { |
374 | - mHandlers->onInterfaceDisconnected(this, getBoundInterface()); | |
566 | + mCurrentlyConnectedNetworkId = -1; | |
567 | + mHandlers->onInterfaceDisconnected(this); | |
375 | 568 | } |
376 | 569 | |
377 | 570 | #if 0 |
@@ -411,3 +604,216 @@ void WifiController::onDriverStateEvent(SupplicantEvent *evt) { | ||
411 | 604 | LOGD("onDriverStateEvent(%s)", evt->getEvent()); |
412 | 605 | } |
413 | 606 | #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 | + |
@@ -23,41 +23,207 @@ | ||
23 | 23 | #include "ScanResult.h" |
24 | 24 | #include "WifiNetwork.h" |
25 | 25 | #include "ISupplicantEventHandler.h" |
26 | +#include "IWifiStatusPollerHandler.h" | |
26 | 27 | |
27 | 28 | class NetInterface; |
28 | 29 | class Supplicant; |
29 | -class WifiScanner; | |
30 | 30 | class SupplicantAssociatingEvent; |
31 | 31 | class SupplicantAssociatedEvent; |
32 | 32 | class SupplicantConnectedEvent; |
33 | 33 | class SupplicantScanResultsEvent; |
34 | 34 | class SupplicantStateChangeEvent; |
35 | 35 | class SupplicantDisconnectedEvent; |
36 | +class WifiStatusPoller; | |
36 | 37 | |
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 { | |
42 | 41 | |
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 | + }; | |
48 | 177 | |
49 | -private: | |
50 | 178 | Supplicant *mSupplicant; |
51 | 179 | char mModulePath[255]; |
52 | 180 | char mModuleName[64]; |
53 | 181 | char mModuleArgs[255]; |
54 | 182 | |
55 | - uint32_t mCurrentScanMode; | |
56 | - WifiScanner *mScanner; | |
57 | 183 | 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; | |
58 | 195 | |
59 | 196 | ScanResultCollection *mLatestScanResults; |
60 | 197 | 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; | |
61 | 227 | |
62 | 228 | bool mEnabled; |
63 | 229 |
@@ -72,9 +238,6 @@ public: | ||
72 | 238 | int removeNetwork(int networkId); |
73 | 239 | WifiNetworkCollection *createNetworkList(); |
74 | 240 | |
75 | - virtual int set(const char *name, const char *value); | |
76 | - virtual const char *get(const char *name, char *buffer, size_t maxlen); | |
77 | - | |
78 | 241 | ScanResultCollection *createScanResults(); |
79 | 242 | |
80 | 243 | char *getModulePath() { return mModulePath; } |
@@ -94,18 +257,25 @@ protected: | ||
94 | 257 | |
95 | 258 | private: |
96 | 259 | void sendStatusBroadcast(const char *msg); |
97 | - int setScanMode(uint32_t mode); | |
260 | + int setActiveScan(bool active); | |
261 | + int triggerScan(); | |
98 | 262 | int enable(); |
99 | 263 | 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); | |
100 | 270 | |
101 | 271 | // 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); | |
109 | 279 | #if 0 |
110 | 280 | virtual void onTerminatingEvent(SupplicantEvent *evt); |
111 | 281 | virtual void onPasswordChangedEvent(SupplicantEvent *evt); |
@@ -118,6 +288,9 @@ private: | ||
118 | 288 | virtual void onDriverStateEvent(SupplicantEvent *evt); |
119 | 289 | #endif |
120 | 290 | |
291 | + void onStatusPollInterval(); | |
292 | + | |
293 | + int verifyNotSuspended(); | |
121 | 294 | }; |
122 | 295 | |
123 | 296 | #endif |
@@ -26,17 +26,7 @@ | ||
26 | 26 | #include "WifiNetwork.h" |
27 | 27 | #include "Supplicant.h" |
28 | 28 | #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 | + | |
40 | 30 | WifiNetwork::WifiNetwork() { |
41 | 31 | // This is private to restrict copy constructors |
42 | 32 | } |
@@ -76,11 +66,11 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data) | ||
76 | 66 | mDefaultKeyIndex = -1; |
77 | 67 | mPriority = -1; |
78 | 68 | 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; | |
84 | 74 | mEnabled = true; |
85 | 75 | |
86 | 76 | if (flags && flags[0] != '\0') { |
@@ -90,11 +80,8 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, const char *data) | ||
90 | 80 | LOGW("Unsupported flags '%s'", flags); |
91 | 81 | } |
92 | 82 | |
93 | - char *tmp2; | |
94 | - asprintf(&tmp2, "wifi.net.%d", mNetid); | |
95 | - mIfaceCfg = new InterfaceConfig(tmp2); | |
96 | - free(tmp2); | |
97 | 83 | free(tmp); |
84 | + createProperties(); | |
98 | 85 | } |
99 | 86 | |
100 | 87 | WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, int networkId) { |
@@ -108,17 +95,13 @@ WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, int networkId) { | ||
108 | 95 | mDefaultKeyIndex = -1; |
109 | 96 | mPriority = -1; |
110 | 97 | 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; | |
116 | 103 | mEnabled = false; |
117 | - | |
118 | - char *tmp2; | |
119 | - asprintf(&tmp2, "wifi.net.%d", mNetid); | |
120 | - mIfaceCfg = new InterfaceConfig(tmp2); | |
121 | - free(tmp2); | |
104 | + createProperties(); | |
122 | 105 | } |
123 | 106 | |
124 | 107 | WifiNetwork *WifiNetwork::clone() { |
@@ -140,15 +123,35 @@ WifiNetwork *WifiNetwork::clone() { | ||
140 | 123 | r->mPriority = mPriority; |
141 | 124 | if (mHiddenSsid) |
142 | 125 | 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; | |
148 | 131 | return r; |
149 | 132 | } |
150 | 133 | |
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 | + | |
151 | 152 | WifiNetwork::~WifiNetwork() { |
153 | + if (mPropNamespace) | |
154 | + free(mPropNamespace); | |
152 | 155 | if (mSsid) |
153 | 156 | free(mSsid); |
154 | 157 | if (mBssid) |
@@ -162,13 +165,26 @@ WifiNetwork::~WifiNetwork() { | ||
162 | 165 | |
163 | 166 | if (mHiddenSsid) |
164 | 167 | 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; | |
167 | 182 | } |
168 | 183 | |
169 | 184 | int WifiNetwork::refresh() { |
170 | 185 | char buffer[255]; |
171 | 186 | size_t len; |
187 | + uint32_t mask; | |
172 | 188 | |
173 | 189 | len = sizeof(buffer); |
174 | 190 | if (mSuppl->getNetworkVar(mNetid, "psk", buffer, len)) |
@@ -198,46 +214,47 @@ int WifiNetwork::refresh() { | ||
198 | 214 | |
199 | 215 | len = sizeof(buffer); |
200 | 216 | 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 | + } | |
221 | 222 | } |
222 | 223 | |
223 | 224 | len = sizeof(buffer); |
224 | 225 | 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 | + } | |
226 | 231 | } |
227 | 232 | |
228 | 233 | len = sizeof(buffer); |
229 | 234 | 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 | + } | |
231 | 240 | } |
232 | 241 | |
233 | 242 | len = sizeof(buffer); |
234 | 243 | 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 | + } | |
236 | 249 | } |
237 | 250 | |
238 | 251 | len = sizeof(buffer); |
239 | 252 | 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 | + } | |
241 | 258 | } |
242 | 259 | |
243 | 260 | return 0; |
@@ -246,179 +263,10 @@ out_err: | ||
246 | 263 | return -1; |
247 | 264 | } |
248 | 265 | |
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 | - | |
420 | 266 | 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)) | |
422 | 270 | return -1; |
423 | 271 | if (mSsid) |
424 | 272 | free(mSsid); |
@@ -436,7 +284,9 @@ int WifiNetwork::setBssid(const char *bssid) { | ||
436 | 284 | } |
437 | 285 | |
438 | 286 | 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)) | |
440 | 290 | return -1; |
441 | 291 | |
442 | 292 | if (mPsk) |
@@ -491,28 +341,34 @@ int WifiNetwork::setHiddenSsid(const char *ssid) { | ||
491 | 341 | return 0; |
492 | 342 | } |
493 | 343 | |
494 | -int WifiNetwork::setAllowedKeyManagement(uint32_t mask) { | |
495 | - char accum[255]; | |
344 | +int WifiNetwork::setKeyManagement(uint32_t mask) { | |
345 | + char accum[64] = {'\0'}; | |
496 | 346 | |
497 | 347 | if (mask == KeyManagementMask::NONE) |
498 | 348 | strcpy(accum, "NONE"); |
499 | 349 | 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 | + } | |
506 | 362 | } |
507 | 363 | |
508 | 364 | if (mSuppl->setNetworkVar(mNetid, "key_mgmt", accum)) |
509 | 365 | return -1; |
510 | - mAllowedKeyManagement = mask; | |
366 | + mKeyManagement = mask; | |
511 | 367 | return 0; |
512 | 368 | } |
513 | 369 | |
514 | -int WifiNetwork::setAllowedProtocols(uint32_t mask) { | |
515 | - char accum[255]; | |
370 | +int WifiNetwork::setProtocols(uint32_t mask) { | |
371 | + char accum[64]; | |
516 | 372 | |
517 | 373 | accum[0] = '\0'; |
518 | 374 |
@@ -524,15 +380,18 @@ int WifiNetwork::setAllowedProtocols(uint32_t mask) { | ||
524 | 380 | |
525 | 381 | if (mSuppl->setNetworkVar(mNetid, "proto", accum)) |
526 | 382 | return -1; |
527 | - mAllowedProtocols = mask; | |
383 | + mProtocols = mask; | |
528 | 384 | return 0; |
529 | 385 | } |
530 | 386 | |
531 | -int WifiNetwork::setAllowedAuthAlgorithms(uint32_t mask) { | |
532 | - char accum[255]; | |
387 | +int WifiNetwork::setAuthAlgorithms(uint32_t mask) { | |
388 | + char accum[64]; | |
533 | 389 | |
534 | 390 | accum[0] = '\0'; |
535 | 391 | |
392 | + if (mask == 0) | |
393 | + strcpy(accum, ""); | |
394 | + | |
536 | 395 | if (mask & AuthenticationAlgorithmMask::OPEN) |
537 | 396 | strcpy(accum, "OPEN "); |
538 | 397 |
@@ -545,12 +404,14 @@ int WifiNetwork::setAllowedAuthAlgorithms(uint32_t mask) { | ||
545 | 404 | if (mSuppl->setNetworkVar(mNetid, "auth_alg", accum)) |
546 | 405 | return -1; |
547 | 406 | |
548 | - mAllowedAuthAlgorithms = mask; | |
407 | + mAuthAlgorithms = mask; | |
549 | 408 | return 0; |
550 | 409 | } |
551 | 410 | |
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'; | |
554 | 415 | |
555 | 416 | if (mask == PairwiseCiphersMask::NONE) |
556 | 417 | strcpy(accum, "NONE"); |
@@ -564,12 +425,14 @@ int WifiNetwork::setAllowedPairwiseCiphers(uint32_t mask) { | ||
564 | 425 | if (mSuppl->setNetworkVar(mNetid, "pairwise", accum)) |
565 | 426 | return -1; |
566 | 427 | |
567 | - mAllowedPairwiseCiphers = mask; | |
428 | + mPairwiseCiphers = mask; | |
568 | 429 | return 0; |
569 | 430 | } |
570 | 431 | |
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'; | |
573 | 436 | |
574 | 437 | if (mask & GroupCiphersMask::WEP40) |
575 | 438 | strcat(accum, "WEP40 "); |
@@ -582,7 +445,7 @@ int WifiNetwork::setAllowedGroupCiphers(uint32_t mask) { | ||
582 | 445 | |
583 | 446 | if (mSuppl->setNetworkVar(mNetid, "group", accum)) |
584 | 447 | return -1; |
585 | - mAllowedGroupCiphers = mask; | |
448 | + mGroupCiphers = mask; | |
586 | 449 | return 0; |
587 | 450 | } |
588 | 451 |
@@ -594,7 +457,7 @@ int WifiNetwork::setEnabled(bool enabled) { | ||
594 | 457 | errno = EAGAIN; |
595 | 458 | return -1; |
596 | 459 | } |
597 | - if (getAllowedKeyManagement() == KeyManagementMask::UNKNOWN) { | |
460 | + if (getKeyManagement() == KeyManagementMask::UNKNOWN) { | |
598 | 461 | LOGE("Cannot enable network when KeyManagement is not set"); |
599 | 462 | errno = EAGAIN; |
600 | 463 | return -1; |
@@ -608,29 +471,500 @@ int WifiNetwork::setEnabled(bool enabled) { | ||
608 | 471 | return 0; |
609 | 472 | } |
610 | 473 | |
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 | +} | |
615 | 569 | |
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); | |
619 | 593 | return -1; |
620 | 594 | } |
621 | - free(tmp); | |
622 | 595 | } |
596 | + free(v_tmp); | |
623 | 597 | return 0; |
624 | 598 | } |
625 | 599 | |
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 | +} | |
630 | 634 | |
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 | + } | |
634 | 659 | } |
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); | |
635 | 712 | return 0; |
636 | 713 | } |
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 | +} |
@@ -21,6 +21,10 @@ | ||
21 | 21 | |
22 | 22 | #include <utils/List.h> |
23 | 23 | |
24 | +#include "Property.h" | |
25 | + | |
26 | +class PropertyManager; | |
27 | + | |
24 | 28 | class KeyManagementMask { |
25 | 29 | public: |
26 | 30 | static const uint32_t UNKNOWN = 0; |
@@ -60,19 +64,140 @@ public: | ||
60 | 64 | }; |
61 | 65 | |
62 | 66 | class Supplicant; |
63 | -class InterfaceConfig; | |
64 | 67 | class Controller; |
65 | 68 | class WifiController; |
66 | 69 | |
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 | + }; | |
72 | 198 | |
73 | 199 | private: |
74 | 200 | Supplicant *mSuppl; |
75 | - InterfaceConfig *mIfaceCfg; | |
76 | 201 | WifiController *mController; |
77 | 202 | |
78 | 203 | /* |
@@ -128,33 +253,49 @@ private: | ||
128 | 253 | /* |
129 | 254 | * The set of key management protocols supported by this configuration. |
130 | 255 | */ |
131 | - uint32_t mAllowedKeyManagement; | |
256 | + uint32_t mKeyManagement; | |
132 | 257 | |
133 | 258 | /* |
134 | 259 | * The set of security protocols supported by this configuration. |
135 | 260 | */ |
136 | - uint32_t mAllowedProtocols; | |
261 | + uint32_t mProtocols; | |
137 | 262 | |
138 | 263 | /* |
139 | 264 | * The set of authentication protocols supported by this configuration. |
140 | 265 | */ |
141 | - uint32_t mAllowedAuthAlgorithms; | |
266 | + uint32_t mAuthAlgorithms; | |
142 | 267 | |
143 | 268 | /* |
144 | 269 | * The set of pairwise ciphers for WPA supported by this configuration. |
145 | 270 | */ |
146 | - uint32_t mAllowedPairwiseCiphers; | |
271 | + uint32_t mPairwiseCiphers; | |
147 | 272 | |
148 | 273 | /* |
149 | 274 | * The set of group ciphers for WPA supported by this configuration. |
150 | 275 | */ |
151 | - uint32_t mAllowedGroupCiphers; | |
276 | + uint32_t mGroupCiphers; | |
152 | 277 | |
153 | 278 | /* |
154 | 279 | * Set if this Network is enabled |
155 | 280 | */ |
156 | 281 | bool mEnabled; |
157 | 282 | |
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; | |
158 | 299 | private: |
159 | 300 | WifiNetwork(); |
160 | 301 |
@@ -165,8 +306,8 @@ public: | ||
165 | 306 | virtual ~WifiNetwork(); |
166 | 307 | |
167 | 308 | WifiNetwork *clone(); |
168 | - int registerProperties(); | |
169 | - int unregisterProperties(); | |
309 | + int attachProperties(PropertyManager *pm, const char *nsName); | |
310 | + int detachProperties(PropertyManager *pm, const char *nsName); | |
170 | 311 | |
171 | 312 | int getNetworkId() { return mNetid; } |
172 | 313 | const char *getSsid() { return mSsid; } |
@@ -176,19 +317,14 @@ public: | ||
176 | 317 | int getDefaultKeyIndex() { return mDefaultKeyIndex; } |
177 | 318 | int getPriority() { return mPriority; } |
178 | 319 | 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; } | |
184 | 325 | bool getEnabled() { return mEnabled; } |
185 | 326 | Controller *getController() { return (Controller *) mController; } |
186 | 327 | |
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 | - | |
192 | 328 | int setEnabled(bool enabled); |
193 | 329 | int setSsid(const char *ssid); |
194 | 330 | int setBssid(const char *bssid); |
@@ -197,14 +333,22 @@ public: | ||
197 | 333 | int setDefaultKeyIndex(int idx); |
198 | 334 | int setPriority(int pri); |
199 | 335 | 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); | |
205 | 341 | |
206 | 342 | // XXX:Should this really be exposed?.. meh |
207 | 343 | 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(); | |
208 | 352 | }; |
209 | 353 | |
210 | 354 | typedef android::List<WifiNetwork *> WifiNetworkCollection; |
@@ -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 | +} |
@@ -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 |