nexus: Switch controllers to use abstracted properties and refactor command protocol

Also fixes a select() bug and removes debugging

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

nexus: fix whitespace
This commit is contained in:
San Mehat 2009-05-20 15:28:43 -07:00
parent 463de48fb0
commit 4876567cb9
16 changed files with 306 additions and 281 deletions

View file

@ -33,54 +33,19 @@
CommandListener::CommandListener() :
FrameworkListener("nexus") {
registerCmd(new WifiEnableCmd());
registerCmd(new WifiDisableCmd());
registerCmd(new WifiScanCmd());
registerCmd(new WifiScanResultsCmd());
registerCmd(new WifiListNetworksCmd());
registerCmd(new WifiAddNetworkCmd());
registerCmd(new WifiRemoveNetworkCmd());
registerCmd(new WifiSetVarCmd());
registerCmd(new WifiGetVarCmd());
registerCmd(new VpnEnableCmd());
registerCmd(new VpnSetVarCmd());
registerCmd(new VpnGetVarCmd());
registerCmd(new VpnDisableCmd());
registerCmd(new GetCmd());
registerCmd(new SetCmd());
}
/* -------------
* Wifi Commands
* ------------ */
CommandListener::WifiEnableCmd::WifiEnableCmd() :
NexusCommand("wifi_enable") {
}
int CommandListener::WifiEnableCmd::runCommand(SocketClient *cli, char *data) {
Controller *c = NetworkManager::Instance()->findController("WIFI");
if (c->enable())
cli->sendMsg(ErrorCode::OperationFailed, "Failed to enable wifi", true);
else
cli->sendMsg(ErrorCode::CommandOkay, "Wifi Enabled", false);
return 0;
}
CommandListener::WifiDisableCmd::WifiDisableCmd() :
NexusCommand("wifi_disable") {
}
int CommandListener::WifiDisableCmd::runCommand(SocketClient *cli, char *data) {
Controller *c = NetworkManager::Instance()->findController("WIFI");
if (c->disable())
cli->sendMsg(ErrorCode::OperationFailed, "Failed to disable wifi", true);
else
cli->sendMsg(ErrorCode::CommandOkay, "Wifi Disabled", false);
return 0;
}
CommandListener::WifiAddNetworkCmd::WifiAddNetworkCmd() :
NexusCommand("wifi_add_network") {
}
@ -116,21 +81,6 @@ int CommandListener::WifiRemoveNetworkCmd::runCommand(SocketClient *cli, char *d
return 0;
}
CommandListener::WifiScanCmd::WifiScanCmd() :
NexusCommand("wifi_scan") {
}
int CommandListener::WifiScanCmd::runCommand(SocketClient *cli, char *data) {
WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI");
if (wc->setScanMode(atoi(data)))
cli->sendMsg(ErrorCode::OperationFailed, "Failed to set scan mode", true);
else
cli->sendMsg(ErrorCode::CommandOkay, "Scan mode set", false);
return 0;
}
CommandListener::WifiScanResultsCmd::WifiScanResultsCmd() :
NexusCommand("wifi_scan_results") {
}
@ -181,158 +131,39 @@ int CommandListener::WifiListNetworksCmd::runCommand(SocketClient *cli, char *da
return 0;
}
CommandListener::WifiSetVarCmd::WifiSetVarCmd() :
NexusCommand("wifi_setvar") {
}
int CommandListener::WifiSetVarCmd::runCommand(SocketClient *cli, char *data) {
WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI");
char *bword;
char *last;
char varname[32];
char val[250];
int networkId;
if (!(bword = strtok_r(data, ":", &last)))
goto out_inval;
networkId = atoi(bword);
if (!(bword = strtok_r(NULL, ":", &last)))
goto out_inval;
strncpy(varname, bword, sizeof(varname));
if (!(bword = strtok_r(NULL, ":", &last)))
goto out_inval;
strncpy(val, bword, sizeof(val));
LOGD("Network id %d, varname '%s', value '%s'", networkId, varname, val);
return 0;
out_inval:
errno = EINVAL;
cli->sendMsg(ErrorCode::CommandParameterError, "Failed to set variable.", true);
return 0;
}
CommandListener::WifiGetVarCmd::WifiGetVarCmd() :
NexusCommand("wifi_getvar") {
}
int CommandListener::WifiGetVarCmd::runCommand(SocketClient *cli, char *data) {
WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI");
char *bword;
char *last;
char varname[32];
int networkId;
if (!(bword = strtok_r(data, ":", &last)))
goto out_inval;
networkId = atoi(bword);
if (!(bword = strtok_r(NULL, ":", &last)))
goto out_inval;
strncpy(varname, bword, sizeof(varname));
LOGD("networkId = %d, varname '%s'", networkId, varname);
return 0;
out_inval:
errno = EINVAL;
cli->sendMsg(ErrorCode::CommandParameterError, "Failed to get variable.", true);
return 0;
}
/* ------------
* Vpn Commands
* ------------ */
CommandListener::VpnEnableCmd::VpnEnableCmd() :
NexusCommand("vpn_enable") {
}
int CommandListener::VpnEnableCmd::runCommand(SocketClient *cli, char *data) {
Controller *c = NetworkManager::Instance()->findController("VPN");
if (c->enable())
cli->sendMsg(ErrorCode::OperationFailed, "Failed to enable VPN", true);
else
cli->sendMsg(ErrorCode::CommandOkay, "VPN enabled", false);
return 0;
}
CommandListener::VpnSetVarCmd::VpnSetVarCmd() :
NexusCommand("vpn_setvar") {
/* ----------------
* Generic Commands
* ---------------- */
CommandListener::GetCmd::GetCmd() :
NexusCommand("get") {
}
int CommandListener::VpnSetVarCmd::runCommand(SocketClient *cli, char *data) {
VpnController *vc = (VpnController *) NetworkManager::Instance()->findController("VPN");
int CommandListener::GetCmd::runCommand(SocketClient *cli, char *data) {
char *bword;
char *last;
char varname[32];
char val[250];
if (!(bword = strtok_r(data, ":", &last)))
goto out_inval;
strncpy(varname, bword, sizeof(varname));
if (!(bword = strtok_r(NULL, ":", &last)))
goto out_inval;
strncpy(val, bword, sizeof(val));
if (!strcasecmp(varname, "vpn_gateway")) {
if (vc->setVpnGateway(val))
goto out_inval;
} else {
cli->sendMsg(ErrorCode::CommandParameterError, "Variable not found.", true);
return 0;
}
cli->sendMsg(ErrorCode::CommandOkay, "Variable written.", false);
return 0;
out_inval:
errno = EINVAL;
cli->sendMsg(ErrorCode::CommandParameterError, "Failed to set variable.", true);
return 0;
}
CommandListener::VpnGetVarCmd::VpnGetVarCmd() :
NexusCommand("vpn_getvar") {
}
int CommandListener::VpnGetVarCmd::runCommand(SocketClient *cli, char *data) {
VpnController *vc = (VpnController *) NetworkManager::Instance()->findController("VPN");
char *bword;
char *last;
char varname[32];
char propname[32];
if (!(bword = strtok_r(data, ":", &last)))
goto out_inval;
strncpy(varname, bword, sizeof(varname));
strncpy(propname, bword, sizeof(propname));
if (!strcasecmp(varname, "vpn_gateway")) {
char buffer[255];
char pb[255];
snprintf(pb, sizeof(pb), "%s:", propname);
sprintf(buffer, "%s:%s", varname, inet_ntoa(vc->getVpnGateway()));
cli->sendMsg(ErrorCode::VariableRead, buffer, false);
} else {
cli->sendMsg(ErrorCode::CommandParameterError, "Variable not found.", true);
return 0;
if (!NetworkManager::Instance()->getProperty(propname,
&pb[strlen(pb)],
sizeof(pb) - strlen(pb))) {
goto out_inval;
}
cli->sendMsg(ErrorCode::CommandOkay, "Variable read.", false);
cli->sendMsg(ErrorCode::VariableRead, pb, false);
cli->sendMsg(ErrorCode::CommandOkay, "Property read.", false);
return 0;
out_inval:
errno = EINVAL;
@ -340,16 +171,34 @@ out_inval:
return 0;
}
CommandListener::VpnDisableCmd::VpnDisableCmd() :
NexusCommand("vpn_disable") {
}
int CommandListener::VpnDisableCmd::runCommand(SocketClient *cli, char *data) {
Controller *c = NetworkManager::Instance()->findController("VPN");
CommandListener::SetCmd::SetCmd() :
NexusCommand("set") {
}
if (c->disable())
cli->sendMsg(ErrorCode::OperationFailed, "Failed to disable VPN", true);
else
cli->sendMsg(ErrorCode::CommandOkay, "VPN disabled", false);
int CommandListener::SetCmd::runCommand(SocketClient *cli, char *data) {
char *bword;
char *last;
char propname[32];
char propval[250];
if (!(bword = strtok_r(data, ":", &last)))
goto out_inval;
strncpy(propname, bword, sizeof(propname));
if (!(bword = strtok_r(NULL, ":", &last)))
goto out_inval;
strncpy(propval, bword, sizeof(propval));
if (NetworkManager::Instance()->setProperty(propname, propval))
goto out_inval;
cli->sendMsg(ErrorCode::CommandOkay, "Property set.", false);
return 0;
out_inval:
errno = EINVAL;
cli->sendMsg(ErrorCode::CommandParameterError, "Failed to set property.", true);
return 0;
}

View file

@ -25,19 +25,6 @@ public:
virtual ~CommandListener() {}
private:
class WifiEnableCmd : public NexusCommand {
public:
WifiEnableCmd();
virtual ~WifiEnableCmd() {}
int runCommand(SocketClient *c, char *data);
};
class WifiDisableCmd : public NexusCommand {
public:
WifiDisableCmd();
virtual ~WifiDisableCmd() {}
int runCommand(SocketClient *c, char *data);
};
class WifiScanCmd : public NexusCommand {
public:
@ -74,48 +61,19 @@ private:
int runCommand(SocketClient *c, char *data);
};
class WifiSetVarCmd : public NexusCommand {
class SetCmd : public NexusCommand {
public:
WifiSetVarCmd();
virtual ~WifiSetVarCmd() {}
SetCmd();
virtual ~SetCmd() {}
int runCommand(SocketClient *c, char *data);
};
class WifiGetVarCmd : public NexusCommand {
class GetCmd : public NexusCommand {
public:
WifiGetVarCmd();
virtual ~WifiGetVarCmd() {}
GetCmd();
virtual ~GetCmd() {}
int runCommand(SocketClient *c, char *data);
};
class VpnEnableCmd : public NexusCommand {
public:
VpnEnableCmd();
virtual ~VpnEnableCmd() {}
int runCommand(SocketClient *c, char *data);
};
class VpnSetVarCmd : public NexusCommand {
public:
VpnSetVarCmd();
virtual ~VpnSetVarCmd() {}
int runCommand(SocketClient *c, char *data);
};
class VpnGetVarCmd : public NexusCommand {
public:
VpnGetVarCmd();
virtual ~VpnGetVarCmd() {}
int runCommand(SocketClient *c, char *data);
};
class VpnDisableCmd : public NexusCommand {
public:
VpnDisableCmd();
virtual ~VpnDisableCmd() {}
int runCommand(SocketClient *c, char *data);
};
};
#endif

View file

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
@ -32,8 +33,13 @@
extern "C" int init_module(void *, unsigned int, const char *);
extern "C" int delete_module(const char *, unsigned int);
Controller::Controller(const char *name) {
Controller::Controller(const char *name, const char *prefix) {
mName = name;
mPropertyPrefix = prefix;
mProperties = new PropertyCollection();
mEnabled = false;
registerProperty("enable");
}
int Controller::start() {
@ -44,12 +50,69 @@ int Controller::stop() {
return 0;
}
const PropertyCollection & Controller::getProperties() {
return *mProperties;
}
int Controller::setProperty(const char *name, char *value) {
if (!strcmp(name, "enable")) {
int en = atoi(value);
int rc;
rc = (en ? enable() : disable());
if (!rc)
mEnabled = en;
return rc;
}
errno = ENOENT;
return -1;
}
const char *Controller::getProperty(const char *name, char *buffer, size_t maxsize) {
if (!strcmp(name, "enable")) {
snprintf(buffer, maxsize, "%d", mEnabled);
return buffer;
}
errno = ENOENT;
return NULL;
}
int Controller::registerProperty(const char *name) {
PropertyCollection::iterator it;
for (it = mProperties->begin(); it != mProperties->end(); ++it) {
if (!strcmp(name, (*it))) {
errno = EADDRINUSE;
LOGE("Failed to register property (%s)", strerror(errno));
return -1;
}
}
mProperties->push_back(name);
return 0;
}
int Controller::unregisterProperty(const char *name) {
PropertyCollection::iterator it;
for (it = mProperties->begin(); it != mProperties->end(); ++it) {
if (!strcmp(name, (*it))) {
mProperties->erase(it);
return 0;
}
}
errno = ENOENT;
return -1;
}
int Controller::loadKernelModule(char *modpath, const char *args) {
void *module;
unsigned int size;
LOGD("loadKernelModule(%s, %s)", modpath, args);
module = loadFile(modpath, &size);
if (!module) {
errno = -EIO;
@ -65,7 +128,6 @@ int Controller::unloadKernelModule(const char *modtag) {
int rc = -1;
int retries = 10;
LOGD("unloadKernelModule(%s)", modtag);
while (retries--) {
rc = delete_module(modtag, O_NONBLOCK | O_EXCL);
if (rc < 0 && errno == EAGAIN)
@ -107,7 +169,6 @@ bool Controller::isKernelModuleLoaded(const char *modtag) {
return false;
}
void *Controller::loadFile(char *filename, unsigned int *_size)
{
int ret, fd;

View file

@ -16,31 +16,48 @@
#ifndef _CONTROLLER_H
#define _CONTROLLER_H
#include <unistd.h>
#include <sys/types.h>
#include "../../../frameworks/base/include/utils/List.h"
#include "PropertyCollection.h"
class Controller {
private:
const char *mName;
const char *mPropertyPrefix;
PropertyCollection *mProperties;
bool mEnabled;
public:
Controller(const char *name);
Controller(const char *name, const char *prefix);
virtual ~Controller() {}
virtual int start();
virtual int stop();
virtual int enable() = 0;
virtual int disable() = 0;
virtual const PropertyCollection &getProperties();
virtual int setProperty(const char *name, char *value);
virtual const char *getProperty(const char *name, char *buffer, size_t maxsize);
virtual const char *getName() { return mName; }
const char *getName() { return mName; }
const char *getPropertyPrefix() { return mPropertyPrefix; }
protected:
int loadKernelModule(char *modpath, const char *args);
bool isKernelModuleLoaded(const char *modtag);
int unloadKernelModule(const char *modtag);
int registerProperty(const char *name);
int unregisterProperty(const char *name);
private:
void *loadFile(char *filename, unsigned int *_size);
virtual int enable() = 0;
virtual int disable() = 0;
};
typedef android::List<Controller *> ControllerCollection;

View file

@ -18,7 +18,7 @@
#include "LoopController.h"
LoopController::LoopController() :
Controller("LOOP") {
Controller("LOOP", "loop") {
}
int LoopController::enable() {

View file

@ -23,6 +23,7 @@ public:
LoopController();
virtual ~LoopController() {}
private:
int enable();
int disable();
};

View file

@ -83,6 +83,73 @@ Controller *NetworkManager::findController(const char *name) {
return NULL;
}
int NetworkManager::setProperty(const char *name, char *value) {
char *tmp = strdup(name);
char *next = tmp;
char *prefix;
char *rest;
ControllerCollection::iterator it;
if (!(prefix = strsep(&next, ".")))
goto out_inval;
rest = next;
if (!strncasecmp(prefix, "netman", 6)) {
errno = ENOSYS;
return -1;
}
for (it = mControllers->begin(); it != mControllers->end(); ++it) {
if (!strcasecmp(prefix, (*it)->getPropertyPrefix())) {
return (*it)->setProperty(rest, value);
}
}
errno = ENOENT;
return -1;
out_inval:
errno = EINVAL;
return -1;
}
const char *NetworkManager::getProperty(const char *name, char *buffer,
size_t maxsize) {
char *tmp = strdup(name);
char *next = tmp;
char *prefix;
char *rest;
ControllerCollection::iterator it;
if (!(prefix = strsep(&next, ".")))
goto out_inval;
rest = next;
if (!strncasecmp(prefix, "netman", 6)) {
errno = ENOSYS;
return NULL;
}
for (it = mControllers->begin(); it != mControllers->end(); ++it) {
if (!strcasecmp(prefix, (*it)->getPropertyPrefix())) {
return (*it)->getProperty(rest, buffer, maxsize);
}
}
errno = ENOENT;
return NULL;
out_inval:
errno = EINVAL;
return NULL;
}
const PropertyCollection &NetworkManager::getProperties() {
return *mProperties;
}
int NetworkManager::onInterfaceCreated(Controller *c, char *name) {
LOGD("Interface %s created by controller %s", name, c->getName());
return 0;

View file

@ -19,6 +19,7 @@
#include <sysutils/SocketListener.h>
#include "Controller.h"
#include "PropertyCollection.h"
class NetworkManager {
private:
@ -27,6 +28,7 @@ private:
private:
ControllerCollection *mControllers;
SocketListener *mBroadcaster;
PropertyCollection *mProperties;
public:
virtual ~NetworkManager() {}
@ -37,6 +39,10 @@ public:
Controller *findController(const char *name);
const PropertyCollection &getProperties();
int setProperty(const char *name, char *value);
const char *getProperty(const char *name, char *buffer, size_t maxsize);
void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
SocketListener *getBroadcaster() { return mBroadcaster; }
@ -45,6 +51,9 @@ public:
private:
int startControllers();
int stopControllers();
int registerProperty(const char *name);
int unregisterProperty(const char *name);
NetworkManager();
public:

View file

@ -63,7 +63,6 @@ int OpenVpnController::enable() {
}
int OpenVpnController::disable() {
if (mServiceManager->stop("openvpn"))
return -1;
return 0;

View file

@ -31,6 +31,8 @@ public:
int start();
int stop();
private:
int enable();
int disable();
};

View file

@ -0,0 +1,25 @@
/*
* 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 _PROPERTY_COLLECTION_H
#define _PROPERTY_COLLECTION_H
#include "../../../frameworks/base/include/utils/List.h"
typedef android::List<const char *> PropertyCollection;
#endif

View file

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
@ -23,7 +24,8 @@
#include "VpnController.h"
VpnController::VpnController() :
Controller("VPN") {
Controller("VPN", "vpn") {
registerProperty("gateway");
}
int VpnController::start() {
@ -46,15 +48,23 @@ int VpnController::disable() {
return -1;
}
int VpnController::setVpnGateway(const char *vpnGw) {
if (!inet_aton(vpnGw, &mVpnGateway)) {
errno = EINVAL;
return -1;
}
return 0;
int VpnController::setProperty(const char *name, char *value) {
if (!strcmp(name, "gateway")) {
if (!inet_aton(value, &mVpnGateway)) {
errno = EINVAL;
return -1;
}
return 0;
}
return Controller::setProperty(name, value);
}
int VpnController::setVpnGateway(struct in_addr *vpnGw) {
memcpy(&mVpnGateway, vpnGw, sizeof(struct in_addr));
return 0;
const char *VpnController::getProperty(const char *name, char *buffer, size_t maxsize) {
if (!strcmp(name, "gateway")) {
snprintf(buffer, maxsize, "%s", inet_ntoa(mVpnGateway));
return buffer;
}
return Controller::getProperty(name, buffer, maxsize);
}

View file

@ -33,14 +33,14 @@ public:
virtual int start();
virtual int stop();
virtual int setProperty(const char *name, char *value);
virtual const char *getProperty(const char *name, char *buffer,
size_t maxlen);
private:
virtual int enable();
virtual int disable();
struct in_addr &getVpnGateway() { return mVpnGateway; }
int setVpnGateway(const char *vpnGw);
int setVpnGateway(struct in_addr *vpnGw);
protected:
};
#endif

View file

@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@ -26,7 +28,7 @@
#include "ErrorCode.h"
WifiController::WifiController(char *modpath, char *modname, char *modargs) :
Controller("WIFI") {
Controller("WIFI", "wifi") {
strncpy(mModulePath, modpath, sizeof(mModulePath));
strncpy(mModuleName, modname, sizeof(mModuleName));
strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
@ -34,6 +36,8 @@ WifiController::WifiController(char *modpath, char *modname, char *modargs) :
mSupplicant = new Supplicant();
mScanner = new WifiScanner(mSupplicant, 10);
mCurrentScanMode = 0;
registerProperty("scanmode");
}
int WifiController::start() {
@ -94,7 +98,7 @@ out_powerdown:
return -1;
}
void WifiController::sendStatusBroadcast(char *msg) {
void WifiController::sendStatusBroadcast(const char *msg) {
NetworkManager::Instance()->
getBroadcaster()->
sendBroadcast(ErrorCode::UnsolicitedInformational, msg, false);
@ -167,3 +171,20 @@ ScanResultCollection *WifiController::createScanResults() {
WifiNetworkCollection *WifiController::createNetworkList() {
return mSupplicant->createNetworkList();
}
int WifiController::setProperty(const char *name, char *value) {
if (!strcmp(name, "scanmode"))
return setScanMode((uint32_t) strtoul(value, NULL, 0));
return Controller::setProperty(name, value);
}
const char *WifiController::getProperty(const char *name, char *buffer, size_t maxsize) {
if (!strcmp(name, "scanmode")) {
snprintf(buffer, maxsize, "0x%.8x", mCurrentScanMode);
return buffer;
}
return Controller::getProperty(name, buffer, maxsize);
}

View file

@ -54,15 +54,14 @@ public:
int start();
int stop();
int enable();
int disable();
int addNetwork();
int removeNetwork(int networkId);
WifiNetworkCollection *createNetworkList();
int getScanMode() { return mCurrentScanMode; }
int setScanMode(uint32_t mode);
virtual int setProperty(const char *name, char *value);
virtual const char *getProperty(const char *name, char *buffer,
size_t maxlen);
ScanResultCollection *createScanResults();
char *getModulePath() { return mModulePath; }
@ -79,7 +78,13 @@ protected:
virtual bool isFirmwareLoaded() = 0;
virtual bool isPoweredUp() = 0;
void sendStatusBroadcast(char *msg);
void sendStatusBroadcast(const char *msg);
private:
int setScanMode(uint32_t mode);
int enable();
int disable();
};
#endif

View file

@ -65,7 +65,7 @@ void WifiScanner::run() {
struct timeval to;
int rc = 0;
to.tv_sec = 0;
to.tv_usec = 0;
to.tv_sec = mPeriod;
FD_ZERO(&read_fds);
@ -83,4 +83,5 @@ void WifiScanner::run() {
} else if (FD_ISSET(mCtrlPipe[0], &read_fds))
break;
} // while
LOGD("Stopping wifi scanner");
}