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>
This commit is contained in:
San Mehat 2009-06-23 21:10:57 -07:00
parent a0c0d8a89e
commit c4a895b709
41 changed files with 3282 additions and 861 deletions

View File

@ -33,7 +33,7 @@ public:
SocketListener(const char *socketNames, bool listen);
SocketListener(int socketFd, bool listen);
virtual ~SocketListener() {}
virtual ~SocketListener();
int startListener();
int stopListener();

View File

@ -56,24 +56,73 @@ void FrameworkListener::registerCmd(FrameworkCommand *cmd) {
}
void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
int argc;
FrameworkCommandCollection::iterator i;
int argc = 0;
char *argv[FrameworkListener::CMD_ARGS_MAX];
char tmp[255];
char *p = data;
char *q = tmp;
bool esc = false;
bool quote = false;
int k;
if (!index(data, '"')) {
char *next = data;
char *field;
int i;
memset(argv, 0, sizeof(argv));
memset(tmp, 0, sizeof(tmp));
while(*p) {
if (*p == '\\') {
if (esc) {
*q++ = '\\';
esc = false;
} else
esc = true;
p++;
continue;
} else if (esc) {
if (*p == '"')
*q++ = '"';
else if (*p == '\\')
*q++ = '\\';
else {
cli->sendMsg(500, "Unsupported escape sequence", false);
goto out;
}
p++;
esc = false;
continue;
}
for (i = 0; (i < FrameworkListener::CMD_ARGS_MAX) &&
(argv[i] = strsep(&next, " ")); i++);
argc = i+1;
} else {
LOGD("blehhh not supported");
return;
if (*p == '"') {
if (quote)
quote = false;
else
quote = true;
p++;
continue;
}
*q = *p++;
if (!quote && *q == ' ') {
*q = '\0';
argv[argc++] = strdup(tmp);
memset(tmp, 0, sizeof(tmp));
q = tmp;
continue;
}
q++;
}
FrameworkCommandCollection::iterator i;
argv[argc++] = strdup(tmp);
#if 0
for (k = 0; k < argc; k++) {
LOGD("arg[%d] = '%s'", k, argv[k]);
}
#endif
if (quote) {
cli->sendMsg(500, "Unclosed quotes error", false);
goto out;
}
for (i = mCommands->begin(); i != mCommands->end(); ++i) {
FrameworkCommand *c = *i;
@ -81,10 +130,14 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
if (c->runCommand(cli, argc, argv)) {
LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno));
}
return;
goto out;
}
}
cli->sendMsg(500, "Command not recognized", false);
out:
int j;
for (j = 0; j < argc; j++)
free(argv[j]);
return;
}

View File

@ -45,9 +45,26 @@ SocketListener::SocketListener(int socketFd, bool listen) {
mClients = new SocketClientCollection();
}
SocketListener::~SocketListener() {
if (mSocketName && mSock > -1)
close(mSock);
if (mCtrlPipe[0] != -1) {
close(mCtrlPipe[0]);
close(mCtrlPipe[1]);
}
SocketClientCollection::iterator it;
for (it = mClients->begin(); it != mClients->end(); ++it) {
delete (*it);
it = mClients->erase(it);
}
delete mClients;
}
int SocketListener::startListener() {
if (!mSocketName && mSock == -1) {
LOGE("Failed to start unbound listener");
errno = EINVAL;
return -1;
} else if (mSocketName) {
@ -64,11 +81,15 @@ int SocketListener::startListener() {
} else if (!mListen)
mClients->push_back(new SocketClient(mSock));
if (pipe(mCtrlPipe))
if (pipe(mCtrlPipe)) {
LOGE("pipe failed (%s)", strerror(errno));
return -1;
}
if (pthread_create(&mThread, NULL, SocketListener::threadStart, this))
if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) {
LOGE("pthread_create (%s)", strerror(errno));
return -1;
}
return 0;
}
@ -88,6 +109,19 @@ int SocketListener::stopListener() {
}
close(mCtrlPipe[0]);
close(mCtrlPipe[1]);
mCtrlPipe[0] = -1;
mCtrlPipe[1] = -1;
if (mSocketName && mSock > -1) {
close(mSock);
mSock = -1;
}
SocketClientCollection::iterator it;
for (it = mClients->begin(); it != mClients->end(); ++it) {
delete (*it);
it = mClients->erase(it);
}
return 0;
}

View File

@ -7,23 +7,22 @@ include $(CLEAR_VARS)
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 @@ LOCAL_SRC_FILES:= \
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

View File

@ -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 @@ int CommandListener::WifiCreateNetworkCmd::runCommand(SocketClient *cli,
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 @@ int CommandListener::WifiRemoveNetworkCmd::runCommand(SocketClient *cli,
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 @@ int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli,
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 @@ int CommandListener::WifiListNetworksCmd::runCommand(SocketClient *cli,
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 @@ int CommandListener::GetCmd::runCommand(SocketClient *cli, int argc, char **argv
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 @@ int CommandListener::SetCmd::runCommand(SocketClient *cli, int argc,
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 @@ CommandListener::ListCmd::ListCmd() :
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 @@ int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **arg
free((*it));
continue;
}
cli->sendMsg(ErrorCode::PropertyList, buf, false);
cli->sendMsg(ResponseCode::PropertyList, buf, false);
free(buf);
free((*it));
@ -226,6 +230,6 @@ int CommandListener::ListCmd::runCommand(SocketClient *cli, int argc, char **arg
delete pc;
cli->sendMsg(ErrorCode::CommandOkay, "Properties list complete.", false);
cli->sendMsg(ResponseCode::CommandOkay, "Properties list complete.", false);
return 0;
}

View File

@ -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 @@ int Controller::stop() {
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 @@ bail:
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;
}

View File

@ -26,9 +26,8 @@ class PropertyManager;
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 @@ public:
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);

View File

@ -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 @@ char *dhcp_get_errmsg();
}
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 @@ DhcpClient::~DhcpClient() {
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;
}

View File

@ -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();
};

56
nexus/DhcpEvent.cpp Normal file
View File

@ -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;
}
}

View File

@ -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;
static char *toString(int val, char *buffer, int max);
static int parseString(const char *buffer);
};
typedef android::List<IPropertyProvider *> IPropertyProviderCollection;
#endif

View File

@ -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;
}

View File

@ -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:

80
nexus/DhcpState.cpp Normal file
View File

@ -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;
}
}

View File

@ -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

View File

@ -22,8 +22,11 @@ class InterfaceConfig;
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

View File

@ -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

View File

@ -27,6 +27,7 @@ class SupplicantDisconnectedEvent;
class ISupplicantEventHandler {
public:
virtual ~ISupplicantEventHandler(){}
virtual void onAssociatingEvent(SupplicantAssociatingEvent *evt) = 0;
virtual void onAssociatedEvent(SupplicantAssociatedEvent *evt) = 0;
virtual void onConnectedEvent(SupplicantConnectedEvent *evt) = 0;

View File

@ -0,0 +1,26 @@
/*
* 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 _IWIFISTATUSPOLLER_HANDLER_H
#define _IWIFISTATUSPOLLER_HANDLER_H
class IWifiStatusPollerHandler {
public:
virtual ~IWifiStatusPollerHandler() {}
virtual void onStatusPollInterval() = 0;
};
#endif

View File

@ -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;
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;
}
InterfaceConfig::InterfaceDnsProperty::InterfaceDnsProperty(InterfaceConfig *c,
bool ro) :
IPV4AddressProperty("Dns", ro, 2) {
mCfg = c;
}
int InterfaceConfig::InterfaceDnsProperty::set(int idx, struct in_addr *value) {
memcpy(&mCfg->mDns[idx], value, sizeof(struct in_addr));
return 0;
}
int InterfaceConfig::InterfaceDnsProperty::get(int idx, struct in_addr *buf) {
memcpy(buf, &mCfg->mDns[idx], sizeof(struct in_addr));
return 0;
out_inval:
errno = EINVAL;
return -1;
}
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;
}

View File

@ -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;
struct {
IPV4AddressPropertyHelper *propIp;
IPV4AddressPropertyHelper *propNetmask;
IPV4AddressPropertyHelper *propGateway;
IPV4AddressPropertyHelper *propBroadcast;
InterfaceDnsProperty *propDns;
} mStaticProperties;
private:
char *mPropPrefix;
bool mUseDhcp;
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);
};
};

View File

@ -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);
}

View File

@ -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::Instance() {
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::run() {
}
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::startControllers() {
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;
}

View File

@ -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 InterfaceConfig;
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 @@ private:
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

203
nexus/Property.cpp Normal file
View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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 @@ public:
// 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

View File

@ -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 @@ bool Supplicant::isStarted() {
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 @@ int Supplicant::refreshNetworkList() {
return -1;
}
PropertyManager *pm = NetworkManager::Instance()->getPropMngr();
pthread_mutex_lock(&mNetworksLock);
int num_added = 0;
@ -182,7 +205,9 @@ int Supplicant::refreshNetworkList() {
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 @@ int Supplicant::refreshNetworkList() {
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 @@ int Supplicant::connectToSupplicant() {
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 @@ int Supplicant::triggerScan(bool active) {
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 @@ WifiNetwork *Supplicant::createNetwork() {
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 @@ int Supplicant::setNetworkVar(int networkId, const char *var, const char *val) {
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 @@ int Supplicant::enableNetwork(int networkId, bool enabled) {
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 @@ int Supplicant::retrieveInterfaceName() {
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;
}

View File

@ -30,7 +30,6 @@ class SupplicantStatus;
#include "ISupplicantEventHandler.h"
class Supplicant {
private:
struct wpa_ctrl *mCtrl;
struct wpa_ctrl *mMonitor;
SupplicantListener *mListener;
@ -50,7 +49,8 @@ public:
int stop();
bool isStarted();
int triggerScan(bool active);
int setScanMode(bool active);
int triggerScan();
WifiNetwork *createNetwork();
WifiNetwork *lookupNetwork(int networkId);
@ -63,6 +63,21 @@ public:
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; }

View File

@ -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);

View File

@ -51,6 +51,7 @@ int TiwlanWifiController::powerUp() {
int TiwlanWifiController::powerDown() {
if (mEventListener) {
delete mEventListener;
shutdown(mListenerSock, SHUT_RDWR);
close(mListenerSock);
mListenerSock = -1;
mEventListener = NULL;
@ -77,7 +78,8 @@ int TiwlanWifiController::loadFirmware() {
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::loadFirmware() {
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() {

View File

@ -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;
VpnController::VpnIntegerProperty::VpnIntegerProperty(VpnController *c,
const char *name,
bool ro,
int elements) :
IntegerProperty(name, ro, elements) {
mVc = c;
}
if (en == mEnabled)
return 0;
rc = (en ? enable() : disable());
VpnController::VpnStringProperty::VpnStringProperty(VpnController *c,
const char *name,
bool ro, int elements) :
StringProperty(name, ro, elements) {
mVc = c;
}
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) {
mEnabled = en;
if (en)
mPropMngr->unregisterProperty("vpn.gateway");
else
mPropMngr->unregisterProperty("vpn.gateway");
mVc->mPropMngr->attachProperty("vpn", mVc->mDynamicProperties.propGateway);
}
return rc;
} if (!strcmp(name, "vpn.gateway")) {
if (!inet_aton(value, &mVpnGateway)) {
errno = EINVAL;
return -1;
}
return 0;
}
return Controller::set(name, value);
}
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;
}
return Controller::get(name, buffer, maxsize);
if (!rc)
mVc->mEnabled = value;
return rc;
}

View File

@ -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 @@ public:
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

View File

@ -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 @@ WifiController::WifiController(PropertyManager *mPropMngr,
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 @@ int WifiController::enable() {
if (mSupplicant->refreshNetworkList())
LOGW("Error getting list of networks (%s)", strerror(errno));
mPropMngr->registerProperty("wifi.supplicant.state", this);
mPropMngr->registerProperty("wifi.scanmode", this);
mPropMngr->registerProperty("wifi.interface", this);
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 @@ out_powerdown:
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 @@ int WifiController::loadFirmware() {
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 @@ WifiNetworkCollection *WifiController::createNetworkList() {
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 @@ void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
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 @@ void WifiController::onConnectedEvent(SupplicantConnectedEvent *evt) {
}
delete ss;
mHandlers->onInterfaceConnected(this, wn->getIfaceCfg());
mHandlers->onInterfaceConnected(this);
}
void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
@ -314,6 +474,10 @@ void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
return;
}
mNumScanResultsSinceLastStateChange++;
if (mNumScanResultsSinceLastStateChange >= 3)
mIsSupplicantSearching = false;
size_t len = 4096;
if (mSupplicant->sendCommand("SCAN_RESULTS", reply, &len)) {
@ -346,10 +510,14 @@ void WifiController::onScanResultsEvent(SupplicantScanResultsEvent *evt) {
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 @@ void WifiController::onStateChangeEvent(SupplicantStateChangeEvent *evt) {
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::onConnectionTimeoutEvent(SupplicantConnectionTimeoutEvent *
}
void WifiController::onDisconnectedEvent(SupplicantDisconnectedEvent *evt) {
mHandlers->onInterfaceDisconnected(this, getBoundInterface());
mCurrentlyConnectedNetworkId = -1;
mHandlers->onInterfaceDisconnected(this);
}
#if 0
@ -411,3 +604,216 @@ void WifiController::onDriverStateEvent(SupplicantEvent *evt) {
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();
}

View File

@ -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;
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);
};
private:
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 @@ public:
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 @@ protected:
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 @@ private:
virtual void onDriverStateEvent(SupplicantEvent *evt);
#endif
void onStatusPollInterval();
int verifyNotSuspended();
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -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 @@ public:
};
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 @@ private:
/*
* 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 @@ public:
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 @@ public:
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 @@ public:
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;

104
nexus/WifiStatusPoller.cpp Normal file
View File

@ -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;
}
}

47
nexus/WifiStatusPoller.h Normal file
View File

@ -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