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:
parent
a0c0d8a89e
commit
c4a895b709
|
@ -33,7 +33,7 @@ public:
|
|||
SocketListener(const char *socketNames, bool listen);
|
||||
SocketListener(int socketFd, bool listen);
|
||||
|
||||
virtual ~SocketListener() {}
|
||||
virtual ~SocketListener();
|
||||
int startListener();
|
||||
int stopListener();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
118
nexus/Property.h
118
nexus/Property.h
|
@ -14,8 +14,124 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _PROPERTY_H
|
||||
#define _PROPERTY_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <utils/List.h>
|
||||
|
||||
class Property {
|
||||
const char *mName;
|
||||
bool mReadOnly;
|
||||
int mType;
|
||||
int mNumElements;
|
||||
|
||||
public:
|
||||
static const int NameMaxSize = 128;
|
||||
static const int NameMaxSize = 128;
|
||||
static const int ValueMaxSize = 255;
|
||||
|
||||
static const int Type_STRING = 1;
|
||||
static const int Type_INTEGER = 2;
|
||||
static const int Type_IPV4 = 3;
|
||||
|
||||
Property(const char *name, bool ro, int type, int elements);
|
||||
virtual ~Property() {}
|
||||
|
||||
virtual int set(int idx, const char *value) = 0;
|
||||
virtual int set(int idx, int value) = 0;
|
||||
virtual int set(int idx, struct in_addr *value) = 0;
|
||||
|
||||
virtual int get(int idx, char *buffer, size_t max) = 0;
|
||||
virtual int get(int idx, int *buffer) = 0;
|
||||
virtual int get(int idx, struct in_addr *buffer) = 0;
|
||||
|
||||
int getType() { return mType; }
|
||||
bool getReadOnly() { return mReadOnly; }
|
||||
int getNumElements() { return mNumElements; }
|
||||
const char *getName() { return mName; }
|
||||
};
|
||||
|
||||
class StringProperty : public Property {
|
||||
public:
|
||||
StringProperty(const char *name, bool ro, int elements);
|
||||
virtual ~StringProperty() {}
|
||||
|
||||
virtual int set(int idx, const char *value) = 0;
|
||||
int set(int idx, int value);
|
||||
int set(int idx, struct in_addr *value);
|
||||
|
||||
virtual int get(int idx, char *buffer, size_t max) = 0;
|
||||
int get(int idx, int *buffer);
|
||||
int get(int idx, struct in_addr *buffer);
|
||||
};
|
||||
|
||||
class StringPropertyHelper : public StringProperty {
|
||||
char *mBuffer;
|
||||
size_t mMax;
|
||||
public:
|
||||
StringPropertyHelper(const char *name, bool ro,
|
||||
char *buffer, size_t max);
|
||||
int set(int idx, const char *value);
|
||||
int get(int idx, char *buffer, size_t max);
|
||||
};
|
||||
|
||||
class IntegerProperty : public Property {
|
||||
public:
|
||||
IntegerProperty(const char *name, bool ro, int elements);
|
||||
virtual ~IntegerProperty() {}
|
||||
|
||||
int set(int idx, const char *value);
|
||||
virtual int set(int idx, int value) = 0;
|
||||
int set(int idx, struct in_addr *value);
|
||||
|
||||
int get(int idx, char *buffer, size_t max);
|
||||
virtual int get(int idx, int *buffer) = 0;
|
||||
int get(int idx, struct in_addr *buffer);
|
||||
};
|
||||
|
||||
class IntegerPropertyHelper : public IntegerProperty {
|
||||
int *mBuffer;
|
||||
public:
|
||||
IntegerPropertyHelper(const char *name, bool ro, int *buffer);
|
||||
int set(int idx, int value);
|
||||
int get(int idx, int *buffer);
|
||||
};
|
||||
|
||||
class IPV4AddressProperty : public Property {
|
||||
public:
|
||||
IPV4AddressProperty(const char *name, bool ro, int elements);
|
||||
virtual ~IPV4AddressProperty() {}
|
||||
|
||||
int set(int idx, const char *value);
|
||||
int set(int idx, int value);
|
||||
virtual int set(int idx, struct in_addr *value) = 0;
|
||||
|
||||
int get(int idx, char *buffer, size_t max);
|
||||
int get(int idx, int *buffer);
|
||||
virtual int get(int idx, struct in_addr *buffer) = 0;
|
||||
};
|
||||
|
||||
class IPV4AddressPropertyHelper : public IPV4AddressProperty {
|
||||
struct in_addr *mBuffer;
|
||||
public:
|
||||
IPV4AddressPropertyHelper(const char *name, bool ro, struct in_addr *buf);
|
||||
int set(int idx, struct in_addr *value);
|
||||
int get(int idx, struct in_addr *buffer);
|
||||
};
|
||||
|
||||
typedef android::List<Property *> PropertyCollection;
|
||||
|
||||
class PropertyNamespace {
|
||||
char *mName;
|
||||
PropertyCollection *mProperties;
|
||||
|
||||
public:
|
||||
PropertyNamespace(const char *name);
|
||||
virtual ~PropertyNamespace();
|
||||
|
||||
const char *getName() { return mName; }
|
||||
PropertyCollection *getProperties() { return mProperties; }
|
||||
};
|
||||
|
||||
typedef android::List<PropertyNamespace *> PropertyNamespaceCollection;
|
||||
#endif
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue