nexus: Rollup update for nexus
nexus: Change field separator from : to ' '
Signed-off-by: San Mehat <san@google.com>
nexus: Add some prototypes for stuff to come
Signed-off-by: San Mehat <san@google.com>
nexus: Add some TODOs
Signed-off-by: San Mehat <san@google.com>
libsysutils: Put a proper token parser into the FrameworkListener which
supports minimal \ escapes and quotes
Signed-off-by: San Mehat <san@google.com>
nexus: Fix a lot of bugs
Signed-off-by: San Mehat <san@google.com>
libsysutils: Remove some debugging
Signed-off-by: San Mehat <san@google.com>
nexus: Send broadcasts for supplicant state changes
Signed-off-by: San Mehat <san@google.com>
nexus: Plumb DHCP listener state changes to NetworkManager
Signed-off-by: San Mehat <san@google.com>
nexus: Make the SupplicantState strings more parsable
Signed-off-by: San Mehat <san@google.com>
nexus: Broadcast a message when dhcp state changes.
Signed-off-by: San Mehat <san@google.com>
nexus: Add a few new response codes
Signed-off-by: San Mehat <san@google.com>
nexus: Rename ErrorCode -> ResponseCode
Signed-off-by: San Mehat <san@google.com>
nexus: Add DHCP event broadcasting. Also adds the framework for
tracking supplicant 'searching-for-AP' state
Signed-off-by: San Mehat <san@google.com>
nexus: REmove WifiScanner
Signed-off-by: San Mehat <san@google.com>
nexus: Change the way scanning works. scanmode can now be selected
independantly of triggering a scan. Also adds rxfilter support
Signed-off-by: San Mehat <san@google.com>
nexus: Add support for configuring bluetooth coexistence scanning and modes
Signed-off-by: San Mehat <san@google.com>
nexus: use case insensitive match for property names
Signed-off-by: San Mehat <san@google.com>
nexus: Rollup of a bunch of stuff:
- 'list' command now takes an argument to match against
- InterfaceConfig has been moved into the Controller base (for now)
- DhcpClient now has some rudimentry locking
- process 'ADDRINFO' messages from dhcpcd
- Drop tertiary dns
Signed-off-by: San Mehat <san@google.com>
nexus: Clean up some of the supplicant variable parsing and add 'wifi.current'
Signed-off-by: San Mehat <san@google.com>
nexus: Add driver-stop/start, initial suspend support
Signed-off-by: San Mehat <san@google.com>
nexus: Add Controller suspend/resume callbacks, as well as locking
Signed-off-by: San Mehat <san@google.com>
nexus: Make ARP probing configurable for DhcpClient
Signed-off-by: San Mehat <san@google.com>
nexus: Add linkspeed / rssi retrieval
Signed-off-by: San Mehat <san@google.com>
nexus: Add WifiStatusPoller to track RSSI/linkspeed when associated
Signed-off-by: San Mehat <san@google.com>
nexus: Disable some debugging and add 'wifi.netcount' property
Signed-off-by: San Mehat <san@google.com>
nexus: Replace the hackish property system with something more flexible with namespaces
Signed-off-by: San Mehat <san@google.com>
libsysutils: Fix a few bugs in SocketListener
Signed-off-by: San Mehat <san@google.com>
nexus: PropertyManager: Add array support
Signed-off-by: San Mehat <san@google.com>
nexus: Clean up properties
Signed-off-by: San Mehat <san@google.com>
nexus: WifiController: Change name of 'CurrentNetwork' property
Signed-off-by: San Mehat <san@google.com>
diff --git a/nexus/Android.mk b/nexus/Android.mk
index cd477ef..f9f7110 100644
--- a/nexus/Android.mk
+++ b/nexus/Android.mk
@@ -7,23 +7,22 @@
LOCAL_SRC_FILES:= \
main.cpp \
- NetworkManager.cpp \
+ NexusCommand.cpp \
CommandListener.cpp \
+ Property.cpp \
+ PropertyManager.cpp \
+ InterfaceConfig.cpp \
+ NetworkManager.cpp \
Controller.cpp \
WifiController.cpp \
- LoopController.cpp \
- NexusCommand.cpp \
TiwlanWifiController.cpp \
+ TiwlanEventListener.cpp \
+ WifiNetwork.cpp \
+ WifiStatusPoller.cpp \
+ ScanResult.cpp \
Supplicant.cpp \
SupplicantEvent.cpp \
SupplicantListener.cpp \
- VpnController.cpp \
- ScanResult.cpp \
- WifiScanner.cpp \
- WifiNetwork.cpp \
- OpenVpnController.cpp \
- InterfaceConfig.cpp \
- PropertyManager.cpp \
SupplicantState.cpp \
SupplicantEventFactory.cpp \
SupplicantConnectedEvent.cpp \
@@ -34,8 +33,11 @@
SupplicantConnectionTimeoutEvent.cpp \
SupplicantDisconnectedEvent.cpp \
SupplicantStatus.cpp \
- TiwlanEventListener.cpp \
+ OpenVpnController.cpp \
+ VpnController.cpp \
+ LoopController.cpp \
DhcpClient.cpp DhcpListener.cpp \
+ DhcpState.cpp DhcpEvent.cpp \
LOCAL_MODULE:= nexus
diff --git a/nexus/CommandListener.cpp b/nexus/CommandListener.cpp
index 8eb378b..5973ff5 100644
--- a/nexus/CommandListener.cpp
+++ b/nexus/CommandListener.cpp
@@ -31,7 +31,7 @@
#include "NetworkManager.h"
#include "WifiController.h"
#include "VpnController.h"
-#include "ErrorCode.h"
+#include "ResponseCode.h"
CommandListener::CommandListener() :
FrameworkListener("nexus") {
@@ -60,11 +60,11 @@
WifiNetwork *wn;
if (!(wn = wc->createNetwork()))
- cli->sendMsg(ErrorCode::OperationFailed, "Failed to create network", true);
+ cli->sendMsg(ResponseCode::OperationFailed, "Failed to create network", true);
else {
char tmp[128];
sprintf(tmp, "Created network id %d.", wn->getNetworkId());
- cli->sendMsg(ErrorCode::CommandOkay, tmp, false);
+ cli->sendMsg(ResponseCode::CommandOkay, tmp, false);
}
return 0;
}
@@ -79,9 +79,9 @@
WifiController *wc = (WifiController *) nm->findController("WIFI");
if (wc->removeNetwork(atoi(argv[1])))
- cli->sendMsg(ErrorCode::OperationFailed, "Failed to remove network", true);
+ cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove network", true);
else {
- cli->sendMsg(ErrorCode::CommandOkay, "Network removed.", false);
+ cli->sendMsg(ResponseCode::CommandOkay, "Network removed.", false);
}
return 0;
}
@@ -100,16 +100,16 @@
char buffer[256];
for(it = src->begin(); it != src->end(); ++it) {
- sprintf(buffer, "%s:%u:%d:%s:%s",
+ sprintf(buffer, "%s %u %d %s %s",
(*it)->getBssid(), (*it)->getFreq(), (*it)->getLevel(),
(*it)->getFlags(), (*it)->getSsid());
- cli->sendMsg(ErrorCode::WifiScanResult, buffer, false);
+ cli->sendMsg(ResponseCode::WifiScanResult, buffer, false);
delete (*it);
it = src->erase(it);
}
delete src;
- cli->sendMsg(ErrorCode::CommandOkay, "Scan results complete.", false);
+ cli->sendMsg(ResponseCode::CommandOkay, "Scan results complete.", false);
return 0;
}
@@ -128,12 +128,12 @@
for(it = src->begin(); it != src->end(); ++it) {
sprintf(buffer, "%d:%s", (*it)->getNetworkId(), (*it)->getSsid());
- cli->sendMsg(ErrorCode::WifiNetworkList, buffer, false);
+ cli->sendMsg(ResponseCode::WifiNetworkList, buffer, false);
delete (*it);
}
delete src;
- cli->sendMsg(ErrorCode::CommandOkay, "Network listing complete.", false);
+ cli->sendMsg(ResponseCode::CommandOkay, "Network listing complete.", false);
return 0;
}
@@ -159,14 +159,14 @@
char *tmp;
asprintf(&tmp, "%s %s", argv[1], val);
- cli->sendMsg(ErrorCode::PropertyRead, tmp, false);
+ cli->sendMsg(ResponseCode::PropertyRead, tmp, false);
free(tmp);
- cli->sendMsg(ErrorCode::CommandOkay, "Property read.", false);
+ cli->sendMsg(ResponseCode::CommandOkay, "Property read.", false);
return 0;
out_inval:
errno = EINVAL;
- cli->sendMsg(ErrorCode::CommandParameterError, "Failed to read property.", true);
+ cli->sendMsg(ResponseCode::CommandParameterError, "Failed to read property.", true);
return 0;
}
@@ -179,12 +179,12 @@
if (NetworkManager::Instance()->getPropMngr()->set(argv[1], argv[2]))
goto out_inval;
- cli->sendMsg(ErrorCode::CommandOkay, "Property set.", false);
+ cli->sendMsg(ResponseCode::CommandOkay, "Property set.", false);
return 0;
out_inval:
errno = EINVAL;
- cli->sendMsg(ErrorCode::CommandParameterError, "Failed to set property.", true);
+ cli->sendMsg(ResponseCode::CommandParameterError, "Failed to set property.", true);
return 0;
}
@@ -194,10 +194,14 @@
int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **argv) {
android::List<char *> *pc;
+ char *prefix = NULL;
- if (!(pc = NetworkManager::Instance()->getPropMngr()->createPropertyList())) {
+ if (argc > 1)
+ prefix = argv[1];
+
+ if (!(pc = NetworkManager::Instance()->getPropMngr()->createPropertyList(prefix))) {
errno = ENODATA;
- cli->sendMsg(ErrorCode::CommandParameterError, "Failed to list properties.", true);
+ cli->sendMsg(ResponseCode::CommandParameterError, "Failed to list properties.", true);
return 0;
}
@@ -218,7 +222,7 @@
free((*it));
continue;
}
- cli->sendMsg(ErrorCode::PropertyList, buf, false);
+ cli->sendMsg(ResponseCode::PropertyList, buf, false);
free(buf);
free((*it));
@@ -226,6 +230,6 @@
delete pc;
- cli->sendMsg(ErrorCode::CommandOkay, "Properties list complete.", false);
+ cli->sendMsg(ResponseCode::CommandOkay, "Properties list complete.", false);
return 0;
}
diff --git a/nexus/Controller.cpp b/nexus/Controller.cpp
index 17fb519..f6a2436 100644
--- a/nexus/Controller.cpp
+++ b/nexus/Controller.cpp
@@ -30,6 +30,7 @@
#include <cutils/log.h>
#include "Controller.h"
+#include "InterfaceConfig.h"
extern "C" int init_module(void *, unsigned int, const char *);
extern "C" int delete_module(const char *, unsigned int);
@@ -57,16 +58,6 @@
return 0;
}
-int Controller::set(const char *name, const char *value) {
- errno = ENOENT;
- return -1;
-}
-
-const char *Controller::get(const char *name, char *buffer, size_t maxsize) {
- errno = ENOENT;
- return NULL;
-}
-
int Controller::loadKernelModule(char *modpath, const char *args) {
void *module;
unsigned int size;
@@ -164,13 +155,11 @@
int Controller::bindInterface(const char *ifname) {
mBoundInterface = strdup(ifname);
- LOGD("Controller %s bound to %s", mName, ifname);
return 0;
}
int Controller::unbindInterface(const char *ifname) {
free(mBoundInterface);
mBoundInterface = NULL;
- LOGD("Controller %s unbound from %s", mName, ifname);
return 0;
}
diff --git a/nexus/Controller.h b/nexus/Controller.h
index af03d2e..e7e17c5 100644
--- a/nexus/Controller.h
+++ b/nexus/Controller.h
@@ -26,9 +26,8 @@
class IControllerHandler;
#include "PropertyManager.h"
-#include "IPropertyProvider.h"
-class Controller : public IPropertyProvider {
+class Controller {
/*
* Name of this controller - WIFI/VPN/USBNET/BTNET/BTDUN/LOOP/etc
*/
@@ -54,11 +53,7 @@
const char *getName() { return mName; }
const char *getBoundInterface() { return mBoundInterface; }
-
- /* IPropertyProvider methods */
- virtual int set(const char *name, const char *value);
- virtual const char *get(const char *name, char *buffer, size_t maxsize);
-
+
protected:
int loadKernelModule(char *modpath, const char *args);
bool isKernelModuleLoaded(const char *modtag);
diff --git a/nexus/DhcpClient.cpp b/nexus/DhcpClient.cpp
index 2bd9c68..a5654d2 100644
--- a/nexus/DhcpClient.cpp
+++ b/nexus/DhcpClient.cpp
@@ -17,7 +17,9 @@
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
+#include <sys/socket.h>
#include <arpa/inet.h>
+#include <pthread.h>
#define LOG_TAG "DhcpClient"
#include <cutils/log.h>
@@ -29,6 +31,7 @@
#include "DhcpState.h"
#include "DhcpListener.h"
#include "IDhcpEventHandlers.h"
+#include "Controller.h"
extern "C" {
int ifc_disable(const char *ifname);
@@ -54,9 +57,13 @@
}
DhcpClient::DhcpClient(IDhcpEventHandlers *handlers) :
- mState(DhcpState::STOPPED), mHandlers(handlers) {
+ mState(DhcpState::INIT), mHandlers(handlers) {
mServiceManager = new ServiceManager();
mListener = NULL;
+ mListenerSocket = NULL;
+ mController = NULL;
+ mDoArpProbe = false;
+ pthread_mutex_init(&mLock, NULL);
}
DhcpClient::~DhcpClient() {
@@ -65,41 +72,89 @@
delete mListener;
}
-int DhcpClient::start(const char *interface) {
-
+int DhcpClient::start(Controller *c) {
+ LOGD("Starting DHCP service (arp probe = %d)", mDoArpProbe);
char svc[PROPERTY_VALUE_MAX];
- snprintf(svc, sizeof(svc), "dhcpcd_ng:%s", interface);
+ snprintf(svc,
+ sizeof(svc),
+ "dhcpcd:%s%s",
+ (!mDoArpProbe ? "-A " : ""),
+ c->getBoundInterface());
- if (mServiceManager->start(svc)) {
- LOGE("Failed to start dhcp service");
+ pthread_mutex_lock(&mLock);
+
+ if (mController) {
+ pthread_mutex_unlock(&mLock);
+ errno = EBUSY;
+ return -1;
+ }
+ mController = c;
+
+ sockaddr_in addr;
+ if ((mListenerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ LOGE("Failed to create DHCP listener socket");
+ pthread_mutex_unlock(&mLock);
+ return -1;
+ }
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ addr.sin_port = htons(DhcpClient::STATUS_MONITOR_PORT);
+
+ if (bind(mListenerSocket, (struct sockaddr *) &addr, sizeof(addr))) {
+ LOGE("Failed to bind DHCP listener socket");
+ close(mListenerSocket);
+ mListenerSocket = -1;
+ pthread_mutex_unlock(&mLock);
return -1;
}
- mListener = new DhcpListener(mHandlers);
+ if (mServiceManager->start(svc)) {
+ LOGE("Failed to start dhcp service");
+ pthread_mutex_unlock(&mLock);
+ return -1;
+ }
+
+ mListener = new DhcpListener(mController, mListenerSocket, mHandlers);
if (mListener->startListener()) {
LOGE("Failed to start listener");
#if 0
- mServiceManager->stop("dhcpcd_ng");
+ mServiceManager->stop("dhcpcd");
return -1;
#endif
delete mListener;
mListener = NULL;
+ pthread_mutex_unlock(&mLock);
}
- mState = DhcpState::STARTED;
-
+ pthread_mutex_unlock(&mLock);
return 0;
}
int DhcpClient::stop() {
+ pthread_mutex_lock(&mLock);
+ if (!mController) {
+ pthread_mutex_unlock(&mLock);
+ return 0;
+ }
+
if (mListener) {
mListener->stopListener();
delete mListener;
mListener = NULL;
}
+ close(mListenerSocket);
- if (mServiceManager->stop("dhcpcd_ng"))
+ if (mServiceManager->stop("dhcpcd")) {
LOGW("Failed to stop DHCP service (%s)", strerror(errno));
- mState = DhcpState::STOPPED;
+ // XXX: Kill it the hard way.. but its gotta go!
+ }
+
+ mController = NULL;
+ pthread_mutex_unlock(&mLock);
return 0;
}
+
+void DhcpClient::setDoArpProbe(bool probe) {
+ mDoArpProbe = probe;
+}
diff --git a/nexus/DhcpClient.h b/nexus/DhcpClient.h
index e0a2784..42bfda0 100644
--- a/nexus/DhcpClient.h
+++ b/nexus/DhcpClient.h
@@ -18,23 +18,36 @@
#ifndef _DhcpClient_H
#define _DhcpClient_H
+#include <pthread.h>
+
class IDhcpEventHandlers;
class ServiceManager;
class DhcpListener;
+class Controller;
class DhcpClient {
+public:
+ static const int STATUS_MONITOR_PORT = 6666;
+
+private:
int mState;
IDhcpEventHandlers *mHandlers;
ServiceManager *mServiceManager;
DhcpListener *mListener;
+ int mListenerSocket;
+ pthread_mutex_t mLock;
+ Controller *mController;
+ bool mDoArpProbe;
public:
DhcpClient(IDhcpEventHandlers *handlers);
virtual ~DhcpClient();
int getState() { return mState; }
+ bool getDoArpProbe() { return mDoArpProbe; }
+ void setDoArpProbe(bool probe);
- int start(const char *interface);
+ int start(Controller *c);
int stop();
};
diff --git a/nexus/DhcpEvent.cpp b/nexus/DhcpEvent.cpp
new file mode 100644
index 0000000..58893f4
--- /dev/null
+++ b/nexus/DhcpEvent.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+
+#define LOG_TAG "DhcpEvent"
+#include <cutils/log.h>
+
+#include "DhcpEvent.h"
+
+char *DhcpEvent::toString(int val, char *buffer, int max) {
+ if (val == DhcpEvent::UNKNOWN)
+ strncpy(buffer, "UNKNOWN", max);
+ else if (val == DhcpEvent::STOP)
+ strncpy(buffer, "STOP", max);
+ else if (val == DhcpEvent::RENEW)
+ strncpy(buffer, "RENEW", max);
+ else if (val == DhcpEvent::RELEASE)
+ strncpy(buffer, "RELEASE", max);
+ else if (val == DhcpEvent::TIMEOUT)
+ strncpy(buffer, "TIMEOUT", max);
+ else
+ strncpy(buffer, "(internal error)", max);
+
+ return buffer;
+}
+
+int DhcpEvent::parseString(const char *buffer) {
+ if (!strcasecmp(buffer, "UNKNOWN"))
+ return DhcpEvent::UNKNOWN;
+ else if (!strcasecmp(buffer, "STOP"))
+ return DhcpEvent::STOP;
+ else if (!strcasecmp(buffer, "RENEW"))
+ return DhcpEvent::RENEW;
+ else if (!strcasecmp(buffer, "RELEASE"))
+ return DhcpEvent::RELEASE;
+ else if (!strcasecmp(buffer, "TIMEOUT"))
+ return DhcpEvent::TIMEOUT;
+ else {
+ LOGW("Bad event '%s'", buffer);
+ return -1;
+ }
+}
diff --git a/nexus/IPropertyProvider.h b/nexus/DhcpEvent.h
similarity index 63%
rename from nexus/IPropertyProvider.h
rename to nexus/DhcpEvent.h
index 17ad5f8..f77834d 100644
--- a/nexus/IPropertyProvider.h
+++ b/nexus/DhcpEvent.h
@@ -14,20 +14,20 @@
* limitations under the License.
*/
-#ifndef _IPROPERTY_PROVIDER_H
-#define _IPROPERTY_PROVIDER_H
+#ifndef _DHCP_EVENT_H
+#define _DHCP_EVENT_H
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <utils/List.h>
-
-class IPropertyProvider {
+class DhcpEvent {
public:
- virtual int set(const char *name, const char *value) = 0;
- virtual const char *get(const char *name, char *buffer, size_t max) = 0;
-};
+ static const int UNKNOWN = 0;
+ static const int STOP = 1;
+ static const int RENEW = 2;
+ static const int RELEASE = 3;
+ static const int TIMEOUT = 4;
-typedef android::List<IPropertyProvider *> IPropertyProviderCollection;
+ static char *toString(int val, char *buffer, int max);
+
+ static int parseString(const char *buffer);
+};
#endif
diff --git a/nexus/DhcpListener.cpp b/nexus/DhcpListener.cpp
index 2d07ee8..afa68eb 100644
--- a/nexus/DhcpListener.cpp
+++ b/nexus/DhcpListener.cpp
@@ -14,21 +14,95 @@
* limitations under the License.
*/
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
#define LOG_TAG "DhcpListener"
#include <cutils/log.h>
#include <DhcpListener.h>
#include "IDhcpEventHandlers.h"
+#include "DhcpState.h"
+#include "DhcpEvent.h"
+#include "Controller.h"
-DhcpListener::DhcpListener(IDhcpEventHandlers *handlers) :
- SocketListener("dhcp_ng", false) {
+DhcpListener::DhcpListener(Controller *c, int socket, IDhcpEventHandlers *handlers) :
+ SocketListener(socket, false) {
mHandlers = handlers;
+ mController = c;
}
DhcpListener::~DhcpListener() {
}
bool DhcpListener::onDataAvailable(SocketClient *cli) {
- LOGD("onDataAvailable()");
+ char buffer[255];
+ int rc;
+
+ if ((rc = read(cli->getSocket(), buffer, sizeof(buffer))) < 0) {
+ LOGW("Error reading dhcp status msg (%s)", strerror(errno));
+ return true;
+ }
+
+ if (!strncmp(buffer, "STATE:", 6)) {
+ char *next = buffer;
+ char *tmp;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (!(tmp = strsep(&next, ":"))) {
+ LOGW("Error parsing state '%s'", buffer);
+ return true;
+ }
+ }
+
+ int st = DhcpState::parseString(tmp);
+ mHandlers->onDhcpStateChanged(mController, st);
+ } else if (!strncmp(buffer, "ADDRINFO:", 9)) {
+ char *next = buffer + 9;
+ struct in_addr ipaddr, netmask, gateway, broadcast, dns1, dns2;
+
+ if (!inet_aton(strsep(&next, ":"), &ipaddr)) {
+ LOGW("Malformatted IP specified");
+ }
+ if (!inet_aton(strsep(&next, ":"), &netmask)) {
+ LOGW("Malformatted netmask specified");
+ }
+ if (!inet_aton(strsep(&next, ":"), &broadcast)) {
+ LOGW("Malformatted broadcast specified");
+ }
+ if (!inet_aton(strsep(&next, ":"), &gateway)) {
+ LOGW("Malformatted gateway specified");
+ }
+ if (!inet_aton(strsep(&next, ":"), &dns1)) {
+ LOGW("Malformatted dns1 specified");
+ }
+ if (!inet_aton(strsep(&next, ":"), &dns2)) {
+ LOGW("Malformatted dns2 specified");
+ }
+ mHandlers->onDhcpLeaseUpdated(mController, &ipaddr, &netmask,
+ &broadcast, &gateway, &dns1, &dns2);
+
+ } else if (!strncmp(buffer, "EVENT:", 6)) {
+ char *next = buffer;
+ char *tmp;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (!(tmp = strsep(&next, ":"))) {
+ LOGW("Error parsing event '%s'", buffer);
+ return true;
+ }
+ }
+
+ int ev = DhcpEvent::parseString(tmp);
+ mHandlers->onDhcpEvent(mController, ev);
+
+ } else {
+ LOGW("Unknown DHCP monitor msg '%s'", buffer);
+ }
+
return true;
}
diff --git a/nexus/DhcpListener.h b/nexus/DhcpListener.h
index bfc5a37..ca6fe37 100644
--- a/nexus/DhcpListener.h
+++ b/nexus/DhcpListener.h
@@ -20,13 +20,15 @@
#include <sysutils/SocketListener.h>
class IDhcpEventHandlers;
+class Controller;
class DhcpListener : public SocketListener {
IDhcpEventHandlers *mHandlers;
+ Controller *mController;
public:
- DhcpListener(IDhcpEventHandlers *handlers);
+ DhcpListener(Controller *c, int socket, IDhcpEventHandlers *handlers);
virtual ~DhcpListener();
private:
diff --git a/nexus/DhcpState.cpp b/nexus/DhcpState.cpp
new file mode 100644
index 0000000..c9d5135
--- /dev/null
+++ b/nexus/DhcpState.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+
+#define LOG_TAG "DhcpState"
+#include <cutils/log.h>
+
+#include "DhcpState.h"
+
+char *DhcpState::toString(int val, char *buffer, int max) {
+ if (val == DhcpState::INIT)
+ strncpy(buffer, "INIT", max);
+ else if (val == DhcpState::DISCOVERING)
+ strncpy(buffer, "DISCOVERING", max);
+ else if (val == DhcpState::REQUESTING)
+ strncpy(buffer, "REQUESTING", max);
+ else if (val == DhcpState::BOUND)
+ strncpy(buffer, "BOUND", max);
+ else if (val == DhcpState::RENEWING)
+ strncpy(buffer, "RENEWING", max);
+ else if (val == DhcpState::REBINDING)
+ strncpy(buffer, "REBINDING", max);
+ else if (val == DhcpState::REBOOT)
+ strncpy(buffer, "REBOOT", max);
+ else if (val == DhcpState::RENEW_REQUESTED)
+ strncpy(buffer, "RENEW_REQUESTED", max);
+ else if (val == DhcpState::INIT_IPV4LL)
+ strncpy(buffer, "INIT_IPV4LL", max);
+ else if (val == DhcpState::PROBING)
+ strncpy(buffer, "PROBING", max);
+ else if (val == DhcpState::ANNOUNCING)
+ strncpy(buffer, "ANNOUNCING", max);
+ else
+ strncpy(buffer, "(internal error)", max);
+
+ return buffer;
+}
+
+int DhcpState::parseString(const char *buffer) {
+ if (!strcasecmp(buffer, "INIT"))
+ return DhcpState::INIT;
+ else if (!strcasecmp(buffer, "DISCOVERING"))
+ return DhcpState::DISCOVERING;
+ else if (!strcasecmp(buffer, "REQUESTING"))
+ return DhcpState::REQUESTING;
+ else if (!strcasecmp(buffer, "BOUND"))
+ return DhcpState::BOUND;
+ else if (!strcasecmp(buffer, "RENEWING"))
+ return DhcpState::RENEWING;
+ else if (!strcasecmp(buffer, "REBINDING"))
+ return DhcpState::REBINDING;
+ else if (!strcasecmp(buffer, "REBOOT"))
+ return DhcpState::REBOOT;
+ else if (!strcasecmp(buffer, "RENEW_REQUESTED"))
+ return DhcpState::INIT_IPV4LL;
+ else if (!strcasecmp(buffer, "INIT_IPV4LL"))
+ return DhcpState::INIT_IPV4LL;
+ else if (!strcasecmp(buffer, "PROBING"))
+ return DhcpState::PROBING;
+ else if (!strcasecmp(buffer, "ANNOUNCING"))
+ return DhcpState::ANNOUNCING;
+ else {
+ LOGW("Bad state '%s'", buffer);
+ return -1;
+ }
+}
diff --git a/nexus/DhcpState.h b/nexus/DhcpState.h
index 27d7c7e..041c5d2 100644
--- a/nexus/DhcpState.h
+++ b/nexus/DhcpState.h
@@ -14,14 +14,26 @@
* limitations under the License.
*/
-#ifndef _DhcpState_H
-#define _DhcpState_H
+#ifndef _DHCP_STATE_H
+#define _DHCP_STATE_H
class DhcpState {
public:
- static const int UNKNOWN = 0;
- static const int STOPPED = 1;
- static const int STARTED = 2;
+ static const int INIT = 0;
+ static const int DISCOVERING = 1;
+ static const int REQUESTING = 2;
+ static const int BOUND = 3;
+ static const int RENEWING = 4;
+ static const int REBINDING = 5;
+ static const int REBOOT = 6;
+ static const int RENEW_REQUESTED = 7;
+ static const int INIT_IPV4LL = 8;
+ static const int PROBING = 9;
+ static const int ANNOUNCING = 10;
+
+ static char *toString(int val, char *buffer, int max);
+
+ static int parseString(const char *buffer);
};
#endif
diff --git a/nexus/IControllerHandler.h b/nexus/IControllerHandler.h
index f7be39c..3151587 100644
--- a/nexus/IControllerHandler.h
+++ b/nexus/IControllerHandler.h
@@ -22,8 +22,11 @@
class IControllerHandler {
public:
- virtual void onInterfaceConnected(Controller *c, const InterfaceConfig *cfg) = 0;
- virtual void onInterfaceDisconnected(Controller *c, const char *name) = 0;
+ virtual ~IControllerHandler() {}
+ virtual void onInterfaceConnected(Controller *c) = 0;
+ virtual void onInterfaceDisconnected(Controller *c) = 0;
+ virtual void onControllerSuspending(Controller *c) = 0;
+ virtual void onControllerResumed(Controller *c) = 0;
};
#endif
diff --git a/nexus/IDhcpEventHandlers.h b/nexus/IDhcpEventHandlers.h
index 3f51f64..2568f09 100644
--- a/nexus/IDhcpEventHandlers.h
+++ b/nexus/IDhcpEventHandlers.h
@@ -20,6 +20,14 @@
class IDhcpEventHandlers {
public:
+ virtual ~IDhcpEventHandlers() {}
+ virtual void onDhcpStateChanged(Controller *c, int state) = 0;
+ virtual void onDhcpEvent(Controller *c, int event) = 0;
+ virtual void onDhcpLeaseUpdated(Controller *c,
+ struct in_addr *addr, struct in_addr *net,
+ struct in_addr *brd,
+ struct in_addr *gw, struct in_addr *dns1,
+ struct in_addr *dns2) = 0;
};
#endif
diff --git a/nexus/ISupplicantEventHandler.h b/nexus/ISupplicantEventHandler.h
index b7fd17b..1a3aa07 100644
--- a/nexus/ISupplicantEventHandler.h
+++ b/nexus/ISupplicantEventHandler.h
@@ -27,6 +27,7 @@
class ISupplicantEventHandler {
public:
+ virtual ~ISupplicantEventHandler(){}
virtual void onAssociatingEvent(SupplicantAssociatingEvent *evt) = 0;
virtual void onAssociatedEvent(SupplicantAssociatedEvent *evt) = 0;
virtual void onConnectedEvent(SupplicantConnectedEvent *evt) = 0;
diff --git a/nexus/IPropertyProvider.h b/nexus/IWifiStatusPollerHandler.h
similarity index 63%
copy from nexus/IPropertyProvider.h
copy to nexus/IWifiStatusPollerHandler.h
index 17ad5f8..9b94945 100644
--- a/nexus/IPropertyProvider.h
+++ b/nexus/IWifiStatusPollerHandler.h
@@ -14,20 +14,13 @@
* limitations under the License.
*/
-#ifndef _IPROPERTY_PROVIDER_H
-#define _IPROPERTY_PROVIDER_H
+#ifndef _IWIFISTATUSPOLLER_HANDLER_H
+#define _IWIFISTATUSPOLLER_HANDLER_H
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <utils/List.h>
-
-class IPropertyProvider {
+class IWifiStatusPollerHandler {
public:
- virtual int set(const char *name, const char *value) = 0;
- virtual const char *get(const char *name, char *buffer, size_t max) = 0;
+ virtual ~IWifiStatusPollerHandler() {}
+ virtual void onStatusPollInterval() = 0;
};
-typedef android::List<IPropertyProvider *> IPropertyProviderCollection;
-
#endif
diff --git a/nexus/InterfaceConfig.cpp b/nexus/InterfaceConfig.cpp
index 66861d0..832cbca 100644
--- a/nexus/InterfaceConfig.cpp
+++ b/nexus/InterfaceConfig.cpp
@@ -23,147 +23,72 @@
#include "InterfaceConfig.h"
#include "NetworkManager.h"
-const char *InterfaceConfig::PropertyNames[] = { "dhcp", "ip",
- "netmask",
- "gateway", "dns1", "dns2",
- "dns3", '\0' };
-
-InterfaceConfig::InterfaceConfig(const char *prop_prefix) {
- mPropPrefix = strdup(prop_prefix);
- mUseDhcp = true;
- registerProperties();
+InterfaceConfig::InterfaceConfig(bool propertiesReadOnly) {
+ mStaticProperties.propIp = new IPV4AddressPropertyHelper("Addr", propertiesReadOnly, &mIp);
+ mStaticProperties.propNetmask = new IPV4AddressPropertyHelper("Netmask", propertiesReadOnly, &mNetmask);
+ mStaticProperties.propGateway = new IPV4AddressPropertyHelper("Gateway", propertiesReadOnly, &mGateway);
+ mStaticProperties.propBroadcast = new IPV4AddressPropertyHelper("Broadcast", propertiesReadOnly, &mBroadcast);
+ mStaticProperties.propDns = new InterfaceDnsProperty(this, propertiesReadOnly);
}
InterfaceConfig::~InterfaceConfig() {
- unregisterProperties();
- free(mPropPrefix);
+ delete mStaticProperties.propIp;
+ delete mStaticProperties.propNetmask;
+ delete mStaticProperties.propGateway;
+ delete mStaticProperties.propBroadcast;
+ delete mStaticProperties.propDns;
}
-InterfaceConfig::InterfaceConfig(const char *prop_prefix,
- const char *ip, const char *nm,
- const char *gw, const char *dns1, const char *dns2,
- const char *dns3) {
- mPropPrefix = strdup(prop_prefix);
- mUseDhcp = false;
-
- if (!inet_aton(ip, &mIp))
- LOGW("Unable to parse ip (%s)", ip);
- if (!inet_aton(nm, &mNetmask))
- LOGW("Unable to parse netmask (%s)", nm);
- if (!inet_aton(gw, &mGateway))
- LOGW("Unable to parse gateway (%s)", gw);
- if (!inet_aton(dns1, &mDns1))
- LOGW("Unable to parse dns1 (%s)", dns1);
- if (!inet_aton(dns2, &mDns2))
- LOGW("Unable to parse dns2 (%s)", dns2);
- if (!inet_aton(dns3, &mDns3))
- LOGW("Unable to parse dns3 (%s)", dns3);
- registerProperties();
+void InterfaceConfig::setIp(struct in_addr *addr) {
+ memcpy(&mIp, addr, sizeof(struct in_addr));
}
-InterfaceConfig::InterfaceConfig(const char *prop_prefix,
- const struct in_addr *ip,
- const struct in_addr *nm, const struct in_addr *gw,
- const struct in_addr *dns1, const struct in_addr *dns2,
- const struct in_addr *dns3) {
- mPropPrefix = strdup(prop_prefix);
- mUseDhcp = false;
-
- memcpy(&mIp, ip, sizeof(struct in_addr));
- memcpy(&mNetmask, nm, sizeof(struct in_addr));
- memcpy(&mGateway, gw, sizeof(struct in_addr));
- memcpy(&mDns1, dns1, sizeof(struct in_addr));
- memcpy(&mDns2, dns2, sizeof(struct in_addr));
- memcpy(&mDns3, dns3, sizeof(struct in_addr));
- registerProperties();
+void InterfaceConfig::setNetmask(struct in_addr *addr) {
+ memcpy(&mNetmask, addr, sizeof(struct in_addr));
}
-int InterfaceConfig::registerProperties() {
- for (const char **p = InterfaceConfig::PropertyNames; *p != '\0'; p++) {
- char *tmp;
- asprintf(&tmp, "%s.if.%s", mPropPrefix, *p);
+void InterfaceConfig::setGateway(struct in_addr *addr) {
+ memcpy(&mGateway, addr, sizeof(struct in_addr));
+}
- if (NetworkManager::Instance()->getPropMngr()->registerProperty(tmp,
- this)) {
- free(tmp);
- return -1;
- }
- free(tmp);
- }
+void InterfaceConfig::setBroadcast(struct in_addr *addr) {
+ memcpy(&mBroadcast, addr, sizeof(struct in_addr));
+}
+
+void InterfaceConfig::setDns(int idx, struct in_addr *addr) {
+ memcpy(&mDns[idx], addr, sizeof(struct in_addr));
+}
+
+int InterfaceConfig::attachProperties(PropertyManager *pm, const char *nsName) {
+ pm->attachProperty(nsName, mStaticProperties.propIp);
+ pm->attachProperty(nsName, mStaticProperties.propNetmask);
+ pm->attachProperty(nsName, mStaticProperties.propGateway);
+ pm->attachProperty(nsName, mStaticProperties.propBroadcast);
+ pm->attachProperty(nsName, mStaticProperties.propDns);
return 0;
}
-int InterfaceConfig::unregisterProperties() {
- for (const char **p = InterfaceConfig::PropertyNames; *p != '\0'; p++) {
- char *tmp;
- asprintf(&tmp, "%s.if.%s", mPropPrefix, *p);
-
- if (NetworkManager::Instance()->getPropMngr()->unregisterProperty(tmp))
- LOGW("Unable to remove property '%s' (%s)", tmp, strerror(errno));
- free(tmp);
- }
+int InterfaceConfig::detachProperties(PropertyManager *pm, const char *nsName) {
+ pm->detachProperty(nsName, mStaticProperties.propIp);
+ pm->detachProperty(nsName, mStaticProperties.propNetmask);
+ pm->detachProperty(nsName, mStaticProperties.propGateway);
+ pm->detachProperty(nsName, mStaticProperties.propBroadcast);
+ pm->detachProperty(nsName, mStaticProperties.propDns);
return 0;
}
-int InterfaceConfig::set(const char *name, const char *value) {
- const char *n;
+InterfaceConfig::InterfaceDnsProperty::InterfaceDnsProperty(InterfaceConfig *c,
+ bool ro) :
+ IPV4AddressProperty("Dns", ro, 2) {
+ mCfg = c;
+}
- for (n = &name[strlen(name)]; *n != '.'; n--);
- n++;
-
- if (!strcasecmp(n, "name")) {
- errno = EROFS;
- return -1;
- } else if (!strcasecmp(n, "ip") && !inet_aton(value, &mIp))
- goto out_inval;
- else if (!strcasecmp(n, "dhcp"))
- mUseDhcp = (atoi(value) == 0 ? false : true);
- else if (!strcasecmp(n, "netmask") && !inet_aton(value, &mNetmask))
- goto out_inval;
- else if (!strcasecmp(n, "gateway") && !inet_aton(value, &mGateway))
- goto out_inval;
- else if (!strcasecmp(n, "dns1") && !inet_aton(value, &mDns1))
- goto out_inval;
- else if (!strcasecmp(n, "dns2") && !inet_aton(value, &mDns2))
- goto out_inval;
- else if (!strcasecmp(n, "dns3") && !inet_aton(value, &mDns3))
- goto out_inval;
- else {
- errno = ENOENT;
- return -1;
- }
-
+int InterfaceConfig::InterfaceDnsProperty::set(int idx, struct in_addr *value) {
+ memcpy(&mCfg->mDns[idx], value, sizeof(struct in_addr));
return 0;
-
-out_inval:
- errno = EINVAL;
- return -1;
+}
+int InterfaceConfig::InterfaceDnsProperty::get(int idx, struct in_addr *buf) {
+ memcpy(buf, &mCfg->mDns[idx], sizeof(struct in_addr));
+ return 0;
}
-const char *InterfaceConfig::get(const char *name, char *buffer, size_t max) {
- const char *n;
-
- for (n = &name[strlen(name)]; *n != '.'; n--);
- n++;
-
- if (!strcasecmp(n, "ip"))
- strncpy(buffer, inet_ntoa(mIp), max);
- else if (!strcasecmp(n, "dhcp"))
- snprintf(buffer, max, "%d", mUseDhcp);
- else if (!strcasecmp(n, "netmask"))
- strncpy(buffer, inet_ntoa(mNetmask), max);
- else if (!strcasecmp(n, "gateway"))
- strncpy(buffer, inet_ntoa(mGateway), max);
- else if (!strcasecmp(n, "dns1"))
- strncpy(buffer, inet_ntoa(mDns1), max);
- else if (!strcasecmp(n, "dns2"))
- strncpy(buffer, inet_ntoa(mDns2), max);
- else if (!strcasecmp(n, "dns3"))
- strncpy(buffer, inet_ntoa(mDns3), max);
- else {
- strncpy(buffer, "(internal error)", max);
- errno = ENOENT;
- return NULL;
- }
- return buffer;
-}
diff --git a/nexus/InterfaceConfig.h b/nexus/InterfaceConfig.h
index d97f20b..3fc7390 100644
--- a/nexus/InterfaceConfig.h
+++ b/nexus/InterfaceConfig.h
@@ -22,53 +22,58 @@
#include <netinet/in.h>
#include <arpa/inet.h>
-#include "IPropertyProvider.h"
-
+#include "Property.h"
class PropertyManager;
-class InterfaceConfig : public IPropertyProvider {
-public:
- static const char *PropertyNames[];
+class InterfaceConfig {
+ class InterfaceDnsProperty;
+ friend class InterfaceConfig::InterfaceDnsProperty;
-private:
- char *mPropPrefix;
- bool mUseDhcp;
+ struct {
+ IPV4AddressPropertyHelper *propIp;
+ IPV4AddressPropertyHelper *propNetmask;
+ IPV4AddressPropertyHelper *propGateway;
+ IPV4AddressPropertyHelper *propBroadcast;
+ InterfaceDnsProperty *propDns;
+ } mStaticProperties;
+
struct in_addr mIp;
struct in_addr mNetmask;
struct in_addr mGateway;
- struct in_addr mDns1;
- struct in_addr mDns2;
- struct in_addr mDns3;
+ struct in_addr mBroadcast;
+ struct in_addr mDns[2];
public:
- InterfaceConfig(const char *prop_prefix);
- InterfaceConfig(const char *prop_prefix,
- const char *ip, const char *nm,
- const char *gw, const char *dns1, const char *dns2,
- const char *dns3);
-
- InterfaceConfig(const char *prop_prefix,
- const struct in_addr *ip,
- const struct in_addr *nm, const struct in_addr *gw,
- const struct in_addr *dns1, const struct in_addr *dns2,
- const struct in_addr *dns3);
-
+ InterfaceConfig(bool propertiesReadOnly);
virtual ~InterfaceConfig();
int set(const char *name, const char *value);
const char *get(const char *name, char *buffer, size_t maxsize);
- bool getUseDhcp() const { return mUseDhcp; }
const struct in_addr &getIp() const { return mIp; }
const struct in_addr &getNetmask() const { return mNetmask; }
const struct in_addr &getGateway() const { return mGateway; }
- const struct in_addr &getDns1() const { return mDns1; }
- const struct in_addr &getDns2() const { return mDns2; }
- const struct in_addr &getDns3() const { return mDns3; }
+ const struct in_addr &getBroadcast() const { return mBroadcast; }
+ const struct in_addr &getDns(int idx) const { return mDns[idx]; }
+
+ void setIp(struct in_addr *addr);
+ void setNetmask(struct in_addr *addr);
+ void setGateway(struct in_addr *addr);
+ void setBroadcast(struct in_addr *addr);
+ void setDns(int idx, struct in_addr *addr);
+
+ int attachProperties(PropertyManager *pm, const char *nsName);
+ int detachProperties(PropertyManager *pm, const char *nsName);
private:
- int registerProperties();
- int unregisterProperties();
+
+ class InterfaceDnsProperty : public IPV4AddressProperty {
+ InterfaceConfig *mCfg;
+ public:
+ InterfaceDnsProperty(InterfaceConfig *cfg, bool ro);
+ int set(int idx, struct in_addr *value);
+ int get(int idx, struct in_addr *buffer);
+ };
};
diff --git a/nexus/LoopController.cpp b/nexus/LoopController.cpp
index 5cfb1fe..f8e01d7 100644
--- a/nexus/LoopController.cpp
+++ b/nexus/LoopController.cpp
@@ -21,14 +21,5 @@
LoopController::LoopController(PropertyManager *propmngr,
IControllerHandler *handlers) :
- Controller("LOOP", propmngr, handlers) {
+ Controller("loop", propmngr, handlers) {
}
-
-int LoopController::set(const char *name, const char *value) {
- return Controller::set(name, value);
-}
-
-const char *LoopController::get(const char *name, char *buffer, size_t maxsize) {
- return Controller::get(name, buffer, maxsize);
-}
-
diff --git a/nexus/NetworkManager.cpp b/nexus/NetworkManager.cpp
index 7450b95..e0df409 100644
--- a/nexus/NetworkManager.cpp
+++ b/nexus/NetworkManager.cpp
@@ -24,6 +24,9 @@
#include "NetworkManager.h"
#include "InterfaceConfig.h"
#include "DhcpClient.h"
+#include "DhcpState.h"
+#include "DhcpEvent.h"
+#include "ResponseCode.h"
NetworkManager *NetworkManager::sInstance = NULL;
@@ -35,8 +38,9 @@
NetworkManager::NetworkManager(PropertyManager *propMngr) {
mBroadcaster = NULL;
- mControllers = new ControllerCollection();
+ mControllerBindings = new ControllerBindingCollection();
mPropMngr = propMngr;
+ mLastDhcpState = DhcpState::INIT;
mDhcp = new DhcpClient(this);
}
@@ -51,17 +55,17 @@
}
int NetworkManager::attachController(Controller *c) {
- mControllers->push_back(c);
+ ControllerBinding *cb = new ControllerBinding(c);
+ mControllerBindings->push_back(cb);
return 0;
}
int NetworkManager::startControllers() {
int rc = 0;
- ControllerCollection::iterator i;
+ ControllerBindingCollection::iterator it;
- for (i = mControllers->begin(); i != mControllers->end(); ++i) {
- int irc = (*i)->start();
- LOGD("Controller '%s' start rc = %d", (*i)->getName(), irc);
+ for (it = mControllerBindings->begin(); it != mControllerBindings->end(); ++it) {
+ int irc = (*it)->getController()->start();
if (irc && !rc)
rc = irc;
}
@@ -70,52 +74,132 @@
int NetworkManager::stopControllers() {
int rc = 0;
- ControllerCollection::iterator i;
+ ControllerBindingCollection::iterator it;
- for (i = mControllers->begin(); i != mControllers->end(); ++i) {
- int irc = (*i)->stop();
- LOGD("Controller '%s' stop rc = %d", (*i)->getName(), irc);
+ for (it = mControllerBindings->begin(); it != mControllerBindings->end(); ++it) {
+ int irc = (*it)->getController()->stop();
if (irc && !rc)
rc = irc;
}
return rc;
}
-Controller *NetworkManager::findController(const char *name) {
- ControllerCollection::iterator i;
- for (i = mControllers->begin(); i != mControllers->end(); ++i) {
- if (!strcmp((*i)->getName(), name))
- return *i;
+NetworkManager::ControllerBinding *NetworkManager::lookupBinding(Controller *c) {
+ ControllerBindingCollection::iterator it;
+
+ for (it = mControllerBindings->begin(); it != mControllerBindings->end(); ++it) {
+ if ((*it)->getController() == c)
+ return (*it);
}
- LOGW("Controller '%s' not found", name);
+ errno = ENOENT;
return NULL;
}
-void NetworkManager::onInterfaceConnected(Controller *c, const InterfaceConfig *cfg) {
+Controller *NetworkManager::findController(const char *name) {
+ ControllerBindingCollection::iterator it;
+
+ for (it = mControllerBindings->begin(); it != mControllerBindings->end(); ++it) {
+ if (!strcasecmp((*it)->getController()->getName(), name))
+ return (*it)->getController();
+ }
+ errno = ENOENT;
+ return NULL;
+}
+
+void NetworkManager::onInterfaceConnected(Controller *c) {
LOGD("Controller %s interface %s connected", c->getName(), c->getBoundInterface());
- // Look up the interface
-
- if (0) { // already started?
- }
-
- if (cfg) {
- if (cfg->getUseDhcp() && mDhcp->start(c->getBoundInterface())) {
- LOGE("DHCP start failed");
- } else if (!cfg->getUseDhcp()) {
- // Static configuration
- }
- } else {
- LOGD("No InterfaceConfig for %s:%s - assuming self-managed",
- c->getName(), c->getBoundInterface());
+ if (mDhcp->start(c)) {
+ LOGE("Failed to start DHCP (%s)", strerror(errno));
+ return;
}
}
-void NetworkManager::onInterfaceDisconnected(Controller *c, const char *name) {
- LOGD("Controller %s interface %s disconnected", c->getName(), name);
+void NetworkManager::onInterfaceDisconnected(Controller *c) {
+ LOGD("Controller %s interface %s disconnected", c->getName(),
+ c->getBoundInterface());
- // If we have a DHCP request out on this interface then stop it
- if (1) {
- mDhcp->stop();
- }
+ mDhcp->stop();
}
+
+void NetworkManager::onControllerSuspending(Controller *c) {
+ LOGD("Controller %s interface %s suspending", c->getName(),
+ c->getBoundInterface());
+ mDhcp->stop();
+}
+
+void NetworkManager::onControllerResumed(Controller *c) {
+ LOGD("Controller %s interface %s resumed", c->getName(),
+ c->getBoundInterface());
+}
+
+void NetworkManager::onDhcpStateChanged(Controller *c, int state) {
+ char tmp[255];
+ char tmp2[255];
+
+ LOGD("onDhcpStateChanged(%s -> %s)",
+ DhcpState::toString(mLastDhcpState, tmp, sizeof(tmp)),
+ DhcpState::toString(state, tmp2, sizeof(tmp2)));
+
+ switch(state) {
+ case DhcpState::BOUND:
+ // Refresh the 'net.xxx' for the controller
+ break;
+ case DhcpState::RENEWING:
+ break;
+ default:
+ break;
+ }
+
+ char *tmp3;
+ asprintf(&tmp3,
+ "DHCP state changed from %d (%s) -> %d (%s)",
+ mLastDhcpState,
+ DhcpState::toString(mLastDhcpState, tmp, sizeof(tmp)),
+ state,
+ DhcpState::toString(state, tmp2, sizeof(tmp2)));
+
+ getBroadcaster()->sendBroadcast(ResponseCode::DhcpStateChange,
+ tmp3,
+ false);
+ free(tmp3);
+
+ mLastDhcpState = state;
+}
+
+void NetworkManager::onDhcpEvent(Controller *c, int evt) {
+ char tmp[64];
+ LOGD("onDhcpEvent(%s)", DhcpEvent::toString(evt, tmp, sizeof(tmp)));
+}
+
+void NetworkManager::onDhcpLeaseUpdated(Controller *c, struct in_addr *addr,
+ struct in_addr *net,
+ struct in_addr *brd,
+ struct in_addr *gw,
+ struct in_addr *dns1,
+ struct in_addr *dns2) {
+ ControllerBinding *bind = lookupBinding(c);
+
+ if (!bind->getCurrentCfg())
+ bind->setCurrentCfg(new InterfaceConfig(true));
+
+ bind->getCurrentCfg()->setIp(addr);
+ bind->getCurrentCfg()->setNetmask(net);
+ bind->getCurrentCfg()->setGateway(gw);
+ bind->getCurrentCfg()->setBroadcast(brd);
+ bind->getCurrentCfg()->setDns(0, dns1);
+ bind->getCurrentCfg()->setDns(1, dns2);
+}
+
+NetworkManager::ControllerBinding::ControllerBinding(Controller *c) :
+ mController(c) {
+}
+
+void NetworkManager::ControllerBinding::setCurrentCfg(InterfaceConfig *c) {
+ mCurrentCfg = c;
+}
+
+void NetworkManager::ControllerBinding::setBoundCfg(InterfaceConfig *c) {
+ mBoundCfg = c;
+}
+
diff --git a/nexus/NetworkManager.h b/nexus/NetworkManager.h
index 44f3417..93702ce 100644
--- a/nexus/NetworkManager.h
+++ b/nexus/NetworkManager.h
@@ -17,6 +17,7 @@
#ifndef _NETWORKMANAGER_H
#define _NETWORKMANAGER_H
+#include <utils/List.h>
#include <sysutils/SocketListener.h>
#include "Controller.h"
@@ -28,14 +29,33 @@
class DhcpClient;
class NetworkManager : public IControllerHandler, public IDhcpEventHandlers {
-private:
static NetworkManager *sInstance;
+ class ControllerBinding {
+ Controller *mController;
+ InterfaceConfig *mCurrentCfg;
+ InterfaceConfig *mBoundCfg;
+
+ public:
+ ControllerBinding(Controller *c);
+ virtual ~ControllerBinding() {}
+
+ InterfaceConfig *getCurrentCfg() { return mCurrentCfg; }
+ InterfaceConfig *getBoundCfg() { return mCurrentCfg; }
+ Controller *getController() { return mController; }
+
+ void setCurrentCfg(InterfaceConfig *cfg);
+ void setBoundCfg(InterfaceConfig *cfg);
+ };
+
+ typedef android::List<ControllerBinding *> ControllerBindingCollection;
+
private:
- ControllerCollection *mControllers;
- SocketListener *mBroadcaster;
- PropertyManager *mPropMngr;
- DhcpClient *mDhcp;
+ ControllerBindingCollection *mControllerBindings;
+ SocketListener *mBroadcaster;
+ PropertyManager *mPropMngr;
+ DhcpClient *mDhcp;
+ int mLastDhcpState;
public:
virtual ~NetworkManager();
@@ -57,8 +77,19 @@
int stopControllers();
NetworkManager(PropertyManager *propMngr);
+ ControllerBinding *lookupBinding(Controller *c);
- void onInterfaceConnected(Controller *c, const InterfaceConfig *cfg);
- void onInterfaceDisconnected(Controller *c, const char *name);
+ void onInterfaceConnected(Controller *c);
+ void onInterfaceDisconnected(Controller *c);
+ void onControllerSuspending(Controller *c);
+ void onControllerResumed(Controller *c);
+
+ void onDhcpStateChanged(Controller *c, int state);
+ void onDhcpEvent(Controller *c, int event);
+ void onDhcpLeaseUpdated(Controller *c,
+ struct in_addr *addr, struct in_addr *net,
+ struct in_addr *brd,
+ struct in_addr *gw, struct in_addr *dns1,
+ struct in_addr *dns2);
};
#endif
diff --git a/nexus/Property.cpp b/nexus/Property.cpp
new file mode 100644
index 0000000..d02769d
--- /dev/null
+++ b/nexus/Property.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <strings.h>
+#include <netinet/in.h>
+
+#define LOG_TAG "Property"
+
+#include <cutils/log.h>
+
+#include "Property.h"
+
+Property::Property(const char *name, bool readOnly,
+ int type, int numElements) :
+ mName(name), mReadOnly(readOnly), mType(type),
+ mNumElements(numElements) {
+ if (index(name, '.')) {
+ LOGW("Property name %s violates namespace rules", name);
+ }
+}
+
+StringProperty::StringProperty(const char *name, bool ro, int elements) :
+ Property(name, ro, Property::Type_STRING, elements) {
+}
+int StringProperty::set(int idx, int value) {
+ LOGE("Integer 'set' called on string property!");
+ errno = EINVAL;
+ return -1;
+}
+int StringProperty::set(int idx, struct in_addr *value) {
+ LOGE("IpAddr 'set' called on string property!");
+ errno = EINVAL;
+ return -1;
+}
+int StringProperty::get(int idx, int *buffer) {
+ LOGE("Integer 'get' called on string property!");
+ errno = EINVAL;
+ return -1;
+}
+int StringProperty::get(int idx, struct in_addr *buffer) {
+ LOGE("IpAddr 'get' called on string property!");
+ errno = EINVAL;
+ return -1;
+}
+
+StringPropertyHelper::StringPropertyHelper(const char *name, bool ro,
+ char *buffer, size_t max) :
+ StringProperty(name, ro, 1) {
+ mBuffer = buffer;
+ mMax = max;
+}
+
+int StringPropertyHelper::set(int idx, const char *value) {
+ if (idx != 0) {
+ LOGW("Attempt to use array index on StringPropertyHelper::set");
+ errno = EINVAL;
+ return -1;
+ }
+ strncpy(mBuffer, value, mMax);
+ return 0;
+}
+
+int StringPropertyHelper::get(int idx, char *buffer, size_t max) {
+ if (idx != 0) {
+ LOGW("Attempt to use array index on StringPropertyHelper::get");
+ errno = EINVAL;
+ return -1;
+ }
+ strncpy(buffer, mBuffer, max);
+ return 0;
+}
+
+IntegerProperty::IntegerProperty(const char *name, bool ro, int elements) :
+ Property(name, ro, Property::Type_INTEGER, elements) {
+}
+
+int IntegerProperty::set(int idx, const char *value) {
+ LOGE("String 'set' called on integer property!");
+ errno = EINVAL;
+ return -1;
+}
+int IntegerProperty::set(int idx, struct in_addr *value) {
+ LOGE("IpAddr 'set' called on integer property!");
+ errno = EINVAL;
+ return -1;
+}
+int IntegerProperty::get(int idx, char *buffer, size_t max) {
+ LOGE("String 'get' called on integer property!");
+ errno = EINVAL;
+ return -1;
+}
+int IntegerProperty::get(int idx, struct in_addr *buffer) {
+ LOGE("IpAddr 'get' called on integer property!");
+ errno = EINVAL;
+ return -1;
+}
+
+IntegerPropertyHelper::IntegerPropertyHelper(const char *name, bool ro,
+ int *buffer) :
+ IntegerProperty(name, ro, 1) {
+ mBuffer = buffer;
+}
+
+int IntegerPropertyHelper::set(int idx, int value) {
+ if (idx != 0) {
+ LOGW("Attempt to use array index on IntegerPropertyHelper::set");
+ errno = EINVAL;
+ return -1;
+ }
+ *mBuffer = value;
+ return 0;
+}
+
+int IntegerPropertyHelper::get(int idx, int *buffer) {
+ if (idx != 0) {
+ LOGW("Attempt to use array index on IntegerPropertyHelper::get");
+ errno = EINVAL;
+ return -1;
+ }
+ *buffer = *mBuffer;
+ return 0;
+}
+
+IPV4AddressProperty::IPV4AddressProperty(const char *name, bool ro, int elements) :
+ Property(name, ro, Property::Type_IPV4, elements) {
+}
+
+int IPV4AddressProperty::set(int idx, const char *value) {
+ LOGE("String 'set' called on ipv4 property!");
+ errno = EINVAL;
+ return -1;
+}
+int IPV4AddressProperty::set(int idx, int value) {
+ LOGE("Integer 'set' called on ipv4 property!");
+ errno = EINVAL;
+ return -1;
+}
+int IPV4AddressProperty::get(int idx, char *buffer, size_t max) {
+ LOGE("String 'get' called on ipv4 property!");
+ errno = EINVAL;
+ return -1;
+}
+int IPV4AddressProperty::get(int idx, int *buffer) {
+ LOGE("Integer 'get' called on ipv4 property!");
+ errno = EINVAL;
+ return -1;
+}
+
+IPV4AddressPropertyHelper::IPV4AddressPropertyHelper(const char *name, bool ro,
+ struct in_addr *buffer) :
+ IPV4AddressProperty(name, ro, 1) {
+ mBuffer = buffer;
+}
+
+int IPV4AddressPropertyHelper::set(int idx, struct in_addr *value) {
+ if (idx != 0) {
+ LOGW("Attempt to use array index on IPV4AddressPropertyHelper::set");
+ errno = EINVAL;
+ return -1;
+ }
+ memcpy(mBuffer, value, sizeof(struct in_addr));
+ return 0;
+}
+
+int IPV4AddressPropertyHelper::get(int idx, struct in_addr *buffer) {
+ if (idx != 0) {
+ LOGW("Attempt to use array index on IPV4AddressPropertyHelper::get");
+ errno = EINVAL;
+ return -1;
+ }
+ memcpy(buffer, mBuffer, sizeof(struct in_addr));
+ return 0;
+}
+
+PropertyNamespace::PropertyNamespace(const char *name) {
+ mName = strdup(name);
+ mProperties = new PropertyCollection();
+}
+
+PropertyNamespace::~PropertyNamespace() {
+ PropertyCollection::iterator it;
+ for (it = mProperties->begin(); it != mProperties->end();) {
+ delete (*it);
+ it = mProperties->erase(it);
+ }
+ delete mProperties;
+ free(mName);
+}
diff --git a/nexus/Property.h b/nexus/Property.h
index 198f722..ceea2d3 100644
--- a/nexus/Property.h
+++ b/nexus/Property.h
@@ -14,8 +14,124 @@
* limitations under the License.
*/
+#ifndef _PROPERTY_H
+#define _PROPERTY_H
+
+#include <netinet/in.h>
+#include <utils/List.h>
+
class Property {
+ const char *mName;
+ bool mReadOnly;
+ int mType;
+ int mNumElements;
+
public:
- static const int NameMaxSize = 128;
+ static const int NameMaxSize = 128;
static const int ValueMaxSize = 255;
+
+ static const int Type_STRING = 1;
+ static const int Type_INTEGER = 2;
+ static const int Type_IPV4 = 3;
+
+ Property(const char *name, bool ro, int type, int elements);
+ virtual ~Property() {}
+
+ virtual int set(int idx, const char *value) = 0;
+ virtual int set(int idx, int value) = 0;
+ virtual int set(int idx, struct in_addr *value) = 0;
+
+ virtual int get(int idx, char *buffer, size_t max) = 0;
+ virtual int get(int idx, int *buffer) = 0;
+ virtual int get(int idx, struct in_addr *buffer) = 0;
+
+ int getType() { return mType; }
+ bool getReadOnly() { return mReadOnly; }
+ int getNumElements() { return mNumElements; }
+ const char *getName() { return mName; }
};
+
+class StringProperty : public Property {
+public:
+ StringProperty(const char *name, bool ro, int elements);
+ virtual ~StringProperty() {}
+
+ virtual int set(int idx, const char *value) = 0;
+ int set(int idx, int value);
+ int set(int idx, struct in_addr *value);
+
+ virtual int get(int idx, char *buffer, size_t max) = 0;
+ int get(int idx, int *buffer);
+ int get(int idx, struct in_addr *buffer);
+};
+
+class StringPropertyHelper : public StringProperty {
+ char *mBuffer;
+ size_t mMax;
+public:
+ StringPropertyHelper(const char *name, bool ro,
+ char *buffer, size_t max);
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+};
+
+class IntegerProperty : public Property {
+public:
+ IntegerProperty(const char *name, bool ro, int elements);
+ virtual ~IntegerProperty() {}
+
+ int set(int idx, const char *value);
+ virtual int set(int idx, int value) = 0;
+ int set(int idx, struct in_addr *value);
+
+ int get(int idx, char *buffer, size_t max);
+ virtual int get(int idx, int *buffer) = 0;
+ int get(int idx, struct in_addr *buffer);
+};
+
+class IntegerPropertyHelper : public IntegerProperty {
+ int *mBuffer;
+public:
+ IntegerPropertyHelper(const char *name, bool ro, int *buffer);
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+};
+
+class IPV4AddressProperty : public Property {
+public:
+ IPV4AddressProperty(const char *name, bool ro, int elements);
+ virtual ~IPV4AddressProperty() {}
+
+ int set(int idx, const char *value);
+ int set(int idx, int value);
+ virtual int set(int idx, struct in_addr *value) = 0;
+
+ int get(int idx, char *buffer, size_t max);
+ int get(int idx, int *buffer);
+ virtual int get(int idx, struct in_addr *buffer) = 0;
+};
+
+class IPV4AddressPropertyHelper : public IPV4AddressProperty {
+ struct in_addr *mBuffer;
+public:
+ IPV4AddressPropertyHelper(const char *name, bool ro, struct in_addr *buf);
+ int set(int idx, struct in_addr *value);
+ int get(int idx, struct in_addr *buffer);
+};
+
+typedef android::List<Property *> PropertyCollection;
+
+class PropertyNamespace {
+ char *mName;
+ PropertyCollection *mProperties;
+
+public:
+ PropertyNamespace(const char *name);
+ virtual ~PropertyNamespace();
+
+ const char *getName() { return mName; }
+ PropertyCollection *getProperties() { return mProperties; }
+};
+
+typedef android::List<PropertyNamespace *> PropertyNamespaceCollection;
+#endif
diff --git a/nexus/PropertyManager.cpp b/nexus/PropertyManager.cpp
index 6faf9b8..704b223 100644
--- a/nexus/PropertyManager.cpp
+++ b/nexus/PropertyManager.cpp
@@ -14,6 +14,11 @@
* limitations under the License.
*/
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
#define LOG_TAG "PropertyManager"
#include <cutils/log.h>
@@ -21,103 +26,255 @@
#include "PropertyManager.h"
PropertyManager::PropertyManager() {
- mPropertyPairs = new PropertyPairCollection();
+ mNamespaces = new PropertyNamespaceCollection();
pthread_mutex_init(&mLock, NULL);
}
PropertyManager::~PropertyManager() {
- delete mPropertyPairs;
+ PropertyNamespaceCollection::iterator it;
+
+ for (it = mNamespaces->begin(); it != mNamespaces->end();) {
+ delete (*it);
+ it = mNamespaces->erase(it);
+ }
+ delete mNamespaces;
}
-int PropertyManager::registerProperty(const char *name, IPropertyProvider *pp) {
- PropertyPairCollection::iterator it;
+PropertyNamespace *PropertyManager::lookupNamespace_UNLOCKED(const char *ns) {
+ PropertyNamespaceCollection::iterator ns_it;
-// LOGD("registerProperty(%s)", name);
- pthread_mutex_lock(&mLock);
- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) {
- if (!strcmp(name, (*it)->getName())) {
- errno = EADDRINUSE;
- LOGE("Failed to register property %s (%s)",
- name, strerror(errno));
- pthread_mutex_unlock(&mLock);
- return -1;
- }
+ for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
+ if (!strcasecmp(ns, (*ns_it)->getName()))
+ return (*ns_it);
}
- mPropertyPairs->push_back(new PropertyPair(name, pp));
+ errno = ENOENT;
+ return NULL;
+}
+
+Property *PropertyManager::lookupProperty_UNLOCKED(PropertyNamespace *ns, const char *name) {
+ PropertyCollection::iterator it;
+
+ for (it = ns->getProperties()->begin();
+ it != ns->getProperties()->end(); ++it) {
+ if (!strcasecmp(name, (*it)->getName()))
+ return (*it);
+ }
+ errno = ENOENT;
+ return NULL;
+}
+
+int PropertyManager::attachProperty(const char *ns_name, Property *p) {
+ PropertyNamespace *ns;
+
+ LOGD("Attaching property %s to namespace %s", p->getName(), ns_name);
+ pthread_mutex_lock(&mLock);
+ if (!(ns = lookupNamespace_UNLOCKED(ns_name))) {
+ LOGD("Creating namespace %s", ns_name);
+ ns = new PropertyNamespace(ns_name);
+ mNamespaces->push_back(ns);
+ }
+
+ if (lookupProperty_UNLOCKED(ns, p->getName())) {
+ errno = EADDRINUSE;
+ pthread_mutex_unlock(&mLock);
+ LOGE("Failed to register property %s.%s (%s)",
+ ns_name, p->getName(), strerror(errno));
+ return -1;
+ }
+
+ ns->getProperties()->push_back(p);
pthread_mutex_unlock(&mLock);
return 0;
}
-int PropertyManager::unregisterProperty(const char *name) {
- PropertyPairCollection::iterator it;
+int PropertyManager::detachProperty(const char *ns_name, Property *p) {
+ PropertyNamespace *ns;
-// LOGD("unregisterProperty(%s)", name);
+ LOGD("Detaching property %s from namespace %s", p->getName(), ns_name);
pthread_mutex_lock(&mLock);
- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) {
- if (!strcmp(name, (*it)->getName())) {
+ if (!(ns = lookupNamespace_UNLOCKED(ns_name))) {
+ pthread_mutex_unlock(&mLock);
+ LOGE("Namespace '%s' not found", ns_name);
+ return -1;
+ }
+
+ PropertyCollection::iterator it;
+
+ for (it = ns->getProperties()->begin();
+ it != ns->getProperties()->end(); ++it) {
+ if (!strcasecmp(p->getName(), (*it)->getName())) {
delete ((*it));
- mPropertyPairs->erase(it);
+ ns->getProperties()->erase(it);
pthread_mutex_unlock(&mLock);
return 0;
}
}
+
+ LOGE("Property %s.%s not found", ns_name, p->getName());
pthread_mutex_unlock(&mLock);
errno = ENOENT;
return -1;
}
+int PropertyManager::doSet(Property *p, int idx, const char *value) {
+
+ if (p->getReadOnly()) {
+ errno = EROFS;
+ return -1;
+ }
+
+ if (p->getType() == Property::Type_STRING) {
+ return p->set(idx, value);
+ } else if (p->getType() == Property::Type_INTEGER) {
+ int tmp;
+ errno = 0;
+ tmp = strtol(value, (char **) NULL, 10);
+ if (errno) {
+ LOGE("Failed to convert '%s' to int", value);
+ errno = EINVAL;
+ return -1;
+ }
+ return p->set(idx, tmp);
+ } else if (p->getType() == Property::Type_IPV4) {
+ struct in_addr tmp;
+ if (!inet_aton(value, &tmp)) {
+ LOGE("Failed to convert '%s' to ipv4", value);
+ errno = EINVAL;
+ return -1;
+ }
+ return p->set(idx, &tmp);
+ } else {
+ LOGE("Property '%s' has an unknown type (%d)", p->getName(),
+ p->getType());
+ errno = EINVAL;
+ return -1;
+ }
+ errno = ENOENT;
+ return -1;
+}
+
+int PropertyManager::doGet(Property *p, int idx, char *buffer, size_t max) {
+
+ if (p->getType() == Property::Type_STRING) {
+ if (p->get(idx, buffer, max)) {
+ LOGW("String property %s get failed (%s)", p->getName(),
+ strerror(errno));
+ return -1;
+ }
+ }
+ else if (p->getType() == Property::Type_INTEGER) {
+ int tmp;
+ if (p->get(idx, &tmp)) {
+ LOGW("Integer property %s get failed (%s)", p->getName(),
+ strerror(errno));
+ return -1;
+ }
+ snprintf(buffer, max, "%d", tmp);
+ } else if (p->getType() == Property::Type_IPV4) {
+ struct in_addr tmp;
+ if (p->get(idx, &tmp)) {
+ LOGW("IPV4 property %s get failed (%s)", p->getName(),
+ strerror(errno));
+ return -1;
+ }
+ strncpy(buffer, inet_ntoa(tmp), max);
+ } else {
+ LOGE("Property '%s' has an unknown type (%d)", p->getName(),
+ p->getType());
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
/*
* IPropertyManager methods
*/
int PropertyManager::set(const char *name, const char *value) {
- PropertyPairCollection::iterator it;
+ LOGD("set %s = '%s'", name, value);
pthread_mutex_lock(&mLock);
- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) {
- if (!strcmp(name, (*it)->getName())) {
- pthread_mutex_unlock(&mLock);
- return (*it)->getProvider()->set(name, value);
+ PropertyNamespaceCollection::iterator ns_it;
+ for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
+ PropertyCollection::iterator p_it;
+ for (p_it = (*ns_it)->getProperties()->begin();
+ p_it != (*ns_it)->getProperties()->end(); ++p_it) {
+ for (int i = 0; i < (*p_it)->getNumElements(); i++) {
+ char fqn[255];
+ char tmp[8];
+ sprintf(tmp, "_%d", i);
+ snprintf(fqn, sizeof(fqn), "%s.%s%s",
+ (*ns_it)->getName(), (*p_it)->getName(),
+ ((*p_it)->getNumElements() > 1 ? tmp : ""));
+ if (!strcasecmp(name, fqn)) {
+ pthread_mutex_unlock(&mLock);
+ return doSet((*p_it), i, value);
+ }
+ }
}
}
+
+ LOGE("Property %s not found", name);
pthread_mutex_unlock(&mLock);
errno = ENOENT;
return -1;
}
const char *PropertyManager::get(const char *name, char *buffer, size_t max) {
- PropertyPairCollection::iterator it;
-
- memset(buffer, 0, max);
pthread_mutex_lock(&mLock);
- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it) {
- if (!strcmp(name, (*it)->getName())) {
- pthread_mutex_unlock(&mLock);
- return (*it)->getProvider()->get(name, buffer, max);
+ PropertyNamespaceCollection::iterator ns_it;
+ for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
+ PropertyCollection::iterator p_it;
+ for (p_it = (*ns_it)->getProperties()->begin();
+ p_it != (*ns_it)->getProperties()->end(); ++p_it) {
+
+ for (int i = 0; i < (*p_it)->getNumElements(); i++) {
+ char fqn[255];
+ char tmp[8];
+ sprintf(tmp, "_%d", i);
+ snprintf(fqn, sizeof(fqn), "%s.%s%s",
+ (*ns_it)->getName(), (*p_it)->getName(),
+ ((*p_it)->getNumElements() > 1 ? tmp : ""));
+ if (!strcasecmp(name, fqn)) {
+ pthread_mutex_unlock(&mLock);
+ if (doGet((*p_it), i, buffer, max))
+ return NULL;
+ return buffer;
+ }
}
+ }
}
+
+ LOGE("Property %s not found", name);
pthread_mutex_unlock(&mLock);
errno = ENOENT;
return NULL;
}
-android::List<char *> *PropertyManager::createPropertyList() {
+android::List<char *> *PropertyManager::createPropertyList(const char *prefix) {
android::List<char *> *c = new android::List<char *>();
- PropertyPairCollection::iterator it;
-
pthread_mutex_lock(&mLock);
- for (it = mPropertyPairs->begin(); it != mPropertyPairs->end(); ++it)
- c->push_back(strdup((*it)->getName()));
+ PropertyNamespaceCollection::iterator ns_it;
+ for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
+ PropertyCollection::iterator p_it;
+ for (p_it = (*ns_it)->getProperties()->begin();
+ p_it != (*ns_it)->getProperties()->end(); ++p_it) {
+ for (int i = 0; i < (*p_it)->getNumElements(); i++) {
+ char fqn[255];
+ char tmp[8];
+ sprintf(tmp, "_%d", i);
+ snprintf(fqn, sizeof(fqn), "%s.%s%s",
+ (*ns_it)->getName(), (*p_it)->getName(),
+ ((*p_it)->getNumElements() > 1 ? tmp : ""));
+ if (!prefix ||
+ (prefix && !strncasecmp(fqn, prefix, strlen(prefix)))) {
+ c->push_back(strdup(fqn));
+ }
+ }
+ }
+ }
pthread_mutex_unlock(&mLock);
return c;
}
-
-PropertyPair::PropertyPair(const char *name, IPropertyProvider *pp) {
- mName = strdup(name);
- mPp = pp;
-}
-
-PropertyPair::~PropertyPair() {
- free(mName);
-}
diff --git a/nexus/PropertyManager.h b/nexus/PropertyManager.h
index 10d0b2a..af56a9c 100644
--- a/nexus/PropertyManager.h
+++ b/nexus/PropertyManager.h
@@ -22,36 +22,28 @@
#include <utils/List.h>
-#include "IPropertyProvider.h"
-
-class PropertyPair {
-private:
- char *mName;
- IPropertyProvider *mPp;
-
-public:
- PropertyPair(const char *name, IPropertyProvider *pp);
- virtual ~PropertyPair();
-
- const char *getName() { return mName; }
- IPropertyProvider *getProvider() { return mPp; }
-};
-
-typedef android::List<PropertyPair *> PropertyPairCollection;
+#include "Property.h"
class PropertyManager {
- PropertyPairCollection *mPropertyPairs;
- pthread_mutex_t mLock;
+ PropertyNamespaceCollection *mNamespaces;
+ pthread_mutex_t mLock;
public:
PropertyManager();
- virtual ~PropertyManager();
- int registerProperty(const char *name, IPropertyProvider *pp);
- int unregisterProperty(const char *name);
- android::List<char *> *createPropertyList();
+ virtual ~PropertyManager();
+ int attachProperty(const char *ns, Property *p);
+ int detachProperty(const char *ns, Property *p);
+
+ android::List<char *> *createPropertyList(const char *prefix);
int set(const char *name, const char *value);
const char *get(const char *name, char *buffer, size_t max);
+
+private:
+ PropertyNamespace *lookupNamespace_UNLOCKED(const char *ns);
+ Property *lookupProperty_UNLOCKED(PropertyNamespace *ns, const char *name);
+ int doSet(Property *p, int idx, const char *value);
+ int doGet(Property *p, int idx, char *buffer, size_t max);
};
#endif
diff --git a/nexus/ErrorCode.h b/nexus/ResponseCode.h
similarity index 84%
rename from nexus/ErrorCode.h
rename to nexus/ResponseCode.h
index 414dd2c..4b6cac8 100644
--- a/nexus/ErrorCode.h
+++ b/nexus/ResponseCode.h
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#ifndef _ERRORCODE_H
-#define _ERRORCODE_H
+#ifndef _RESPONSECODE_H
+#define _RESPONSECODE_H
-class ErrorCode {
+class ResponseCode {
public:
// 100 series - Requestion action was initiated; expect another reply
// before proceeding with a new command.
@@ -44,5 +44,10 @@
// 600 series - Unsolicited broadcasts
static const int UnsolicitedInformational = 600;
+ static const int DhcpStateChange = 605;
+ static const int SupplicantStateChange = 610;
+ static const int ScanResultsReady = 615;
+ static const int LinkSpeedChange = 620;
+ static const int RssiChange = 625;
};
#endif
diff --git a/nexus/Supplicant.cpp b/nexus/Supplicant.cpp
index 9bb6bf2..6aa36e8 100644
--- a/nexus/Supplicant.cpp
+++ b/nexus/Supplicant.cpp
@@ -30,7 +30,6 @@
#include "Supplicant.h"
#include "SupplicantListener.h"
#include "NetworkManager.h"
-#include "ErrorCode.h"
#include "WifiController.h"
#include "SupplicantStatus.h"
@@ -114,6 +113,29 @@
return mServiceManager->isRunning(SUPPLICANT_SERVICE_NAME);
}
+int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len) {
+
+ if (!mCtrl) {
+ errno = ENOTCONN;
+ return -1;
+ }
+
+// LOGD("sendCommand(): -> '%s'", cmd);
+
+ int rc;
+ memset(reply, 0, *reply_len);
+ if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) {
+ errno = ETIMEDOUT;
+ return -1;
+ } else if (rc < 0 || !strncmp(reply, "FAIL", 4)) {
+ strcpy(reply, "FAIL");
+ errno = EIO;
+ return -1;
+ }
+
+ // LOGD("sendCommand(): <- '%s'", reply);
+ return 0;
+}
SupplicantStatus *Supplicant::getStatus() {
char *reply;
size_t len = 4096;
@@ -162,6 +184,7 @@
return -1;
}
+ PropertyManager *pm = NetworkManager::Instance()->getPropMngr();
pthread_mutex_lock(&mNetworksLock);
int num_added = 0;
@@ -182,7 +205,9 @@
delete new_wn;
} else {
num_added++;
- new_wn->registerProperties();
+ char new_ns[20];
+ snprintf(new_ns, sizeof(new_ns), "wifi.net.%d", new_wn->getNetworkId());
+ new_wn->attachProperties(pm, new_ns);
mNetworks->push_back(new_wn);
if (new_wn->refresh()) {
LOGW("Unable to refresh network id %d (%s)",
@@ -198,7 +223,9 @@
for (i = mNetworks->begin(); i != mNetworks->end(); ++i) {
if (0) {
num_removed++;
- (*i)->unregisterProperties();
+ char del_ns[20];
+ snprintf(del_ns, sizeof(del_ns), "wifi.net.%d", (*i)->getNetworkId());
+ (*i)->detachProperties(pm, del_ns);
delete (*i);
i = mNetworks->erase(i);
}
@@ -247,31 +274,7 @@
return 0;
}
-int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len)
-{
- if (!mCtrl) {
- errno = ENOTCONN;
- return -1;
- }
-
-// LOGD("sendCommand(): -> '%s'", cmd);
-
- int rc;
- memset(reply, 0, *reply_len);
- if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) {
- errno = ETIMEDOUT;
- return -1;
- } else if (rc < 0 || !strncmp(reply, "FAIL", 4)) {
- strcpy(reply, "FAIL");
- errno = EIO;
- return -1;
- }
-
-// LOGD("sendCommand(): <- '%s'", reply);
- return 0;
-}
-
-int Supplicant::triggerScan(bool active) {
+int Supplicant::setScanMode(bool active) {
char reply[255];
size_t len = sizeof(reply);
@@ -281,10 +284,88 @@
strerror(errno));
return -1;
}
- len = sizeof(reply);
+ return 0;
+}
+
+int Supplicant::triggerScan() {
+ char reply[255];
+ size_t len = sizeof(reply);
if (sendCommand("SCAN", reply, &len)) {
- LOGW("triggerScan(%d): Error initiating scan", active);
+ LOGW("triggerScan(): Error initiating scan");
+ return -1;
+ }
+ return 0;
+}
+
+int Supplicant::getRssi(int *buffer) {
+ char reply[64];
+ size_t len = sizeof(reply);
+
+ if (sendCommand("DRIVER RSSI", reply, &len)) {
+ LOGW("Failed to get RSSI (%s)", strerror(errno));
+ return -1;
+ }
+
+ char *next = reply;
+ char *s;
+ for (int i = 0; i < 3; i++) {
+ if (!(s = strsep(&next, " "))) {
+ LOGE("Error parsing RSSI");
+ errno = EIO;
+ return -1;
+ }
+ }
+ *buffer = atoi(s);
+ return 0;
+}
+
+int Supplicant::getLinkSpeed() {
+ char reply[64];
+ size_t len = sizeof(reply);
+
+ if (sendCommand("DRIVER LINKSPEED", reply, &len)) {
+ LOGW("Failed to get LINKSPEED (%s)", strerror(errno));
+ return -1;
+ }
+
+ char *next = reply;
+ char *s;
+
+ if (!(s = strsep(&next, " "))) {
+ LOGE("Error parsing LINKSPEED");
+ errno = EIO;
+ return -1;
+ }
+
+ if (!(s = strsep(&next, " "))) {
+ LOGE("Error parsing LINKSPEED");
+ errno = EIO;
+ return -1;
+ }
+ return atoi(s);
+}
+
+int Supplicant::stopDriver() {
+ char reply[64];
+ size_t len = sizeof(reply);
+
+ LOGD("stopDriver()");
+
+ if (sendCommand("DRIVER STOP", reply, &len)) {
+ LOGW("Failed to stop driver (%s)", strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int Supplicant::startDriver() {
+ char reply[64];
+ size_t len = sizeof(reply);
+
+ LOGD("startDriver()");
+ if (sendCommand("DRIVER START", reply, &len)) {
+ LOGW("Failed to start driver (%s)", strerror(errno));
return -1;
}
return 0;
@@ -301,7 +382,11 @@
reply[strlen(reply) -1] = '\0';
WifiNetwork *wn = new WifiNetwork(mController, this, atoi(reply));
+ PropertyManager *pm = NetworkManager::Instance()->getPropMngr();
pthread_mutex_lock(&mNetworksLock);
+ char new_ns[20];
+ snprintf(new_ns, sizeof(new_ns), "wifi.net.%d", wn->getNetworkId());
+ wn->attachProperties(pm, new_ns);
mNetworks->push_back(wn);
pthread_mutex_unlock(&mNetworksLock);
return wn;
@@ -411,8 +496,9 @@
char reply[255];
size_t len = sizeof(reply) -1;
+ LOGD("netid %d, var '%s' = '%s'", networkId, var, val);
char *tmp;
- asprintf(&tmp, "SET_NETWORK %d %s \"%s\"", networkId, var, val);
+ asprintf(&tmp, "SET_NETWORK %d %s %s", networkId, var, val);
if (sendCommand(tmp, reply, &len)) {
free(tmp);
return -1;
@@ -457,6 +543,95 @@
return 0;
}
+int Supplicant::enablePacketFilter() {
+ char req[128];
+ char reply[16];
+ size_t len;
+ int i;
+
+ for (i = 0; i <=3; i++) {
+ snprintf(req, sizeof(req), "DRIVER RXFILTER-ADD %d", i);
+ len = sizeof(reply);
+ if (sendCommand(req, reply, &len))
+ return -1;
+ }
+
+ len = sizeof(reply);
+ if (sendCommand("DRIVER RXFILTER-START", reply, &len))
+ return -1;
+ return 0;
+}
+
+int Supplicant::disablePacketFilter() {
+ char req[128];
+ char reply[16];
+ size_t len;
+ int i;
+
+ len = sizeof(reply);
+ if (sendCommand("DRIVER RXFILTER-STOP", reply, &len))
+ return -1;
+
+ for (i = 3; i >=0; i--) {
+ snprintf(req, sizeof(req), "DRIVER RXFILTER-REMOVE %d", i);
+ len = sizeof(reply);
+ if (sendCommand(req, reply, &len))
+ return -1;
+ }
+ return 0;
+}
+
+int Supplicant::enableBluetoothCoexistenceScan() {
+ char req[128];
+ char reply[16];
+ size_t len;
+ int i;
+
+ len = sizeof(reply);
+ if (sendCommand("DRIVER BTCOEXSCAN-START", reply, &len))
+ return -1;
+ return 0;
+}
+
+int Supplicant::disableBluetoothCoexistenceScan() {
+ char req[128];
+ char reply[16];
+ size_t len;
+ int i;
+
+ len = sizeof(reply);
+ if (sendCommand("DRIVER BTCOEXSCAN-STOP", reply, &len))
+ return -1;
+ return 0;
+}
+
+int Supplicant::setBluetoothCoexistenceMode(int mode) {
+ char req[64];
+
+ sprintf(req, "DRIVER BTCOEXMODE %d", mode);
+
+ char reply[16];
+ size_t len = sizeof(reply) -1;
+
+ if (sendCommand(req, reply, &len))
+ return -1;
+ return 0;
+}
+
+int Supplicant::setApScanMode(int mode) {
+ char req[64];
+
+// LOGD("setApScanMode(%d)", mode);
+ sprintf(req, "AP_SCAN %d", mode);
+
+ char reply[16];
+ size_t len = sizeof(reply) -1;
+
+ if (sendCommand(req, reply, &len))
+ return -1;
+ return 0;
+}
+
int Supplicant::retrieveInterfaceName() {
char reply[255];
@@ -469,3 +644,34 @@
mInterfaceName = strdup(reply);
return 0;
}
+
+int Supplicant::reconnect() {
+ char req[128];
+ char reply[16];
+ size_t len;
+ int i;
+
+ len = sizeof(reply);
+ if (sendCommand("RECONNECT", reply, &len))
+ return -1;
+ return 0;
+}
+
+int Supplicant::disconnect() {
+ char req[128];
+ char reply[16];
+ size_t len;
+ int i;
+
+ len = sizeof(reply);
+ if (sendCommand("DISCONNECT", reply, &len))
+ return -1;
+ return 0;
+}
+
+int Supplicant::getNetworkCount() {
+ pthread_mutex_lock(&mNetworksLock);
+ int cnt = mNetworks->size();
+ pthread_mutex_unlock(&mNetworksLock);
+ return cnt;
+}
diff --git a/nexus/Supplicant.h b/nexus/Supplicant.h
index 3efbe4c..3900f4f 100644
--- a/nexus/Supplicant.h
+++ b/nexus/Supplicant.h
@@ -30,7 +30,6 @@
#include "ISupplicantEventHandler.h"
class Supplicant {
-private:
struct wpa_ctrl *mCtrl;
struct wpa_ctrl *mMonitor;
SupplicantListener *mListener;
@@ -50,7 +49,8 @@
int stop();
bool isStarted();
- int triggerScan(bool active);
+ int setScanMode(bool active);
+ int triggerScan();
WifiNetwork *createNetwork();
WifiNetwork *lookupNetwork(int networkId);
@@ -63,6 +63,21 @@
size_t max);
int enableNetwork(int networkId, bool enabled);
+ int disconnect();
+ int reconnect();
+ int reassociate();
+ int setApScanMode(int mode);
+ int enablePacketFilter();
+ int disablePacketFilter();
+ int setBluetoothCoexistenceMode(int mode);
+ int enableBluetoothCoexistenceScan();
+ int disableBluetoothCoexistenceScan();
+ int stopDriver();
+ int startDriver();
+ int getRssi(int *buffer);
+ int getLinkSpeed();
+ int getNetworkCount();
+
SupplicantStatus *getStatus();
Controller *getController() { return (Controller *) mController; }
diff --git a/nexus/SupplicantState.cpp b/nexus/SupplicantState.cpp
index a16d370..2815430 100644
--- a/nexus/SupplicantState.cpp
+++ b/nexus/SupplicantState.cpp
@@ -23,25 +23,25 @@
char *SupplicantState::toString(int val, char *buffer, int max) {
if (val == SupplicantState::UNKNOWN)
- strncpy(buffer, "Unknown", max);
+ strncpy(buffer, "UNKNOWN", max);
else if (val == SupplicantState::DISCONNECTED)
- strncpy(buffer, "Disconnected", max);
+ strncpy(buffer, "DISCONNECTED", max);
else if (val == SupplicantState::INACTIVE)
- strncpy(buffer, "Inactive", max);
+ strncpy(buffer, "INACTIVE", max);
else if (val == SupplicantState::SCANNING)
- strncpy(buffer, "Scanning", max);
+ strncpy(buffer, "SCANNING", max);
else if (val == SupplicantState::ASSOCIATING)
- strncpy(buffer, "Associating", max);
+ strncpy(buffer, "ASSOCIATING", max);
else if (val == SupplicantState::ASSOCIATED)
- strncpy(buffer, "Associated", max);
+ strncpy(buffer, "ASSOCIATED", max);
else if (val == SupplicantState::FOURWAY_HANDSHAKE)
- strncpy(buffer, "Fourway Handshake", max);
+ strncpy(buffer, "FOURWAY_HANDSHAKE", max);
else if (val == SupplicantState::GROUP_HANDSHAKE)
- strncpy(buffer, "Group Handshake", max);
+ strncpy(buffer, "GROUP_HANDSHAKE", max);
else if (val == SupplicantState::COMPLETED)
- strncpy(buffer, "Completed", max);
+ strncpy(buffer, "COMPLETED", max);
else if (val == SupplicantState::IDLE)
- strncpy(buffer, "Idle", max);
+ strncpy(buffer, "IDLE", max);
else
strncpy(buffer, "(internal error)", max);
diff --git a/nexus/TiwlanWifiController.cpp b/nexus/TiwlanWifiController.cpp
index 61535c3..016c790 100644
--- a/nexus/TiwlanWifiController.cpp
+++ b/nexus/TiwlanWifiController.cpp
@@ -51,6 +51,7 @@
int TiwlanWifiController::powerDown() {
if (mEventListener) {
delete mEventListener;
+ shutdown(mListenerSock, SHUT_RDWR);
close(mListenerSock);
mListenerSock = -1;
mEventListener = NULL;
@@ -77,7 +78,8 @@
LOGD("Firmware loaded OK");
if (startDriverEventListener()) {
- LOGW("Failed to start driver event listener");
+ LOGW("Failed to start driver event listener (%s)",
+ strerror(errno));
}
return 0;
@@ -95,32 +97,48 @@
int TiwlanWifiController::startDriverEventListener() {
struct sockaddr_in addr;
- int s;
- if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ if (mListenerSock != -1) {
+ LOGE("Listener already started!");
+ errno = EBUSY;
return -1;
+ }
+
+ if ((mListenerSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ LOGE("socket failed (%s)", strerror(errno));
+ return -1;
+ }
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(TI_DRIVER_MSG_PORT);
- if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- close(s);
- return -1;
+ if (bind(mListenerSock,
+ (struct sockaddr *) &addr,
+ sizeof(addr)) < 0) {
+ LOGE("bind failed (%s)", strerror(errno));
+ goto out_err;
}
- mEventListener = new TiwlanEventListener(s);
+ mEventListener = new TiwlanEventListener(mListenerSock);
if (mEventListener->startListener()) {
LOGE("Error starting driver listener (%s)", strerror(errno));
+ goto out_err;
+ }
+ return 0;
+out_err:
+ if (mEventListener) {
delete mEventListener;
mEventListener = NULL;
- close(s);
- return -1;
}
- mListenerSock = s;
- return 0;
+ if (mListenerSock != -1) {
+ shutdown(mListenerSock, SHUT_RDWR);
+ close(mListenerSock);
+ mListenerSock = -1;
+ }
+ return -1;
}
bool TiwlanWifiController::isFirmwareLoaded() {
diff --git a/nexus/VpnController.cpp b/nexus/VpnController.cpp
index add4dc3..015710f 100644
--- a/nexus/VpnController.cpp
+++ b/nexus/VpnController.cpp
@@ -27,56 +27,66 @@
VpnController::VpnController(PropertyManager *propmngr,
IControllerHandler *handlers) :
- Controller("VPN", propmngr, handlers) {
+ Controller("vpn", propmngr, handlers) {
mEnabled = false;
+
+ mStaticProperties.propEnabled = new VpnEnabledProperty(this);
+ mDynamicProperties.propGateway = new IPV4AddressPropertyHelper("Gateway",
+ false,
+ &mGateway);
}
int VpnController::start() {
- mPropMngr->registerProperty("vpn.enabled", this);
+ mPropMngr->attachProperty("vpn", mStaticProperties.propEnabled);
return 0;
}
int VpnController::stop() {
- mPropMngr->unregisterProperty("vpn.enabled");
+ mPropMngr->detachProperty("vpn", mStaticProperties.propEnabled);
return 0;
}
-int VpnController::set(const char *name, const char *value) {
- if (!strcmp(name, "vpn.enabled")) {
- int en = atoi(value);
- int rc;
-
- if (en == mEnabled)
- return 0;
- rc = (en ? enable() : disable());
-
- if (!rc) {
- mEnabled = en;
- if (en)
- mPropMngr->unregisterProperty("vpn.gateway");
- else
- mPropMngr->unregisterProperty("vpn.gateway");
- }
- return rc;
- } if (!strcmp(name, "vpn.gateway")) {
- if (!inet_aton(value, &mVpnGateway)) {
- errno = EINVAL;
- return -1;
- }
- return 0;
- }
-
- return Controller::set(name, value);
+VpnController::VpnIntegerProperty::VpnIntegerProperty(VpnController *c,
+ const char *name,
+ bool ro,
+ int elements) :
+ IntegerProperty(name, ro, elements) {
+ mVc = c;
}
-const char *VpnController::get(const char *name, char *buffer, size_t maxsize) {
- if (!strcmp(name, "vpn.enabled")) {
- snprintf(buffer, maxsize, "%d", mEnabled);
- return buffer;
- } if (!strcmp(name, "vpn.gateway")) {
- snprintf(buffer, maxsize, "%s", inet_ntoa(mVpnGateway));
- return buffer;
- }
+VpnController::VpnStringProperty::VpnStringProperty(VpnController *c,
+ const char *name,
+ bool ro, int elements) :
+ StringProperty(name, ro, elements) {
+ mVc = c;
+}
- return Controller::get(name, buffer, maxsize);
+VpnController::VpnIPV4AddressProperty::VpnIPV4AddressProperty(VpnController *c,
+ const char *name,
+ bool ro, int elements) :
+ IPV4AddressProperty(name, ro, elements) {
+ mVc = c;
+}
+
+VpnController::VpnEnabledProperty::VpnEnabledProperty(VpnController *c) :
+ VpnIntegerProperty(c, "Enabled", false, 1) {
+}
+int VpnController::VpnEnabledProperty::get(int idx, int *buffer) {
+ *buffer = mVc->mEnabled;
+ return 0;
+}
+int VpnController::VpnEnabledProperty::set(int idx, int value) {
+ int rc;
+ if (!value) {
+ mVc->mPropMngr->detachProperty("vpn", mVc->mDynamicProperties.propGateway);
+ rc = mVc->disable();
+ } else {
+ rc = mVc->enable();
+ if (!rc) {
+ mVc->mPropMngr->attachProperty("vpn", mVc->mDynamicProperties.propGateway);
+ }
+ }
+ if (!rc)
+ mVc->mEnabled = value;
+ return rc;
}
diff --git a/nexus/VpnController.h b/nexus/VpnController.h
index 1af4d9f..4bd86b5 100644
--- a/nexus/VpnController.h
+++ b/nexus/VpnController.h
@@ -24,11 +24,63 @@
class IControllerHandler;
class VpnController : public Controller {
+ class VpnIntegerProperty : public IntegerProperty {
+ protected:
+ VpnController *mVc;
+ public:
+ VpnIntegerProperty(VpnController *c, const char *name, bool ro,
+ int elements);
+ virtual ~VpnIntegerProperty() {}
+ virtual int set(int idx, int value) = 0;
+ virtual int get(int idx, int *buffer) = 0;
+ };
+ friend class VpnController::VpnIntegerProperty;
+
+ class VpnStringProperty : public StringProperty {
+ protected:
+ VpnController *mVc;
+ public:
+ VpnStringProperty(VpnController *c, const char *name, bool ro,
+ int elements);
+ virtual ~VpnStringProperty() {}
+ virtual int set(int idx, const char *value) = 0;
+ virtual int get(int idx, char *buffer, size_t max) = 0;
+ };
+ friend class VpnController::VpnStringProperty;
+
+ class VpnIPV4AddressProperty : public IPV4AddressProperty {
+ protected:
+ VpnController *mVc;
+ public:
+ VpnIPV4AddressProperty(VpnController *c, const char *name, bool ro,
+ int elements);
+ virtual ~VpnIPV4AddressProperty() {}
+ virtual int set(int idx, struct in_addr *value) = 0;
+ virtual int get(int idx, struct in_addr *buffer) = 0;
+ };
+ friend class VpnController::VpnIPV4AddressProperty;
+
+ class VpnEnabledProperty : public VpnIntegerProperty {
+ public:
+ VpnEnabledProperty(VpnController *c);
+ virtual ~VpnEnabledProperty() {};
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
bool mEnabled;
/*
* Gateway of the VPN server to connect to
*/
- struct in_addr mVpnGateway;
+ struct in_addr mGateway;
+
+ struct {
+ VpnEnabledProperty *propEnabled;
+ } mStaticProperties;
+
+ struct {
+ IPV4AddressPropertyHelper *propGateway;
+ } mDynamicProperties;
public:
VpnController(PropertyManager *propmngr, IControllerHandler *handlers);
@@ -37,13 +89,9 @@
virtual int start();
virtual int stop();
- virtual int set(const char *name, const char *value);
- virtual const char *get(const char *name, char *buffer, size_t maxlen);
-
protected:
virtual int enable() = 0;
virtual int disable() = 0;
-
};
#endif
diff --git a/nexus/WifiController.cpp b/nexus/WifiController.cpp
index ef5ecae..c218c30 100644
--- a/nexus/WifiController.cpp
+++ b/nexus/WifiController.cpp
@@ -23,9 +23,8 @@
#include "Supplicant.h"
#include "WifiController.h"
-#include "WifiScanner.h"
#include "NetworkManager.h"
-#include "ErrorCode.h"
+#include "ResponseCode.h"
#include "WifiNetwork.h"
#include "ISupplicantEventHandler.h"
#include "SupplicantState.h"
@@ -37,11 +36,12 @@
#include "SupplicantStateChangeEvent.h"
#include "SupplicantConnectionTimeoutEvent.h"
#include "SupplicantDisconnectedEvent.h"
+#include "WifiStatusPoller.h"
WifiController::WifiController(PropertyManager *mPropMngr,
IControllerHandler *handlers,
char *modpath, char *modname, char *modargs) :
- Controller("WIFI", mPropMngr, handlers) {
+ Controller("wifi", mPropMngr, handlers) {
strncpy(mModulePath, modpath, sizeof(mModulePath));
strncpy(mModuleName, modname, sizeof(mModuleName));
strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
@@ -49,22 +49,59 @@
mLatestScanResults = new ScanResultCollection();
pthread_mutex_init(&mLatestScanResultsLock, NULL);
- mSupplicant = new Supplicant(this, this);
- mScanner = new WifiScanner(mSupplicant, 10);
- mCurrentScanMode = 0;
+ pthread_mutex_init(&mLock, NULL);
+ mSupplicant = new Supplicant(this, this);
+ mActiveScan = false;
mEnabled = false;
+ mScanOnly = false;
+ mPacketFilter = false;
+ mBluetoothCoexScan = false;
+ mBluetoothCoexMode = 0;
+ mCurrentlyConnectedNetworkId = -1;
+ mStatusPoller = new WifiStatusPoller(this);
+ mRssiEventThreshold = 5;
+ mLastLinkSpeed = 0;
mSupplicantState = SupplicantState::UNKNOWN;
+
+ mStaticProperties.propEnabled = new WifiEnabledProperty(this);
+ mStaticProperties.propScanOnly = new WifiScanOnlyProperty(this);
+ mStaticProperties.propAllowedChannels = new WifiAllowedChannelsProperty(this);
+
+ mStaticProperties.propRssiEventThreshold =
+ new IntegerPropertyHelper("RssiEventThreshold", false, &mRssiEventThreshold);
+
+ mDynamicProperties.propSupplicantState = new WifiSupplicantStateProperty(this);
+ mDynamicProperties.propActiveScan = new WifiActiveScanProperty(this);
+ mDynamicProperties.propInterface = new WifiInterfaceProperty(this);
+ mDynamicProperties.propSearching = new WifiSearchingProperty(this);
+ mDynamicProperties.propPacketFilter = new WifiPacketFilterProperty(this);
+ mDynamicProperties.propBluetoothCoexScan = new WifiBluetoothCoexScanProperty(this);
+ mDynamicProperties.propBluetoothCoexMode = new WifiBluetoothCoexModeProperty(this);
+ mDynamicProperties.propCurrentNetwork = new WifiCurrentNetworkProperty(this);
+
+ mDynamicProperties.propRssi = new IntegerPropertyHelper("Rssi", true, &mLastRssi);
+ mDynamicProperties.propLinkSpeed = new IntegerPropertyHelper("LinkSpeed", true, &mLastLinkSpeed);
+
+ mDynamicProperties.propSuspended = new WifiSuspendedProperty(this);
+ mDynamicProperties.propNetCount = new WifiNetCountProperty(this);
+ mDynamicProperties.propTriggerScan = new WifiTriggerScanProperty(this);
}
int WifiController::start() {
- mPropMngr->registerProperty("wifi.enabled", this);
+ mPropMngr->attachProperty("wifi", mStaticProperties.propEnabled);
+ mPropMngr->attachProperty("wifi", mStaticProperties.propScanOnly);
+ mPropMngr->attachProperty("wifi", mStaticProperties.propAllowedChannels);
+ mPropMngr->attachProperty("wifi", mStaticProperties.propRssiEventThreshold);
return 0;
}
int WifiController::stop() {
- mPropMngr->unregisterProperty("wifi.enabled");
+ mPropMngr->detachProperty("wifi", mStaticProperties.propEnabled);
+ mPropMngr->detachProperty("wifi", mStaticProperties.propScanOnly);
+ mPropMngr->detachProperty("wifi", mStaticProperties.propAllowedChannels);
+ mPropMngr->detachProperty("wifi", mStaticProperties.propRssiEventThreshold);
return 0;
}
@@ -114,9 +151,21 @@
if (mSupplicant->refreshNetworkList())
LOGW("Error getting list of networks (%s)", strerror(errno));
- mPropMngr->registerProperty("wifi.supplicant.state", this);
- mPropMngr->registerProperty("wifi.scanmode", this);
- mPropMngr->registerProperty("wifi.interface", this);
+ LOGW("TODO: Set # of allowed regulatory channels!");
+
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propSupplicantState);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propActiveScan);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propInterface);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propSearching);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propPacketFilter);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propCurrentNetwork);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propRssi);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propLinkSpeed);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propSuspended);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propNetCount);
+ mPropMngr->attachProperty("wifi", mDynamicProperties.propTriggerScan);
LOGI("Enabled successfully");
return 0;
@@ -135,17 +184,87 @@
return -1;
}
+bool WifiController::getSuspended() {
+ pthread_mutex_lock(&mLock);
+ bool r = mSuspended;
+ pthread_mutex_unlock(&mLock);
+ return r;
+}
+
+int WifiController::setSuspend(bool suspend) {
+
+ pthread_mutex_lock(&mLock);
+ if (suspend == mSuspended) {
+ LOGW("Suspended state already = %d", suspend);
+ pthread_mutex_unlock(&mLock);
+ return 0;
+ }
+
+ if (suspend) {
+ mHandlers->onControllerSuspending(this);
+
+ char tmp[80];
+ LOGD("Suspending from supplicant state %s",
+ SupplicantState::toString(mSupplicantState,
+ tmp,
+ sizeof(tmp)));
+
+ if (mSupplicantState != SupplicantState::IDLE) {
+ LOGD("Forcing Supplicant disconnect");
+ if (mSupplicant->disconnect()) {
+ LOGW("Error disconnecting (%s)", strerror(errno));
+ }
+ }
+
+ LOGD("Stopping Supplicant driver");
+ if (mSupplicant->stopDriver()) {
+ LOGE("Error stopping driver (%s)", strerror(errno));
+ pthread_mutex_unlock(&mLock);
+ return -1;
+ }
+ } else {
+ LOGD("Resuming");
+
+ if (mSupplicant->startDriver()) {
+ LOGE("Error resuming driver (%s)", strerror(errno));
+ pthread_mutex_unlock(&mLock);
+ return -1;
+ }
+ // XXX: set regulatory max channels
+ if (mScanOnly)
+ mSupplicant->triggerScan();
+ else
+ mSupplicant->reconnect();
+
+ mHandlers->onControllerResumed(this);
+ }
+
+ mSuspended = suspend;
+ pthread_mutex_unlock(&mLock);
+ LOGD("Suspend / Resume completed");
+ return 0;
+}
+
void WifiController::sendStatusBroadcast(const char *msg) {
NetworkManager::Instance()->
getBroadcaster()->
- sendBroadcast(ErrorCode::UnsolicitedInformational, msg, false);
+ sendBroadcast(ResponseCode::UnsolicitedInformational, msg, false);
}
int WifiController::disable() {
- mPropMngr->unregisterProperty("wifi.scanmode");
- mPropMngr->unregisterProperty("wifi.supplicant.state");
- mPropMngr->unregisterProperty("wifi.scanmode");
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propSupplicantState);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propActiveScan);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propInterface);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propSearching);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propPacketFilter);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexScan);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propBluetoothCoexMode);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propCurrentNetwork);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propRssi);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propLinkSpeed);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propSuspended);
+ mPropMngr->detachProperty("wifi", mDynamicProperties.propNetCount);
if (mSupplicant->isStarted()) {
sendStatusBroadcast("Stopping WPA Supplicant");
@@ -178,35 +297,61 @@
return 0;
}
-int WifiController::setScanMode(uint32_t mode) {
- int rc = 0;
+int WifiController::triggerScan() {
+ pthread_mutex_lock(&mLock);
+ if (verifyNotSuspended()) {
+ pthread_mutex_unlock(&mLock);
+ return -1;
+ }
- if (mCurrentScanMode == mode)
+ switch (mSupplicantState) {
+ case SupplicantState::DISCONNECTED:
+ case SupplicantState::INACTIVE:
+ case SupplicantState::SCANNING:
+ case SupplicantState::IDLE:
+ break;
+ default:
+ // Switch to scan only mode
+ mSupplicant->setApScanMode(2);
+ break;
+ }
+
+ int rc = mSupplicant->triggerScan();
+ pthread_mutex_unlock(&mLock);
+ return rc;
+}
+
+int WifiController::setActiveScan(bool active) {
+ pthread_mutex_lock(&mLock);
+ if (mActiveScan == active) {
+ pthread_mutex_unlock(&mLock);
return 0;
+ }
+ mActiveScan = active;
- if (!(mode & SCAN_ENABLE_MASK)) {
- if (mCurrentScanMode & SCAN_REPEAT_MASK)
- mScanner->stop();
- } else if (mode & SCAN_REPEAT_MASK)
- rc = mScanner->start(mode & SCAN_ACTIVE_MASK);
- else
- rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
-
- mCurrentScanMode = mode;
+ int rc = mSupplicant->setScanMode(active);
+ pthread_mutex_unlock(&mLock);
return rc;
}
WifiNetwork *WifiController::createNetwork() {
+ pthread_mutex_lock(&mLock);
WifiNetwork *wn = mSupplicant->createNetwork();
+ pthread_mutex_unlock(&mLock);
return wn;
}
int WifiController::removeNetwork(int networkId) {
+ pthread_mutex_lock(&mLock);
WifiNetwork *wn = mSupplicant->lookupNetwork(networkId);
- if (!wn)
+ if (!wn) {
+ pthread_mutex_unlock(&mLock);
return -1;
- return mSupplicant->removeNetwork(wn);
+ }
+ int rc = mSupplicant->removeNetwork(wn);
+ pthread_mutex_unlock(&mLock);
+ return rc;
}
ScanResultCollection *WifiController::createScanResults() {
@@ -225,45 +370,59 @@
return mSupplicant->createNetworkList();
}
-int WifiController::set(const char *name, const char *value) {
+int WifiController::setPacketFilter(bool enable) {
int rc;
- if (!strcmp(name, "wifi.enabled")) {
- int en = atoi(value);
+ pthread_mutex_lock(&mLock);
+ if (enable)
+ rc = mSupplicant->enablePacketFilter();
+ else
+ rc = mSupplicant->disablePacketFilter();
- if (en == mEnabled)
- return 0;
- rc = (en ? enable() : disable());
- if (!rc)
- mEnabled = en;
- } else if (!strcmp(name, "wifi.interface")) {
- errno = EROFS;
- return -1;
- } else if (!strcmp(name, "wifi.scanmode"))
- return setScanMode((uint32_t) strtoul(value, NULL, 0));
- else if (!strcmp(name, "wifi.supplicant.state")) {
- errno = EROFS;
- return -1;
- } else
- return Controller::set(name, value);
+ if (!rc)
+ mPacketFilter = enable;
+ pthread_mutex_unlock(&mLock);
return rc;
}
-const char *WifiController::get(const char *name, char *buffer, size_t maxsize) {
+int WifiController::setBluetoothCoexistenceScan(bool enable) {
+ int rc;
- if (!strcmp(name, "wifi.enabled"))
- snprintf(buffer, maxsize, "%d", mEnabled);
- else if (!strcmp(name, "wifi.interface")) {
- snprintf(buffer, maxsize, "%s",
- (getBoundInterface() ? getBoundInterface() : "none"));
- } else if (!strcmp(name, "wifi.scanmode"))
- snprintf(buffer, maxsize, "0x%.8x", mCurrentScanMode);
- else if (!strcmp(name, "wifi.supplicant.state"))
- return SupplicantState::toString(mSupplicantState, buffer, maxsize);
+ pthread_mutex_lock(&mLock);
+
+ if (enable)
+ rc = mSupplicant->enableBluetoothCoexistenceScan();
else
- return Controller::get(name, buffer, maxsize);
+ rc = mSupplicant->disableBluetoothCoexistenceScan();
- return buffer;
+ if (!rc)
+ mBluetoothCoexScan = enable;
+ pthread_mutex_unlock(&mLock);
+ return rc;
+}
+
+int WifiController::setScanOnly(bool scanOnly) {
+ pthread_mutex_lock(&mLock);
+ int rc = mSupplicant->setApScanMode((scanOnly ? 2 : 1));
+ if (!rc)
+ mScanOnly = scanOnly;
+ if (!mSuspended) {
+ if (scanOnly)
+ mSupplicant->disconnect();
+ else
+ mSupplicant->reconnect();
+ }
+ pthread_mutex_unlock(&mLock);
+ return rc;
+}
+
+int WifiController::setBluetoothCoexistenceMode(int mode) {
+ pthread_mutex_lock(&mLock);
+ int rc = mSupplicant->setBluetoothCoexistenceMode(mode);
+ if (!rc)
+ mBluetoothCoexMode = mode;
+ pthread_mutex_unlock(&mLock);
+ return rc;
}
void WifiController::onAssociatingEvent(SupplicantAssociatingEvent *evt) {
@@ -296,6 +455,7 @@
return;
}
+ mCurrentlyConnectedNetworkId = ss->getId();
if (!(wn = mSupplicant->lookupNetwork(ss->getId()))) {
LOGW("Error looking up connected network id %d (%s)",
ss->getId(), strerror(errno));
@@ -303,7 +463,7 @@
}
delete ss;
- mHandlers->onInterfaceConnected(this, wn->getIfaceCfg());
+ mHandlers->onInterfaceConnected(this);
}
void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
@@ -314,6 +474,10 @@
return;
}
+ mNumScanResultsSinceLastStateChange++;
+ if (mNumScanResultsSinceLastStateChange >= 3)
+ mIsSupplicantSearching = false;
+
size_t len = 4096;
if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
@@ -346,10 +510,14 @@
while((linep = strtok_r(NULL, "\n", &linep_next)))
mLatestScanResults->push_back(new ScanResult(linep));
+ // Switch handling of scan results back to normal mode
+ mSupplicant->setApScanMode(1);
+
char *tmp;
asprintf(&tmp, "Scan results ready (%d)", mLatestScanResults->size());
NetworkManager::Instance()->getBroadcaster()->
- sendBroadcast(ErrorCode::UnsolicitedInformational, tmp, false);
+ sendBroadcast(ResponseCode::ScanResultsReady,
+ tmp, false);
free(tmp);
pthread_mutex_unlock(&mLatestScanResultsLock);
free(reply);
@@ -359,11 +527,35 @@
char tmp[32];
char tmp2[32];
+ if (evt->getState() == mSupplicantState)
+ return;
+
LOGD("onStateChangeEvent(%s -> %s)",
SupplicantState::toString(mSupplicantState, tmp, sizeof(tmp)),
SupplicantState::toString(evt->getState(), tmp2, sizeof(tmp2)));
+ if (evt->getState() != SupplicantState::SCANNING) {
+ mIsSupplicantSearching = true;
+ mNumScanResultsSinceLastStateChange = 0;
+ }
+
+ char *tmp3;
+ asprintf(&tmp3,
+ "Supplicant state changed from %d (%s) -> %d (%s)",
+ mSupplicantState, tmp, evt->getState(), tmp2);
+
mSupplicantState = evt->getState();
+
+ if (mSupplicantState == SupplicantState::COMPLETED) {
+ mStatusPoller->start();
+ } else if (mStatusPoller->isStarted()) {
+ mStatusPoller->stop();
+ }
+
+ NetworkManager::Instance()->getBroadcaster()->
+ sendBroadcast(ResponseCode::SupplicantStateChange,
+ tmp3, false);
+ free(tmp3);
}
void WifiController::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt) {
@@ -371,7 +563,8 @@
}
void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
- mHandlers->onInterfaceDisconnected(this, getBoundInterface());
+ mCurrentlyConnectedNetworkId = -1;
+ mHandlers->onInterfaceDisconnected(this);
}
#if 0
@@ -411,3 +604,216 @@
LOGD("onDriverStateEvent(%s)", evt->getEvent());
}
#endif
+
+void WifiController::onStatusPollInterval() {
+ pthread_mutex_lock(&mLock);
+ int rssi;
+ if (mSupplicant->getRssi(&rssi)) {
+ LOGE("Failed to get rssi (%s)", strerror(errno));
+ pthread_mutex_unlock(&mLock);
+ return;
+ }
+
+ if (abs(mLastRssi - rssi) > mRssiEventThreshold) {
+ char *tmp3;
+ asprintf(&tmp3, "RSSI changed from %d -> %d",
+ mLastRssi, rssi);
+ mLastRssi = rssi;
+ NetworkManager::Instance()->getBroadcaster()->
+ sendBroadcast(ResponseCode::RssiChange,
+ tmp3, false);
+ free(tmp3);
+ }
+
+ int linkspeed = mSupplicant->getLinkSpeed();
+ if (linkspeed != mLastLinkSpeed) {
+ char *tmp3;
+ asprintf(&tmp3, "Link speed changed from %d -> %d",
+ mLastLinkSpeed, linkspeed);
+ mLastLinkSpeed = linkspeed;
+ NetworkManager::Instance()->getBroadcaster()->
+ sendBroadcast(ResponseCode::LinkSpeedChange,
+ tmp3, false);
+ free(tmp3);
+
+ }
+ pthread_mutex_unlock(&mLock);
+}
+
+int WifiController::verifyNotSuspended() {
+ if (mSuspended) {
+ errno = ESHUTDOWN;
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Property inner classes
+ */
+
+WifiController::WifiIntegerProperty::WifiIntegerProperty(WifiController *c,
+ const char *name,
+ bool ro,
+ int elements) :
+ IntegerProperty(name, ro, elements) {
+ mWc = c;
+}
+
+WifiController::WifiStringProperty::WifiStringProperty(WifiController *c,
+ const char *name,
+ bool ro, int elements) :
+ StringProperty(name, ro, elements) {
+ mWc = c;
+}
+
+WifiController::WifiEnabledProperty::WifiEnabledProperty(WifiController *c) :
+ WifiIntegerProperty(c, "Enabled", false, 1) {
+}
+
+int WifiController::WifiEnabledProperty::get(int idx, int *buffer) {
+ *buffer = mWc->mEnabled;
+ return 0;
+}
+int WifiController::WifiEnabledProperty::set(int idx, int value) {
+ int rc = (value ? mWc->enable() : mWc->disable());
+ if (!rc)
+ mWc->mEnabled = value;
+ return rc;
+}
+
+WifiController::WifiScanOnlyProperty::WifiScanOnlyProperty(WifiController *c) :
+ WifiIntegerProperty(c, "ScanOnly", false, 1) {
+}
+int WifiController::WifiScanOnlyProperty::get(int idx, int *buffer) {
+ *buffer = mWc->mScanOnly;
+ return 0;
+}
+int WifiController::WifiScanOnlyProperty::set(int idx, int value) {
+ return mWc->setScanOnly(value == 1);
+}
+
+WifiController::WifiAllowedChannelsProperty::WifiAllowedChannelsProperty(WifiController *c) :
+ WifiIntegerProperty(c, "AllowedChannels", false, 1) {
+}
+int WifiController::WifiAllowedChannelsProperty::get(int idx, int *buffer) {
+ *buffer = mWc->mNumAllowedChannels;
+ return 0;
+}
+int WifiController::WifiAllowedChannelsProperty::set(int idx, int value) {
+ // XXX: IMPL
+ errno = ENOSYS;
+ return -1;
+}
+
+WifiController::WifiSupplicantStateProperty::WifiSupplicantStateProperty(WifiController *c) :
+ WifiStringProperty(c, "SupplicantState", true, 1) {
+}
+int WifiController::WifiSupplicantStateProperty::get(int idx, char *buffer, size_t max) {
+ if (!SupplicantState::toString(mWc->mSupplicantState, buffer, max))
+ return -1;
+ return 0;
+}
+
+WifiController::WifiActiveScanProperty::WifiActiveScanProperty(WifiController *c) :
+ WifiIntegerProperty(c, "ActiveScan", false, 1) {
+}
+int WifiController::WifiActiveScanProperty::get(int idx, int *buffer) {
+ *buffer = mWc->mActiveScan;
+ return 0;
+}
+int WifiController::WifiActiveScanProperty::set(int idx, int value) {
+ return mWc->setActiveScan(value);
+}
+
+WifiController::WifiInterfaceProperty::WifiInterfaceProperty(WifiController *c) :
+ WifiStringProperty(c, "Interface", true, 1) {
+}
+int WifiController::WifiInterfaceProperty::get(int idx, char *buffer, size_t max) {
+ strncpy(buffer, (mWc->getBoundInterface() ? mWc->getBoundInterface() : "none"), max);
+ return 0;
+}
+
+WifiController::WifiSearchingProperty::WifiSearchingProperty(WifiController *c) :
+ WifiIntegerProperty(c, "Searching", true, 1) {
+}
+int WifiController::WifiSearchingProperty::get(int idx, int *buffer) {
+ *buffer = mWc->mIsSupplicantSearching;
+ return 0;
+}
+
+WifiController::WifiPacketFilterProperty::WifiPacketFilterProperty(WifiController *c) :
+ WifiIntegerProperty(c, "PacketFilter", false, 1) {
+}
+int WifiController::WifiPacketFilterProperty::get(int idx, int *buffer) {
+ *buffer = mWc->mPacketFilter;
+ return 0;
+}
+int WifiController::WifiPacketFilterProperty::set(int idx, int value) {
+ return mWc->setPacketFilter(value);
+}
+
+WifiController::WifiBluetoothCoexScanProperty::WifiBluetoothCoexScanProperty(WifiController *c) :
+ WifiIntegerProperty(c, "BluetoothCoexScan", false, 1) {
+}
+int WifiController::WifiBluetoothCoexScanProperty::get(int idx, int *buffer) {
+ *buffer = mWc->mBluetoothCoexScan;
+ return 0;
+}
+int WifiController::WifiBluetoothCoexScanProperty::set(int idx, int value) {
+ return mWc->setBluetoothCoexistenceScan(value == 1);
+}
+
+WifiController::WifiBluetoothCoexModeProperty::WifiBluetoothCoexModeProperty(WifiController *c) :
+ WifiIntegerProperty(c, "BluetoothCoexMode", false, 1) {
+}
+int WifiController::WifiBluetoothCoexModeProperty::get(int idx, int *buffer) {
+ *buffer = mWc->mBluetoothCoexMode;
+ return 0;
+}
+int WifiController::WifiBluetoothCoexModeProperty::set(int idx, int value) {
+ return mWc->setBluetoothCoexistenceMode(value);
+}
+
+WifiController::WifiCurrentNetworkProperty::WifiCurrentNetworkProperty(WifiController *c) :
+ WifiIntegerProperty(c, "CurrentlyConnectedNetworkId", true, 1) {
+}
+int WifiController::WifiCurrentNetworkProperty::get(int idx, int *buffer) {
+ *buffer = mWc->mCurrentlyConnectedNetworkId;
+ return 0;
+}
+
+WifiController::WifiSuspendedProperty::WifiSuspendedProperty(WifiController *c) :
+ WifiIntegerProperty(c, "Suspended", false, 1) {
+}
+int WifiController::WifiSuspendedProperty::get(int idx, int *buffer) {
+ *buffer = mWc->getSuspended();
+ return 0;
+}
+int WifiController::WifiSuspendedProperty::set(int idx, int value) {
+ return mWc->setSuspend(value == 1);
+}
+
+WifiController::WifiNetCountProperty::WifiNetCountProperty(WifiController *c) :
+ WifiIntegerProperty(c, "NetCount", true, 1) {
+}
+int WifiController::WifiNetCountProperty::get(int idx, int *buffer) {
+ pthread_mutex_lock(&mWc->mLock);
+ *buffer = mWc->mSupplicant->getNetworkCount();
+ pthread_mutex_unlock(&mWc->mLock);
+ return 0;
+}
+
+WifiController::WifiTriggerScanProperty::WifiTriggerScanProperty(WifiController *c) :
+ WifiIntegerProperty(c, "TriggerScan", false, 1) {
+}
+int WifiController::WifiTriggerScanProperty::get(int idx, int *buffer) {
+ // XXX: Need action type
+ *buffer = 0;
+ return 0;
+}
+
+int WifiController::WifiTriggerScanProperty::set(int idx, int value) {
+ return mWc->triggerScan();
+}
+
diff --git a/nexus/WifiController.h b/nexus/WifiController.h
index c61d97a..b1524f6 100644
--- a/nexus/WifiController.h
+++ b/nexus/WifiController.h
@@ -23,41 +23,207 @@
#include "ScanResult.h"
#include "WifiNetwork.h"
#include "ISupplicantEventHandler.h"
+#include "IWifiStatusPollerHandler.h"
class NetInterface;
class Supplicant;
-class WifiScanner;
class SupplicantAssociatingEvent;
class SupplicantAssociatedEvent;
class SupplicantConnectedEvent;
class SupplicantScanResultsEvent;
class SupplicantStateChangeEvent;
class SupplicantDisconnectedEvent;
+class WifiStatusPoller;
-class WifiController : public Controller, public ISupplicantEventHandler {
-public:
- static const uint32_t SCAN_ENABLE_MASK = 0x01;
- static const uint32_t SCAN_ACTIVE_MASK = 0x02;
- static const uint32_t SCAN_REPEAT_MASK = 0x04;
+class WifiController : public Controller,
+ public ISupplicantEventHandler,
+ public IWifiStatusPollerHandler {
- static const uint32_t SCANMODE_NONE = 0;
- static const uint32_t SCANMODE_PASSIVE_ONESHOT = SCAN_ENABLE_MASK;
- static const uint32_t SCANMODE_PASSIVE_CONTINUOUS = SCAN_ENABLE_MASK | SCAN_REPEAT_MASK;
- static const uint32_t SCANMODE_ACTIVE_ONESHOT = SCAN_ENABLE_MASK | SCAN_ACTIVE_MASK;
- static const uint32_t SCANMODE_ACTIVE_CONTINUOUS = SCAN_ENABLE_MASK | SCAN_ACTIVE_MASK | SCAN_REPEAT_MASK;
+ class WifiIntegerProperty : public IntegerProperty {
+ protected:
+ WifiController *mWc;
+ public:
+ WifiIntegerProperty(WifiController *c, const char *name, bool ro,
+ int elements);
+ virtual ~WifiIntegerProperty() {}
+ virtual int set(int idx, int value) = 0;
+ virtual int get(int idx, int *buffer) = 0;
+ };
+ friend class WifiController::WifiIntegerProperty;
-private:
+ class WifiStringProperty : public StringProperty {
+ protected:
+ WifiController *mWc;
+ public:
+ WifiStringProperty(WifiController *c, const char *name, bool ro,
+ int elements);
+ virtual ~WifiStringProperty() {}
+ virtual int set(int idx, const char *value) = 0;
+ virtual int get(int idx, char *buffer, size_t max) = 0;
+ };
+ friend class WifiController::WifiStringProperty;
+
+ class WifiEnabledProperty : public WifiIntegerProperty {
+ public:
+ WifiEnabledProperty(WifiController *c);
+ virtual ~WifiEnabledProperty() {}
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiScanOnlyProperty : public WifiIntegerProperty {
+ public:
+ WifiScanOnlyProperty(WifiController *c);
+ virtual ~WifiScanOnlyProperty() {}
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiAllowedChannelsProperty : public WifiIntegerProperty {
+ public:
+ WifiAllowedChannelsProperty(WifiController *c);
+ virtual ~WifiAllowedChannelsProperty() {}
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiActiveScanProperty : public WifiIntegerProperty {
+ public:
+ WifiActiveScanProperty(WifiController *c);
+ virtual ~WifiActiveScanProperty() {}
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiSearchingProperty : public WifiIntegerProperty {
+ public:
+ WifiSearchingProperty(WifiController *c);
+ virtual ~WifiSearchingProperty() {}
+ int set(int idx, int value) { return -1; }
+ int get(int idx, int *buffer);
+ };
+
+ class WifiPacketFilterProperty : public WifiIntegerProperty {
+ public:
+ WifiPacketFilterProperty(WifiController *c);
+ virtual ~WifiPacketFilterProperty() {}
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiBluetoothCoexScanProperty : public WifiIntegerProperty {
+ public:
+ WifiBluetoothCoexScanProperty(WifiController *c);
+ virtual ~WifiBluetoothCoexScanProperty() {}
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiBluetoothCoexModeProperty : public WifiIntegerProperty {
+ public:
+ WifiBluetoothCoexModeProperty(WifiController *c);
+ virtual ~WifiBluetoothCoexModeProperty() {}
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiCurrentNetworkProperty : public WifiIntegerProperty {
+ public:
+ WifiCurrentNetworkProperty(WifiController *c);
+ virtual ~WifiCurrentNetworkProperty() {}
+ int set(int idx, int value) { return -1; }
+ int get(int idx, int *buffer);
+ };
+
+ class WifiSuspendedProperty : public WifiIntegerProperty {
+ public:
+ WifiSuspendedProperty(WifiController *c);
+ virtual ~WifiSuspendedProperty() {}
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiNetCountProperty : public WifiIntegerProperty {
+ public:
+ WifiNetCountProperty(WifiController *c);
+ virtual ~WifiNetCountProperty() {}
+ int set(int idx, int value) { return -1; }
+ int get(int idx, int *buffer);
+ };
+
+ class WifiTriggerScanProperty : public WifiIntegerProperty {
+ public:
+ WifiTriggerScanProperty(WifiController *c);
+ virtual ~WifiTriggerScanProperty() {}
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiSupplicantStateProperty : public WifiStringProperty {
+ public:
+ WifiSupplicantStateProperty(WifiController *c);
+ virtual ~WifiSupplicantStateProperty() {}
+ int set(int idx, const char *value) { return -1; }
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiInterfaceProperty : public WifiStringProperty {
+ public:
+ WifiInterfaceProperty(WifiController *c);
+ virtual ~WifiInterfaceProperty() {}
+ int set(int idx, const char *value) { return -1; }
+ int get(int idx, char *buffer, size_t max);
+ };
+
Supplicant *mSupplicant;
char mModulePath[255];
char mModuleName[64];
char mModuleArgs[255];
- uint32_t mCurrentScanMode;
- WifiScanner *mScanner;
int mSupplicantState;
+ bool mActiveScan;
+ bool mScanOnly;
+ bool mPacketFilter;
+ bool mBluetoothCoexScan;
+ int mBluetoothCoexMode;
+ int mCurrentlyConnectedNetworkId;
+ bool mSuspended;
+ int mLastRssi;
+ int mRssiEventThreshold;
+ int mLastLinkSpeed;
+ int mNumAllowedChannels;
ScanResultCollection *mLatestScanResults;
pthread_mutex_t mLatestScanResultsLock;
+ pthread_mutex_t mLock;
+ WifiStatusPoller *mStatusPoller;
+
+ struct {
+ WifiEnabledProperty *propEnabled;
+ WifiScanOnlyProperty *propScanOnly;
+ WifiAllowedChannelsProperty *propAllowedChannels;
+ IntegerPropertyHelper *propRssiEventThreshold;
+ } mStaticProperties;
+
+ struct {
+ WifiActiveScanProperty *propActiveScan;
+ WifiSearchingProperty *propSearching;
+ WifiPacketFilterProperty *propPacketFilter;
+ WifiBluetoothCoexScanProperty *propBluetoothCoexScan;
+ WifiBluetoothCoexModeProperty *propBluetoothCoexMode;
+ WifiCurrentNetworkProperty *propCurrentNetwork;
+ IntegerPropertyHelper *propRssi;
+ IntegerPropertyHelper *propLinkSpeed;
+ WifiSuspendedProperty *propSuspended;
+ WifiNetCountProperty *propNetCount;
+ WifiSupplicantStateProperty *propSupplicantState;
+ WifiInterfaceProperty *propInterface;
+ WifiTriggerScanProperty *propTriggerScan;
+ } mDynamicProperties;
+
+ // True if supplicant is currently searching for a network
+ bool mIsSupplicantSearching;
+ int mNumScanResultsSinceLastStateChange;
bool mEnabled;
@@ -72,9 +238,6 @@
int removeNetwork(int networkId);
WifiNetworkCollection *createNetworkList();
- virtual int set(const char *name, const char *value);
- virtual const char *get(const char *name, char *buffer, size_t maxlen);
-
ScanResultCollection *createScanResults();
char *getModulePath() { return mModulePath; }
@@ -94,18 +257,25 @@
private:
void sendStatusBroadcast(const char *msg);
- int setScanMode(uint32_t mode);
+ int setActiveScan(bool active);
+ int triggerScan();
int enable();
int disable();
+ int setSuspend(bool suspend);
+ bool getSuspended();
+ int setBluetoothCoexistenceScan(bool enable);
+ int setBluetoothCoexistenceMode(int mode);
+ int setPacketFilter(bool enable);
+ int setScanOnly(bool scanOnly);
// ISupplicantEventHandler methods
- virtual void onAssociatingEvent(SupplicantAssociatingEvent *evt);
- virtual void onAssociatedEvent(SupplicantAssociatedEvent *evt);
- virtual void onConnectedEvent(SupplicantConnectedEvent *evt);
- virtual void onScanResultsEvent(SupplicantScanResultsEvent *evt);
- virtual void onStateChangeEvent(SupplicantStateChangeEvent *evt);
- virtual void onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt);
- virtual void onDisconnectedEvent(SupplicantDisconnectedEvent *evt);
+ void onAssociatingEvent(SupplicantAssociatingEvent *evt);
+ void onAssociatedEvent(SupplicantAssociatedEvent *evt);
+ void onConnectedEvent(SupplicantConnectedEvent *evt);
+ void onScanResultsEvent(SupplicantScanResultsEvent *evt);
+ void onStateChangeEvent(SupplicantStateChangeEvent *evt);
+ void onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *evt);
+ void onDisconnectedEvent(SupplicantDisconnectedEvent *evt);
#if 0
virtual void onTerminatingEvent(SupplicantEvent *evt);
virtual void onPasswordChangedEvent(SupplicantEvent *evt);
@@ -118,6 +288,9 @@
virtual void onDriverStateEvent(SupplicantEvent *evt);
#endif
+ void onStatusPollInterval();
+
+ int verifyNotSuspended();
};
#endif
diff --git a/nexus/WifiNetwork.cpp b/nexus/WifiNetwork.cpp
index 7059bd0..6a0f684 100644
--- a/nexus/WifiNetwork.cpp
+++ b/nexus/WifiNetwork.cpp
@@ -26,17 +26,7 @@
#include "WifiNetwork.h"
#include "Supplicant.h"
#include "WifiController.h"
-#include "InterfaceConfig.h"
-const char *WifiNetwork::PropertyNames[] = { "ssid", "bssid", "psk", "wepkey.1",
- "wepkey.2", "wepkey.3", "wepkey.4",
- "defkeyidx", "pri", "hiddenssid",
- "AllowedKeyManagement",
- "AllowedProtocols",
- "AllowedAuthAlgorithms",
- "AllowedPairwiseCiphers",
- "AllowedGroupCiphers",
- "enabled", '\0' };
WifiNetwork::WifiNetwork() {
// This is private to restrict copy constructors
}
@@ -76,11 +66,11 @@
mDefaultKeyIndex = -1;
mPriority = -1;
mHiddenSsid = NULL;
- mAllowedKeyManagement = KeyManagementMask::UNKNOWN;
- mAllowedProtocols = 0;
- mAllowedAuthAlgorithms = 0;
- mAllowedPairwiseCiphers = 0;
- mAllowedGroupCiphers = 0;
+ mKeyManagement = KeyManagementMask::UNKNOWN;
+ mProtocols = 0;
+ mAuthAlgorithms = 0;
+ mPairwiseCiphers = 0;
+ mGroupCiphers = 0;
mEnabled = true;
if (flags && flags[0] != '\0') {
@@ -90,11 +80,8 @@
LOGW("Unsupported flags '%s'", flags);
}
- char *tmp2;
- asprintf(&tmp2, "wifi.net.%d", mNetid);
- mIfaceCfg = new InterfaceConfig(tmp2);
- free(tmp2);
free(tmp);
+ createProperties();
}
WifiNetwork::WifiNetwork(WifiController *c, Supplicant *suppl, int networkId) {
@@ -108,17 +95,13 @@
mDefaultKeyIndex = -1;
mPriority = -1;
mHiddenSsid = NULL;
- mAllowedKeyManagement = 0;
- mAllowedProtocols = 0;
- mAllowedAuthAlgorithms = 0;
- mAllowedPairwiseCiphers = 0;
- mAllowedGroupCiphers = 0;
+ mKeyManagement = 0;
+ mProtocols = 0;
+ mAuthAlgorithms = 0;
+ mPairwiseCiphers = 0;
+ mGroupCiphers = 0;
mEnabled = false;
-
- char *tmp2;
- asprintf(&tmp2, "wifi.net.%d", mNetid);
- mIfaceCfg = new InterfaceConfig(tmp2);
- free(tmp2);
+ createProperties();
}
WifiNetwork *WifiNetwork::clone() {
@@ -140,15 +123,35 @@
r->mPriority = mPriority;
if (mHiddenSsid)
r->mHiddenSsid = strdup(mHiddenSsid);
- r->mAllowedKeyManagement = mAllowedKeyManagement;
- r->mAllowedProtocols = mAllowedProtocols;
- r->mAllowedAuthAlgorithms = mAllowedAuthAlgorithms;
- r->mAllowedPairwiseCiphers = mAllowedPairwiseCiphers;
- r->mAllowedGroupCiphers = mAllowedGroupCiphers;
+ r->mKeyManagement = mKeyManagement;
+ r->mProtocols = mProtocols;
+ r->mAuthAlgorithms = mAuthAlgorithms;
+ r->mPairwiseCiphers = mPairwiseCiphers;
+ r->mGroupCiphers = mGroupCiphers;
return r;
}
+void WifiNetwork::createProperties() {
+ asprintf(&mPropNamespace, "wifi.net.%d", mNetid);
+
+ mStaticProperties.propEnabled = new WifiNetworkEnabledProperty(this);
+ mStaticProperties.propSsid = new WifiNetworkSsidProperty(this);
+ mStaticProperties.propBssid = new WifiNetworkBssidProperty(this);
+ mStaticProperties.propPsk = new WifiNetworkPskProperty(this);
+ mStaticProperties.propWepKey = new WifiNetworkWepKeyProperty(this);
+ mStaticProperties.propDefKeyIdx = new WifiNetworkDefaultKeyIndexProperty(this);
+ mStaticProperties.propPriority = new WifiNetworkPriorityProperty(this);
+ mStaticProperties.propKeyManagement = new WifiNetworkKeyManagementProperty(this);
+ mStaticProperties.propProtocols = new WifiNetworkProtocolsProperty(this);
+ mStaticProperties.propAuthAlgorithms = new WifiNetworkAuthAlgorithmsProperty(this);
+ mStaticProperties.propPairwiseCiphers = new WifiNetworkPairwiseCiphersProperty(this);
+ mStaticProperties.propGroupCiphers = new WifiNetworkGroupCiphersProperty(this);
+ mStaticProperties.propHiddenSsid = new WifiNetworkHiddenSsidProperty(this);
+}
+
WifiNetwork::~WifiNetwork() {
+ if (mPropNamespace)
+ free(mPropNamespace);
if (mSsid)
free(mSsid);
if (mBssid)
@@ -162,13 +165,26 @@
if (mHiddenSsid)
free(mHiddenSsid);
- if (mIfaceCfg)
- delete(mIfaceCfg);
+
+ delete mStaticProperties.propEnabled;
+ delete mStaticProperties.propSsid;
+ delete mStaticProperties.propBssid;
+ delete mStaticProperties.propPsk;
+ delete mStaticProperties.propWepKey;
+ delete mStaticProperties.propDefKeyIdx;
+ delete mStaticProperties.propPriority;
+ delete mStaticProperties.propKeyManagement;
+ delete mStaticProperties.propProtocols;
+ delete mStaticProperties.propAuthAlgorithms;
+ delete mStaticProperties.propPairwiseCiphers;
+ delete mStaticProperties.propGroupCiphers;
+ delete mStaticProperties.propHiddenSsid;
}
int WifiNetwork::refresh() {
char buffer[255];
size_t len;
+ uint32_t mask;
len = sizeof(buffer);
if (mSuppl->getNetworkVar(mNetid, "psk", buffer, len))
@@ -198,46 +214,47 @@
len = sizeof(buffer);
if (mSuppl->getNetworkVar(mNetid, "key_mgmt", buffer, len)) {
- if (!strcmp(buffer, "NONE"))
- setAllowedKeyManagement(KeyManagementMask::NONE);
- else if (index(buffer, ' ')) {
- char *next = buffer;
- char *token;
- uint32_t mask = 0;
-
- while((token = strsep(&next, " "))) {
- if (!strcmp(token, "WPA-PSK"))
- mask |= KeyManagementMask::WPA_PSK;
- else if (!strcmp(token, "WPA-EAP"))
- mask |= KeyManagementMask::WPA_EAP;
- else if (!strcmp(token, "IEE8021X"))
- mask |= KeyManagementMask::IEEE8021X;
- else
- LOGW("Unsupported key management scheme '%s'" , token);
- }
- setAllowedKeyManagement(mask);
- } else
- LOGE("Unsupported key management '%s'", buffer);
+ if (WifiNetwork::parseKeyManagementMask(buffer, &mask)) {
+ LOGE("Error parsing key_mgmt (%s)", strerror(errno));
+ } else {
+ mKeyManagement = mask;
+ }
}
len = sizeof(buffer);
if (mSuppl->getNetworkVar(mNetid, "proto", buffer, len)) {
- // TODO
+ if (WifiNetwork::parseProtocolsMask(buffer, &mask)) {
+ LOGE("Error parsing proto (%s)", strerror(errno));
+ } else {
+ mProtocols = mask;
+ }
}
len = sizeof(buffer);
if (mSuppl->getNetworkVar(mNetid, "auth_alg", buffer, len)) {
- // TODO
+ if (WifiNetwork::parseAuthAlgorithmsMask(buffer, &mask)) {
+ LOGE("Error parsing auth_alg (%s)", strerror(errno));
+ } else {
+ mAuthAlgorithms = mask;
+ }
}
len = sizeof(buffer);
if (mSuppl->getNetworkVar(mNetid, "pairwise", buffer, len)) {
- // TODO
+ if (WifiNetwork::parsePairwiseCiphersMask(buffer, &mask)) {
+ LOGE("Error parsing pairwise (%s)", strerror(errno));
+ } else {
+ mPairwiseCiphers = mask;
+ }
}
len = sizeof(buffer);
if (mSuppl->getNetworkVar(mNetid, "group", buffer, len)) {
- // TODO
+ if (WifiNetwork::parseGroupCiphersMask(buffer, &mask)) {
+ LOGE("Error parsing group (%s)", strerror(errno));
+ } else {
+ mGroupCiphers = mask;
+ }
}
return 0;
@@ -246,179 +263,10 @@
return -1;
}
-int WifiNetwork::set(const char *name, const char *value) {
- char *n_tmp = strdup(name + strlen("wifi.net."));
- char *n_next = n_tmp;
- char *n_local;
- char *n_rest;
- int rc = 0;
-
- if (!strsep(&n_next, ".")) // skip net id
- goto out_inval;
-
- if (!(n_local = strsep(&n_next, ".")))
- goto out_inval;
-
- n_rest = n_next;
-
-// LOGD("set(): var '%s'(%s / %s) = %s", name, n_local, n_rest, value);
- if (!strcasecmp(n_local, "enabled"))
- rc = setEnabled(atoi(value));
- else if (!strcmp(n_local, "ssid"))
- rc = setSsid(value);
- else if (!strcasecmp(n_local, "bssid"))
- rc = setBssid(value);
- else if (!strcasecmp(n_local, "psk"))
- rc = setPsk(value);
- else if (!strcasecmp(n_local, "wepkey"))
- rc = setWepKey(atoi(n_rest) -1, value);
- else if (!strcasecmp(n_local, "defkeyidx"))
- rc = setDefaultKeyIndex(atoi(value));
- else if (!strcasecmp(n_local, "pri"))
- rc = setPriority(atoi(value));
- else if (!strcasecmp(n_local, "hiddenssid"))
- rc = setHiddenSsid(value);
- else if (!strcasecmp(n_local, "AllowedKeyManagement")) {
- uint32_t mask = 0;
- bool none = false;
- char *v_tmp = strdup(value);
- char *v_next = v_tmp;
- char *v_token;
-
- while((v_token = strsep(&v_next, " "))) {
- if (!strcasecmp(v_token, "NONE")) {
- mask = KeyManagementMask::NONE;
- none = true;
- } else if (!none) {
- if (!strcasecmp(v_token, "WPA_PSK"))
- mask |= KeyManagementMask::WPA_PSK;
- else if (!strcasecmp(v_token, "WPA_EAP"))
- mask |= KeyManagementMask::WPA_EAP;
- else if (!strcasecmp(v_token, "IEEE8021X"))
- mask |= KeyManagementMask::IEEE8021X;
- else {
- errno = EINVAL;
- rc = -1;
- free(v_tmp);
- goto out;
- }
- } else {
- errno = EINVAL;
- rc = -1;
- free(v_tmp);
- goto out;
- }
- }
- free(v_tmp);
- } else if (!strcasecmp(n_local, "AllowedProtocols")) {
- // TODO
- } else if (!strcasecmp(n_local, "AllowedPairwiseCiphers")) {
- // TODO
- } else if (!strcasecmp(n_local, "AllowedAuthAlgorithms")) {
- // TODO
- } else if (!strcasecmp(n_local, "AllowedGroupCiphers")) {
- // TODO
- } else {
- errno = ENOENT;
- free(n_tmp);
- return -1;
- }
-
-out:
- free(n_tmp);
- return rc;
-
-out_inval:
- errno = EINVAL;
- free(n_tmp);
- return -1;
-}
-
-const char *WifiNetwork::get(const char *name, char *buffer, size_t maxsize) {
- char *n_tmp = strdup(name + strlen("wifi.net."));
- char *n_next = n_tmp;
- char *n_local;
- char fc[64];
- char rc[128];
-
- if (!strsep(&n_next, ".")) // skip net id
- goto out_inval;
-
- if (!(n_local = strsep(&n_next, ".")))
- goto out_inval;
-
-
- strncpy(fc, n_local, sizeof(fc));
- rc[0] = '\0';
- if (n_next)
- strncpy(rc, n_next, sizeof(rc));
-
- free(n_tmp);
-
- if (!strcasecmp(fc, "enabled"))
- snprintf(buffer, maxsize, "%d", getEnabled());
- else if (!strcasecmp(fc, "ssid")) {
- strncpy(buffer,
- getSsid() ? getSsid() : "none",
- maxsize);
- } else if (!strcasecmp(fc, "bssid")) {
- strncpy(buffer,
- getBssid() ? getBssid() : "none",
- maxsize);
- } else if (!strcasecmp(fc, "psk")) {
- strncpy(buffer,
- getPsk() ? getPsk() : "none",
- maxsize);
- } else if (!strcasecmp(fc, "wepkey")) {
- strncpy(buffer,
- getWepKey(atoi(rc)-1) ? getWepKey(atoi(rc)-1) : "none",
- maxsize);
- } else if (!strcasecmp(fc, "defkeyidx"))
- snprintf(buffer, maxsize, "%d", getDefaultKeyIndex());
- else if (!strcasecmp(fc, "pri"))
- snprintf(buffer, maxsize, "%d", getPriority());
- else if (!strcasecmp(fc, "AllowedKeyManagement")) {
- if (getAllowedKeyManagement() == KeyManagementMask::NONE)
- strncpy(buffer, "NONE", maxsize);
- else {
- char tmp[80] = { '\0' };
-
- if (getAllowedKeyManagement() & KeyManagementMask::WPA_PSK)
- strcat(tmp, "WPA_PSK ");
- if (getAllowedKeyManagement() & KeyManagementMask::WPA_EAP)
- strcat(tmp, "WPA_EAP ");
- if (getAllowedKeyManagement() & KeyManagementMask::IEEE8021X)
- strcat(tmp, "IEEE8021X");
- if (tmp[0] == '\0') {
- strncpy(buffer, "(internal error)", maxsize);
- errno = ENOENT;
- return NULL;
- }
- if (tmp[strlen(tmp)] == ' ')
- tmp[strlen(tmp)] = '\0';
-
- strncpy(buffer, tmp, maxsize);
- }
- } else if (!strcasecmp(fc, "hiddenssid")) {
- strncpy(buffer,
- getHiddenSsid() ? getHiddenSsid() : "none",
- maxsize);
- } else {
- strncpy(buffer, "(internal error)", maxsize);
- errno = ENOENT;
- return NULL;
- }
-
- return buffer;
-
-out_inval:
- errno = EINVAL;
- free(n_tmp);
- return NULL;
-}
-
int WifiNetwork::setSsid(const char *ssid) {
- if (mSuppl->setNetworkVar(mNetid, "ssid", ssid))
+ char tmp[255];
+ snprintf(tmp, sizeof(tmp), "\"%s\"", ssid);
+ if (mSuppl->setNetworkVar(mNetid, "ssid", tmp))
return -1;
if (mSsid)
free(mSsid);
@@ -436,7 +284,9 @@
}
int WifiNetwork::setPsk(const char *psk) {
- if (mSuppl->setNetworkVar(mNetid, "psk", psk))
+ char tmp[255];
+ snprintf(tmp, sizeof(tmp), "\"%s\"", psk);
+ if (mSuppl->setNetworkVar(mNetid, "psk", tmp))
return -1;
if (mPsk)
@@ -491,28 +341,34 @@
return 0;
}
-int WifiNetwork::setAllowedKeyManagement(uint32_t mask) {
- char accum[255];
+int WifiNetwork::setKeyManagement(uint32_t mask) {
+ char accum[64] = {'\0'};
if (mask == KeyManagementMask::NONE)
strcpy(accum, "NONE");
else {
- if (mask & KeyManagementMask::WPA_PSK)
- strcat(accum, "WPA_PSK ");
- if (mask & KeyManagementMask::WPA_EAP)
- strcat(accum, "WPA_EAP ");
- if (mask & KeyManagementMask::IEEE8021X)
- strcat(accum, "IEEE8021X ");
+ if (mask & KeyManagementMask::WPA_PSK)
+ strcat(accum, "WPA-PSK");
+ if (mask & KeyManagementMask::WPA_EAP) {
+ if (accum[0] != '\0')
+ strcat(accum, " ");
+ strcat(accum, "WPA-EAP");
+ }
+ if (mask & KeyManagementMask::IEEE8021X) {
+ if (accum[0] != '\0')
+ strcat(accum, " ");
+ strcat(accum, "IEEE8021X");
+ }
}
if (mSuppl->setNetworkVar(mNetid, "key_mgmt", accum))
return -1;
- mAllowedKeyManagement = mask;
+ mKeyManagement = mask;
return 0;
}
-int WifiNetwork::setAllowedProtocols(uint32_t mask) {
- char accum[255];
+int WifiNetwork::setProtocols(uint32_t mask) {
+ char accum[64];
accum[0] = '\0';
@@ -524,15 +380,18 @@
if (mSuppl->setNetworkVar(mNetid, "proto", accum))
return -1;
- mAllowedProtocols = mask;
+ mProtocols = mask;
return 0;
}
-int WifiNetwork::setAllowedAuthAlgorithms(uint32_t mask) {
- char accum[255];
+int WifiNetwork::setAuthAlgorithms(uint32_t mask) {
+ char accum[64];
accum[0] = '\0';
+ if (mask == 0)
+ strcpy(accum, "");
+
if (mask & AuthenticationAlgorithmMask::OPEN)
strcpy(accum, "OPEN ");
@@ -545,12 +404,14 @@
if (mSuppl->setNetworkVar(mNetid, "auth_alg", accum))
return -1;
- mAllowedAuthAlgorithms = mask;
+ mAuthAlgorithms = mask;
return 0;
}
-int WifiNetwork::setAllowedPairwiseCiphers(uint32_t mask) {
- char accum[255];
+int WifiNetwork::setPairwiseCiphers(uint32_t mask) {
+ char accum[64];
+
+ accum[0] = '\0';
if (mask == PairwiseCiphersMask::NONE)
strcpy(accum, "NONE");
@@ -564,12 +425,14 @@
if (mSuppl->setNetworkVar(mNetid, "pairwise", accum))
return -1;
- mAllowedPairwiseCiphers = mask;
+ mPairwiseCiphers = mask;
return 0;
}
-int WifiNetwork::setAllowedGroupCiphers(uint32_t mask) {
- char accum[255];
+int WifiNetwork::setGroupCiphers(uint32_t mask) {
+ char accum[64];
+
+ accum[0] = '\0';
if (mask & GroupCiphersMask::WEP40)
strcat(accum, "WEP40 ");
@@ -582,7 +445,7 @@
if (mSuppl->setNetworkVar(mNetid, "group", accum))
return -1;
- mAllowedGroupCiphers = mask;
+ mGroupCiphers = mask;
return 0;
}
@@ -594,7 +457,7 @@
errno = EAGAIN;
return -1;
}
- if (getAllowedKeyManagement() == KeyManagementMask::UNKNOWN) {
+ if (getKeyManagement() == KeyManagementMask::UNKNOWN) {
LOGE("Cannot enable network when KeyManagement is not set");
errno = EAGAIN;
return -1;
@@ -608,29 +471,500 @@
return 0;
}
-int WifiNetwork::registerProperties() {
- for (const char **p = WifiNetwork::PropertyNames; *p != '\0'; p++) {
- char *tmp;
- asprintf(&tmp, "wifi.net.%d.%s", mNetid, *p);
-
- if (NetworkManager::Instance()->getPropMngr()->registerProperty(tmp,
- this)) {
- free(tmp);
- return -1;
- }
- free(tmp);
- }
+int WifiNetwork::attachProperties(PropertyManager *pm, const char *nsName) {
+ pm->attachProperty(nsName, mStaticProperties.propSsid);
+ pm->attachProperty(nsName, mStaticProperties.propBssid);
+ pm->attachProperty(nsName, mStaticProperties.propPsk);
+ pm->attachProperty(nsName, mStaticProperties.propWepKey);
+ pm->attachProperty(nsName, mStaticProperties.propDefKeyIdx);
+ pm->attachProperty(nsName, mStaticProperties.propPriority);
+ pm->attachProperty(nsName, mStaticProperties.propKeyManagement);
+ pm->attachProperty(nsName, mStaticProperties.propProtocols);
+ pm->attachProperty(nsName, mStaticProperties.propAuthAlgorithms);
+ pm->attachProperty(nsName, mStaticProperties.propPairwiseCiphers);
+ pm->attachProperty(nsName, mStaticProperties.propGroupCiphers);
+ pm->attachProperty(nsName, mStaticProperties.propHiddenSsid);
+ pm->attachProperty(nsName, mStaticProperties.propEnabled);
return 0;
}
-int WifiNetwork::unregisterProperties() {
- for (const char **p = WifiNetwork::PropertyNames; *p != '\0'; p++) {
- char *tmp;
- asprintf(&tmp, "wifi.net.%d.%s", mNetid, *p);
+int WifiNetwork::detachProperties(PropertyManager *pm, const char *nsName) {
+ pm->detachProperty(nsName, mStaticProperties.propEnabled);
+ pm->detachProperty(nsName, mStaticProperties.propSsid);
+ pm->detachProperty(nsName, mStaticProperties.propBssid);
+ pm->detachProperty(nsName, mStaticProperties.propPsk);
+ pm->detachProperty(nsName, mStaticProperties.propWepKey);
+ pm->detachProperty(nsName, mStaticProperties.propDefKeyIdx);
+ pm->detachProperty(nsName, mStaticProperties.propPriority);
+ pm->detachProperty(nsName, mStaticProperties.propKeyManagement);
+ pm->detachProperty(nsName, mStaticProperties.propProtocols);
+ pm->detachProperty(nsName, mStaticProperties.propAuthAlgorithms);
+ pm->detachProperty(nsName, mStaticProperties.propPairwiseCiphers);
+ pm->detachProperty(nsName, mStaticProperties.propGroupCiphers);
+ pm->detachProperty(nsName, mStaticProperties.propHiddenSsid);
+ return 0;
+}
- if (NetworkManager::Instance()->getPropMngr()->unregisterProperty(tmp))
- LOGW("Unable to remove property '%s' (%s)", tmp, strerror(errno));
- free(tmp);
+int WifiNetwork::parseKeyManagementMask(const char *buffer, uint32_t *mask) {
+ bool none = false;
+ char *v_tmp = strdup(buffer);
+ char *v_next = v_tmp;
+ char *v_token;
+
+// LOGD("parseKeyManagementMask(%s)", buffer);
+ *mask = 0;
+
+ while((v_token = strsep(&v_next, " "))) {
+ if (!strcasecmp(v_token, "NONE")) {
+ *mask = KeyManagementMask::NONE;
+ none = true;
+ } else if (!none) {
+ if (!strcasecmp(v_token, "WPA-PSK"))
+ *mask |= KeyManagementMask::WPA_PSK;
+ else if (!strcasecmp(v_token, "WPA-EAP"))
+ *mask |= KeyManagementMask::WPA_EAP;
+ else if (!strcasecmp(v_token, "IEEE8021X"))
+ *mask |= KeyManagementMask::IEEE8021X;
+ else {
+ LOGW("Invalid KeyManagementMask value '%s'", v_token);
+ errno = EINVAL;
+ free(v_tmp);
+ return -1;
+ }
+ } else {
+ LOGW("KeyManagementMask value '%s' when NONE", v_token);
+ errno = EINVAL;
+ free(v_tmp);
+ return -1;
+ }
+ }
+ free(v_tmp);
+ return 0;
+}
+
+int WifiNetwork::parseProtocolsMask(const char *buffer, uint32_t *mask) {
+ bool none = false;
+ char *v_tmp = strdup(buffer);
+ char *v_next = v_tmp;
+ char *v_token;
+
+// LOGD("parseProtocolsMask(%s)", buffer);
+ *mask = 0;
+ while((v_token = strsep(&v_next, " "))) {
+ if (!strcasecmp(v_token, "WPA"))
+ *mask |= SecurityProtocolMask::WPA;
+ else if (!strcasecmp(v_token, "RSN"))
+ *mask |= SecurityProtocolMask::RSN;
+ else {
+ LOGW("Invalid ProtocolsMask value '%s'", v_token);
+ errno = EINVAL;
+ free(v_tmp);
+ return -1;
+ }
+ }
+
+ free(v_tmp);
+ return 0;
+}
+
+int WifiNetwork::parseAuthAlgorithmsMask(const char *buffer, uint32_t *mask) {
+ bool none = false;
+ char *v_tmp = strdup(buffer);
+ char *v_next = v_tmp;
+ char *v_token;
+
+// LOGD("parseAuthAlgorithmsMask(%s)", buffer);
+
+ *mask = 0;
+ if (buffer[0] == '\0')
+ return 0;
+
+ while((v_token = strsep(&v_next, " "))) {
+ if (!strcasecmp(v_token, "OPEN"))
+ *mask |= AuthenticationAlgorithmMask::OPEN;
+ else if (!strcasecmp(v_token, "SHARED"))
+ *mask |= AuthenticationAlgorithmMask::SHARED;
+ else if (!strcasecmp(v_token, "LEAP"))
+ *mask |= AuthenticationAlgorithmMask::LEAP;
+ else {
+ LOGW("Invalid AuthAlgorithmsMask value '%s'", v_token);
+ errno = EINVAL;
+ free(v_tmp);
+ return -1;
+ }
+ }
+ free(v_tmp);
+ return 0;
+}
+
+int WifiNetwork::parsePairwiseCiphersMask(const char *buffer, uint32_t *mask) {
+ bool none = false;
+ char *v_tmp = strdup(buffer);
+ char *v_next = v_tmp;
+ char *v_token;
+
+// LOGD("parsePairwiseCiphersMask(%s)", buffer);
+
+ *mask = 0;
+ while((v_token = strsep(&v_next, " "))) {
+ if (!strcasecmp(v_token, "NONE")) {
+ *mask = PairwiseCiphersMask::NONE;
+ none = true;
+ } else if (!none) {
+ if (!strcasecmp(v_token, "TKIP"))
+ *mask |= PairwiseCiphersMask::TKIP;
+ else if (!strcasecmp(v_token, "CCMP"))
+ *mask |= PairwiseCiphersMask::CCMP;
+ else {
+ LOGW("PairwiseCiphersMask value '%s' when NONE", v_token);
+ errno = EINVAL;
+ free(v_tmp);
+ return -1;
+ }
+ } else {
+ LOGW("Invalid PairwiseCiphersMask value '%s'", v_token);
+ errno = EINVAL;
+ free(v_tmp);
+ return -1;
+ }
+ }
+ free(v_tmp);
+ return 0;
+}
+
+int WifiNetwork::parseGroupCiphersMask(const char *buffer, uint32_t *mask) {
+ bool none = false;
+ char *v_tmp = strdup(buffer);
+ char *v_next = v_tmp;
+ char *v_token;
+
+// LOGD("parseGroupCiphersMask(%s)", buffer);
+
+ *mask = 0;
+ while((v_token = strsep(&v_next, " "))) {
+ if (!strcasecmp(v_token, "WEP40"))
+ *mask |= GroupCiphersMask::WEP40;
+ else if (!strcasecmp(v_token, "WEP104"))
+ *mask |= GroupCiphersMask::WEP104;
+ else if (!strcasecmp(v_token, "TKIP"))
+ *mask |= GroupCiphersMask::TKIP;
+ else if (!strcasecmp(v_token, "CCMP"))
+ *mask |= GroupCiphersMask::CCMP;
+ else {
+ LOGW("Invalid GroupCiphersMask value '%s'", v_token);
+ errno = EINVAL;
+ free(v_tmp);
+ return -1;
+ }
+ }
+ free(v_tmp);
+ return 0;
+}
+
+WifiNetwork::WifiNetworkIntegerProperty::WifiNetworkIntegerProperty(WifiNetwork *wn,
+ const char *name,
+ bool ro,
+ int elements) :
+ IntegerProperty(name, ro, elements) {
+ mWn = wn;
+}
+
+WifiNetwork::WifiNetworkStringProperty::WifiNetworkStringProperty(WifiNetwork *wn,
+ const char *name,
+ bool ro, int elements) :
+ StringProperty(name, ro, elements) {
+ mWn = wn;
+}
+
+WifiNetwork::WifiNetworkEnabledProperty::WifiNetworkEnabledProperty(WifiNetwork *wn) :
+ WifiNetworkIntegerProperty(wn, "Enabled", false, 1) {
+}
+
+int WifiNetwork::WifiNetworkEnabledProperty::get(int idx, int *buffer) {
+ *buffer = mWn->mEnabled;
+ return 0;
+}
+int WifiNetwork::WifiNetworkEnabledProperty::set(int idx, int value) {
+ return mWn->setEnabled(value == 1);
+}
+
+WifiNetwork::WifiNetworkSsidProperty::WifiNetworkSsidProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "Ssid", false, 1) {
+}
+
+int WifiNetwork::WifiNetworkSsidProperty::get(int idx, char *buffer, size_t max) {
+ strncpy(buffer,
+ mWn->getSsid() ? mWn->getSsid() : "none",
+ max);
+ return 0;
+}
+int WifiNetwork::WifiNetworkSsidProperty::set(int idx, const char *value) {
+ return mWn->setSsid(value);
+}
+
+WifiNetwork::WifiNetworkBssidProperty::WifiNetworkBssidProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "Bssid", false, 1) {
+}
+int WifiNetwork::WifiNetworkBssidProperty::get(int idx, char *buffer, size_t max) {
+ strncpy(buffer,
+ mWn->getBssid() ? mWn->getBssid() : "none",
+ max);
+ return 0;
+}
+int WifiNetwork::WifiNetworkBssidProperty::set(int idx, const char *value) {
+ return mWn->setBssid(value);
+}
+
+WifiNetwork::WifiNetworkPskProperty::WifiNetworkPskProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "Psk", false, 1) {
+}
+int WifiNetwork::WifiNetworkPskProperty::get(int idx, char *buffer, size_t max) {
+ strncpy(buffer,
+ mWn->getPsk() ? mWn->getPsk() : "none",
+ max);
+ return 0;
+}
+int WifiNetwork::WifiNetworkPskProperty::set(int idx, const char *value) {
+ return mWn->setPsk(value);
+}
+
+WifiNetwork::WifiNetworkWepKeyProperty::WifiNetworkWepKeyProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "WepKey", false, 4) {
+}
+
+int WifiNetwork::WifiNetworkWepKeyProperty::get(int idx, char *buffer, size_t max) {
+ const char *key = mWn->getWepKey(idx);
+
+ strncpy(buffer, (key ? key : "none"), max);
+ return 0;
+}
+int WifiNetwork::WifiNetworkWepKeyProperty::set(int idx, const char *value) {
+ return mWn->setWepKey(idx, value);
+}
+
+WifiNetwork::WifiNetworkDefaultKeyIndexProperty::WifiNetworkDefaultKeyIndexProperty(WifiNetwork *wn) :
+ WifiNetworkIntegerProperty(wn, "DefaultKeyIndex", false, 1) {
+}
+int WifiNetwork::WifiNetworkDefaultKeyIndexProperty::get(int idx, int *buffer) {
+ *buffer = mWn->getDefaultKeyIndex();
+ return 0;
+}
+int WifiNetwork::WifiNetworkDefaultKeyIndexProperty::set(int idx, int value) {
+ return mWn->setDefaultKeyIndex(value);
+}
+
+WifiNetwork::WifiNetworkPriorityProperty::WifiNetworkPriorityProperty(WifiNetwork *wn) :
+ WifiNetworkIntegerProperty(wn, "Priority", false, 1) {
+}
+int WifiNetwork::WifiNetworkPriorityProperty::get(int idx, int *buffer) {
+ *buffer = mWn->getPriority();
+ return 0;
+}
+int WifiNetwork::WifiNetworkPriorityProperty::set(int idx, int value) {
+ return mWn->setPriority(value);
+}
+
+WifiNetwork::WifiNetworkKeyManagementProperty::WifiNetworkKeyManagementProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "KeyManagement", false, 1) {
+}
+int WifiNetwork::WifiNetworkKeyManagementProperty::get(int idx, char *buffer, size_t max) {
+
+ if (mWn->getKeyManagement() == KeyManagementMask::NONE)
+ strncpy(buffer, "NONE", max);
+ else {
+ char tmp[80] = { '\0' };
+
+ if (mWn->getKeyManagement() & KeyManagementMask::WPA_PSK)
+ strcat(tmp, "WPA-PSK");
+ if (mWn->getKeyManagement() & KeyManagementMask::WPA_EAP) {
+ if (tmp[0] != '\0')
+ strcat(tmp, " ");
+ strcat(tmp, "WPA-EAP");
+ }
+ if (mWn->getKeyManagement() & KeyManagementMask::IEEE8021X) {
+ if (tmp[0] != '\0')
+ strcat(tmp, " ");
+ strcat(tmp, "IEEE8021X");
+ }
+ if (tmp[0] == '\0') {
+ strncpy(buffer, "(internal error)", max);
+ errno = ENOENT;
+ return -1;
+ }
+ if (tmp[strlen(tmp)] == ' ')
+ tmp[strlen(tmp)] = '\0';
+
+ strncpy(buffer, tmp, max);
}
return 0;
}
+int WifiNetwork::WifiNetworkKeyManagementProperty::set(int idx, const char *value) {
+ uint32_t mask;
+ if (mWn->parseKeyManagementMask(value, &mask))
+ return -1;
+ return mWn->setKeyManagement(mask);
+}
+
+WifiNetwork::WifiNetworkProtocolsProperty::WifiNetworkProtocolsProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "Protocols", false, 1) {
+}
+int WifiNetwork::WifiNetworkProtocolsProperty::get(int idx, char *buffer, size_t max) {
+ char tmp[80] = { '\0' };
+
+ if (mWn->getProtocols() & SecurityProtocolMask::WPA)
+ strcat(tmp, "WPA");
+ if (mWn->getProtocols() & SecurityProtocolMask::RSN) {
+ if (tmp[0] != '\0')
+ strcat(tmp, " ");
+ strcat(tmp, "RSN");
+ }
+
+ if (tmp[0] == '\0') {
+ strncpy(buffer, "(internal error)", max);
+ errno = ENOENT;
+ return NULL;
+ }
+ if (tmp[strlen(tmp)] == ' ')
+ tmp[strlen(tmp)] = '\0';
+
+ strncpy(buffer, tmp, max);
+ return 0;
+}
+int WifiNetwork::WifiNetworkProtocolsProperty::set(int idx, const char *value) {
+ uint32_t mask;
+ if (mWn->parseProtocolsMask(value, &mask))
+ return -1;
+ return mWn->setProtocols(mask);
+}
+
+WifiNetwork::WifiNetworkAuthAlgorithmsProperty::WifiNetworkAuthAlgorithmsProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "AuthAlgorithms", false, 1) {
+}
+int WifiNetwork::WifiNetworkAuthAlgorithmsProperty::get(int idx, char *buffer, size_t max) {
+ char tmp[80] = { '\0' };
+
+ if (mWn->getAuthAlgorithms() == 0) {
+ strncpy(buffer, "NONE", max);
+ return 0;
+ }
+
+ if (mWn->getAuthAlgorithms() & AuthenticationAlgorithmMask::OPEN)
+ strcat(tmp, "OPEN");
+ if (mWn->getAuthAlgorithms() & AuthenticationAlgorithmMask::SHARED) {
+ if (tmp[0] != '\0')
+ strcat(tmp, " ");
+ strcat(tmp, "SHARED");
+ }
+ if (mWn->getAuthAlgorithms() & AuthenticationAlgorithmMask::LEAP) {
+ if (tmp[0] != '\0')
+ strcat(tmp, " ");
+ strcat(tmp, "LEAP");
+ }
+
+ if (tmp[0] == '\0') {
+ strncpy(buffer, "(internal error)", max);
+ errno = ENOENT;
+ return NULL;
+ }
+ if (tmp[strlen(tmp)] == ' ')
+ tmp[strlen(tmp)] = '\0';
+
+ strncpy(buffer, tmp, max);
+ return 0;
+}
+int WifiNetwork::WifiNetworkAuthAlgorithmsProperty::set(int idx, const char *value) {
+ uint32_t mask;
+ if (mWn->parseAuthAlgorithmsMask(value, &mask))
+ return -1;
+ return mWn->setAuthAlgorithms(mask);
+}
+
+WifiNetwork::WifiNetworkPairwiseCiphersProperty::WifiNetworkPairwiseCiphersProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "PairwiseCiphers", false, 1) {
+}
+int WifiNetwork::WifiNetworkPairwiseCiphersProperty::get(int idx, char *buffer, size_t max) {
+ if (mWn->getPairwiseCiphers() == PairwiseCiphersMask::NONE)
+ strncpy(buffer, "NONE", max);
+ else {
+ char tmp[80] = { '\0' };
+
+ if (mWn->getPairwiseCiphers() & PairwiseCiphersMask::TKIP)
+ strcat(tmp, "TKIP");
+ if (mWn->getPairwiseCiphers() & PairwiseCiphersMask::CCMP) {
+ if (tmp[0] != '\0')
+ strcat(tmp, " ");
+ strcat(tmp, "CCMP");
+ }
+ if (tmp[0] == '\0') {
+ strncpy(buffer, "(internal error)", max);
+ errno = ENOENT;
+ return NULL;
+ }
+ if (tmp[strlen(tmp)] == ' ')
+ tmp[strlen(tmp)] = '\0';
+
+ strncpy(buffer, tmp, max);
+ }
+ return 0;
+}
+int WifiNetwork::WifiNetworkPairwiseCiphersProperty::set(int idx, const char *value) {
+ uint32_t mask;
+ if (mWn->parsePairwiseCiphersMask(value, &mask))
+ return -1;
+ return mWn->setPairwiseCiphers(mask);
+}
+
+WifiNetwork::WifiNetworkGroupCiphersProperty::WifiNetworkGroupCiphersProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "GroupCiphers", false, 1) {
+}
+int WifiNetwork::WifiNetworkGroupCiphersProperty::get(int idx, char *buffer, size_t max) {
+ char tmp[80] = { '\0' };
+
+ if (mWn->getGroupCiphers() & GroupCiphersMask::WEP40)
+ strcat(tmp, "WEP40");
+ if (mWn->getGroupCiphers() & GroupCiphersMask::WEP104) {
+ if (tmp[0] != '\0')
+ strcat(tmp, " ");
+ strcat(tmp, "WEP104");
+ }
+ if (mWn->getGroupCiphers() & GroupCiphersMask::TKIP) {
+ if (tmp[0] != '\0')
+ strcat(tmp, " ");
+ strcat(tmp, "TKIP");
+ }
+ if (mWn->getGroupCiphers() & GroupCiphersMask::CCMP) {
+ if (tmp[0] != '\0')
+ strcat(tmp, " ");
+ strcat(tmp, "CCMP");
+ }
+
+ if (tmp[0] == '\0') {
+ strncpy(buffer, "(internal error)", max);
+ errno = ENOENT;
+ return -1;
+ }
+ if (tmp[strlen(tmp)] == ' ')
+ tmp[strlen(tmp)] = '\0';
+
+ strncpy(buffer, tmp, max);
+ return 0;
+}
+int WifiNetwork::WifiNetworkGroupCiphersProperty::set(int idx, const char *value) {
+ uint32_t mask;
+ if (mWn->parseGroupCiphersMask(value, &mask))
+ return -1;
+ return mWn->setGroupCiphers(mask);
+}
+
+WifiNetwork::WifiNetworkHiddenSsidProperty::WifiNetworkHiddenSsidProperty(WifiNetwork *wn) :
+ WifiNetworkStringProperty(wn, "HiddenSsid", false, 1) {
+}
+int WifiNetwork::WifiNetworkHiddenSsidProperty::get(int idx, char *buffer, size_t max) {
+ const char *scan_ssid = mWn->getHiddenSsid();
+
+ strncpy(buffer, (scan_ssid ? scan_ssid : "none"), max);
+ return 0;
+}
+int WifiNetwork::WifiNetworkHiddenSsidProperty::set(int idx, const char *value) {
+ return mWn->setHiddenSsid(value);
+}
diff --git a/nexus/WifiNetwork.h b/nexus/WifiNetwork.h
index c2f5d23..15ec647 100644
--- a/nexus/WifiNetwork.h
+++ b/nexus/WifiNetwork.h
@@ -21,6 +21,10 @@
#include <utils/List.h>
+#include "Property.h"
+
+class PropertyManager;
+
class KeyManagementMask {
public:
static const uint32_t UNKNOWN = 0;
@@ -60,19 +64,140 @@
};
class Supplicant;
-class InterfaceConfig;
class Controller;
class WifiController;
-#include "IPropertyProvider.h"
+class WifiNetwork {
+ class WifiNetworkIntegerProperty : public IntegerProperty {
+ protected:
+ WifiNetwork *mWn;
+ public:
+ WifiNetworkIntegerProperty(WifiNetwork *wn, const char *name, bool ro,
+ int elements);
+ virtual ~WifiNetworkIntegerProperty() {}
+ virtual int set(int idx, int value) = 0;
+ virtual int get(int idx, int *buffer) = 0;
+ };
+ friend class WifiNetwork::WifiNetworkIntegerProperty;
-class WifiNetwork : public IPropertyProvider{
-public:
- static const char *PropertyNames[];
+ class WifiNetworkStringProperty : public StringProperty {
+ protected:
+ WifiNetwork *mWn;
+ public:
+ WifiNetworkStringProperty(WifiNetwork *wn, const char *name, bool ro,
+ int elements);
+ virtual ~WifiNetworkStringProperty() {}
+ virtual int set(int idx, const char *value) = 0;
+ virtual int get(int idx, char *buffer, size_t max) = 0;
+ };
+ friend class WifiNetwork::WifiNetworkStringProperty;
+
+ class WifiNetworkEnabledProperty : public WifiNetworkIntegerProperty {
+ public:
+ WifiNetworkEnabledProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkEnabledProperty() {};
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiNetworkPriorityProperty : public WifiNetworkIntegerProperty {
+ public:
+ WifiNetworkPriorityProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkPriorityProperty() {};
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiNetworkDefaultKeyIndexProperty : public WifiNetworkIntegerProperty {
+ public:
+ WifiNetworkDefaultKeyIndexProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkDefaultKeyIndexProperty() {};
+ int set(int idx, int value);
+ int get(int idx, int *buffer);
+ };
+
+ class WifiNetworkSsidProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkSsidProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkSsidProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiNetworkBssidProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkBssidProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkBssidProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiNetworkPskProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkPskProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkPskProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiNetworkKeyManagementProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkKeyManagementProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkKeyManagementProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiNetworkAuthAlgorithmsProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkAuthAlgorithmsProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkAuthAlgorithmsProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiNetworkProtocolsProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkProtocolsProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkProtocolsProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiNetworkWepKeyProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkWepKeyProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkWepKeyProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiNetworkPairwiseCiphersProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkPairwiseCiphersProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkPairwiseCiphersProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiNetworkGroupCiphersProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkGroupCiphersProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkGroupCiphersProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
+
+ class WifiNetworkHiddenSsidProperty : public WifiNetworkStringProperty {
+ public:
+ WifiNetworkHiddenSsidProperty(WifiNetwork *wn);
+ virtual ~WifiNetworkHiddenSsidProperty() {};
+ int set(int idx, const char *value);
+ int get(int idx, char *buffer, size_t max);
+ };
private:
Supplicant *mSuppl;
- InterfaceConfig *mIfaceCfg;
WifiController *mController;
/*
@@ -128,33 +253,49 @@
/*
* The set of key management protocols supported by this configuration.
*/
- uint32_t mAllowedKeyManagement;
+ uint32_t mKeyManagement;
/*
* The set of security protocols supported by this configuration.
*/
- uint32_t mAllowedProtocols;
+ uint32_t mProtocols;
/*
* The set of authentication protocols supported by this configuration.
*/
- uint32_t mAllowedAuthAlgorithms;
+ uint32_t mAuthAlgorithms;
/*
* The set of pairwise ciphers for WPA supported by this configuration.
*/
- uint32_t mAllowedPairwiseCiphers;
+ uint32_t mPairwiseCiphers;
/*
* The set of group ciphers for WPA supported by this configuration.
*/
- uint32_t mAllowedGroupCiphers;
+ uint32_t mGroupCiphers;
/*
* Set if this Network is enabled
*/
bool mEnabled;
+ char *mPropNamespace;
+ struct {
+ WifiNetworkEnabledProperty *propEnabled;
+ WifiNetworkSsidProperty *propSsid;
+ WifiNetworkBssidProperty *propBssid;
+ WifiNetworkPskProperty *propPsk;
+ WifiNetworkWepKeyProperty *propWepKey;
+ WifiNetworkDefaultKeyIndexProperty *propDefKeyIdx;
+ WifiNetworkPriorityProperty *propPriority;
+ WifiNetworkKeyManagementProperty *propKeyManagement;
+ WifiNetworkProtocolsProperty *propProtocols;
+ WifiNetworkAuthAlgorithmsProperty *propAuthAlgorithms;
+ WifiNetworkPairwiseCiphersProperty *propPairwiseCiphers;
+ WifiNetworkGroupCiphersProperty *propGroupCiphers;
+ WifiNetworkHiddenSsidProperty *propHiddenSsid;
+ } mStaticProperties;
private:
WifiNetwork();
@@ -165,8 +306,8 @@
virtual ~WifiNetwork();
WifiNetwork *clone();
- int registerProperties();
- int unregisterProperties();
+ int attachProperties(PropertyManager *pm, const char *nsName);
+ int detachProperties(PropertyManager *pm, const char *nsName);
int getNetworkId() { return mNetid; }
const char *getSsid() { return mSsid; }
@@ -176,19 +317,14 @@
int getDefaultKeyIndex() { return mDefaultKeyIndex; }
int getPriority() { return mPriority; }
const char *getHiddenSsid() { return mHiddenSsid; }
- uint32_t getAllowedKeyManagement() { return mAllowedKeyManagement; }
- uint32_t getAllowedProtocols() { return mAllowedProtocols; }
- uint32_t getAllowedAuthAlgorithms() { return mAllowedAuthAlgorithms; }
- uint32_t getAllowedPairwiseCiphers() { return mAllowedPairwiseCiphers; }
- uint32_t getAllowedGroupCiphers() { return mAllowedGroupCiphers; }
+ uint32_t getKeyManagement() { return mKeyManagement; }
+ uint32_t getProtocols() { return mProtocols; }
+ uint32_t getAuthAlgorithms() { return mAuthAlgorithms; }
+ uint32_t getPairwiseCiphers() { return mPairwiseCiphers; }
+ uint32_t getGroupCiphers() { return mGroupCiphers; }
bool getEnabled() { return mEnabled; }
Controller *getController() { return (Controller *) mController; }
- int set(const char *name, const char *value);
- const char *get(const char *name, char *buffer, size_t maxsize);
-
- InterfaceConfig *getIfaceCfg() { return mIfaceCfg; }
-
int setEnabled(bool enabled);
int setSsid(const char *ssid);
int setBssid(const char *bssid);
@@ -197,14 +333,22 @@
int setDefaultKeyIndex(int idx);
int setPriority(int pri);
int setHiddenSsid(const char *ssid);
- int setAllowedKeyManagement(uint32_t mask);
- int setAllowedProtocols(uint32_t mask);
- int setAllowedAuthAlgorithms(uint32_t mask);
- int setAllowedPairwiseCiphers(uint32_t mask);
- int setAllowedGroupCiphers(uint32_t mask);
+ int setKeyManagement(uint32_t mask);
+ int setProtocols(uint32_t mask);
+ int setAuthAlgorithms(uint32_t mask);
+ int setPairwiseCiphers(uint32_t mask);
+ int setGroupCiphers(uint32_t mask);
// XXX:Should this really be exposed?.. meh
int refresh();
+
+private:
+ int parseKeyManagementMask(const char *buffer, uint32_t *mask);
+ int parseProtocolsMask(const char *buffer, uint32_t *mask);
+ int parseAuthAlgorithmsMask(const char *buffer, uint32_t *mask);
+ int parsePairwiseCiphersMask(const char *buffer, uint32_t *mask);
+ int parseGroupCiphersMask(const char *buffer, uint32_t *mask);
+ void createProperties();
};
typedef android::List<WifiNetwork *> WifiNetworkCollection;
diff --git a/nexus/WifiStatusPoller.cpp b/nexus/WifiStatusPoller.cpp
new file mode 100644
index 0000000..cf71733
--- /dev/null
+++ b/nexus/WifiStatusPoller.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+#define LOG_TAG "WifiStatusPoller"
+#include <cutils/log.h>
+
+#include "WifiStatusPoller.h"
+#include "IWifiStatusPollerHandler.h"
+
+
+WifiStatusPoller::WifiStatusPoller(IWifiStatusPollerHandler *handler) :
+ mHandlers(handler) {
+ mPollingInterval = 5;
+ mStarted = false;
+}
+
+int WifiStatusPoller::start() {
+
+ if (pipe(mCtrlPipe))
+ return -1;
+
+ if (pthread_create(&mThread, NULL, WifiStatusPoller::threadStart, this))
+ return -1;
+
+ return 0;
+}
+
+int WifiStatusPoller::stop() {
+ char c = 0;
+
+ if (write(mCtrlPipe[1], &c, 1) != 1) {
+ LOGE("Error writing to control pipe (%s)", strerror(errno));
+ return -1;
+ }
+
+ void *ret;
+ if (pthread_join(mThread, &ret)) {
+ LOGE("Error joining to listener thread (%s)", strerror(errno));
+ return -1;
+ }
+ close(mCtrlPipe[0]);
+ close(mCtrlPipe[1]);
+ return 0;
+}
+
+void *WifiStatusPoller::threadStart(void *obj) {
+ WifiStatusPoller *me = reinterpret_cast<WifiStatusPoller *>(obj);
+
+ me->mStarted = true;
+ LOGD("Starting");
+ me->run();
+ me->mStarted = false;
+ LOGD("Stopping");
+ pthread_exit(NULL);
+ return NULL;
+}
+
+void WifiStatusPoller::run() {
+
+ while(1) {
+ struct timeval to;
+ fd_set read_fds;
+ int rc = 0;
+ int max = 0;
+
+ FD_ZERO(&read_fds);
+ to.tv_usec = 0;
+ to.tv_sec = mPollingInterval;
+
+ FD_SET(mCtrlPipe[0], &read_fds);
+ max = mCtrlPipe[0];
+
+ if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) {
+ LOGE("select failed (%s)", strerror(errno));
+ sleep(1);
+ continue;
+ } else if (!rc) {
+ mHandlers->onStatusPollInterval();
+ }
+ if (FD_ISSET(mCtrlPipe[0], &read_fds))
+ break;
+ }
+}
diff --git a/nexus/WifiStatusPoller.h b/nexus/WifiStatusPoller.h
new file mode 100644
index 0000000..202bbbf
--- /dev/null
+++ b/nexus/WifiStatusPoller.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _WIFI_STATUS_POLLER_H
+#define _WIFI_STATUS_POLLER_H
+
+#include <pthread.h>
+
+class IWifiStatusPollerHandler;
+
+class WifiStatusPoller {
+ pthread_t mThread;
+ int mCtrlPipe[2];
+ int mPollingInterval;
+ IWifiStatusPollerHandler *mHandlers;
+ bool mStarted;
+
+public:
+ WifiStatusPoller(IWifiStatusPollerHandler *handler);
+ virtual ~WifiStatusPoller() {}
+
+ int start();
+ int stop();
+ bool isStarted() { return mStarted; }
+
+ void setPollingInterval(int interval);
+ int getPollingInterval() { return mPollingInterval; }
+
+private:
+ static void *threadStart(void *obj);
+ void run();
+};
+
+#endif