summaryrefslogtreecommitdiffstats
path: root/nexus
diff options
context:
space:
mode:
authorSan Mehat <san@google.com>2009-05-14 15:00:06 -0700
committerSan Mehat <san@google.com>2009-05-15 10:40:29 -0700
commit5d6d417972f8d946c223c4efb9636b1ba4280543 (patch)
treebbe4637de91895dd9a0283b8dcc3a3d2cf9378b0 /nexus
parentc41d1c8074ed02acc9d1e749d81e0aafb5efbbfa (diff)
downloadsystem_core-5d6d417972f8d946c223c4efb9636b1ba4280543.zip
system_core-5d6d417972f8d946c223c4efb9636b1ba4280543.tar.gz
system_core-5d6d417972f8d946c223c4efb9636b1ba4280543.tar.bz2
nexus: Flesh out VPN support a bit more, cleanup service handling
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'nexus')
-rw-r--r--nexus/CommandListener.cpp79
-rw-r--r--nexus/CommandListener.h14
-rw-r--r--nexus/ErrorCode.h3
-rw-r--r--nexus/OpenVpnController.cpp80
-rw-r--r--nexus/OpenVpnController.h9
-rw-r--r--nexus/Supplicant.cpp117
-rw-r--r--nexus/Supplicant.h5
-rw-r--r--nexus/VpnController.cpp27
-rw-r--r--nexus/VpnController.h10
9 files changed, 183 insertions, 161 deletions
diff --git a/nexus/CommandListener.cpp b/nexus/CommandListener.cpp
index d9ee971..fdf3fed 100644
--- a/nexus/CommandListener.cpp
+++ b/nexus/CommandListener.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <errno.h>
#define LOG_TAG "CommandListener"
@@ -25,6 +28,7 @@
#include "Controller.h"
#include "NetworkManager.h"
#include "WifiController.h"
+#include "VpnController.h"
#include "ErrorCode.h"
CommandListener::CommandListener() :
@@ -40,6 +44,8 @@ CommandListener::CommandListener() :
registerCmd(new WifiGetVarCmd());
registerCmd(new VpnEnableCmd());
+ registerCmd(new VpnSetVarCmd());
+ registerCmd(new VpnGetVarCmd());
registerCmd(new VpnDisableCmd());
}
@@ -261,6 +267,79 @@ int CommandListener::VpnEnableCmd::runCommand(SocketClient *cli, char *data) {
return 0;
}
+CommandListener::VpnSetVarCmd::VpnSetVarCmd() :
+ NexusCommand("vpn_setvar") {
+}
+
+int CommandListener::VpnSetVarCmd::runCommand(SocketClient *cli, char *data) {
+ VpnController *vc = (VpnController *) NetworkManager::Instance()->findController("VPN");
+
+ 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];
+
+ if (!(bword = strtok_r(data, ":", &last)))
+ goto out_inval;
+
+ strncpy(varname, bword, sizeof(varname));
+
+ if (!strcasecmp(varname, "vpn_gateway")) {
+ char buffer[255];
+
+ 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;
+ }
+
+ cli->sendMsg(ErrorCode::CommandOkay, "Variable read.", false);
+ return 0;
+out_inval:
+ errno = EINVAL;
+ cli->sendMsg(ErrorCode::CommandParameterError, "Failed to get variable.", true);
+ return 0;
+}
+
CommandListener::VpnDisableCmd::VpnDisableCmd() :
NexusCommand("vpn_disable") {
}
diff --git a/nexus/CommandListener.h b/nexus/CommandListener.h
index 7bc89e3..a44aa29 100644
--- a/nexus/CommandListener.h
+++ b/nexus/CommandListener.h
@@ -95,6 +95,20 @@ private:
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();
diff --git a/nexus/ErrorCode.h b/nexus/ErrorCode.h
index 8ca6cae..57c99c2 100644
--- a/nexus/ErrorCode.h
+++ b/nexus/ErrorCode.h
@@ -26,6 +26,9 @@ public:
static const int WifiScanResult = 125;
static const int WifiNetworkList = 126;
+ static const int VariableRead = 127;
+ static const int VariableWrite = 128;
+
// 200 series - Requested action has been successfully completed
static const int CommandOkay = 200;
diff --git a/nexus/OpenVpnController.cpp b/nexus/OpenVpnController.cpp
index eff653a..d326ad5 100644
--- a/nexus/OpenVpnController.cpp
+++ b/nexus/OpenVpnController.cpp
@@ -14,17 +14,27 @@
* limitations under the License.
*/
#include <errno.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#define LOG_TAG "OpenVpnController"
#include <cutils/log.h>
#include <cutils/properties.h>
+#include <sysutils/ServiceManager.h>
+
#include "OpenVpnController.h"
#define DAEMON_PROP_NAME "vpn.openvpn.status"
+#define DAEMON_CONFIG_FILE "/data/misc/openvpn/openvpn.conf"
OpenVpnController::OpenVpnController() :
VpnController() {
+ mServiceManager = new ServiceManager();
+}
+
+OpenVpnController::~OpenVpnController() {
+ delete mServiceManager;
}
int OpenVpnController::start() {
@@ -37,68 +47,32 @@ int OpenVpnController::stop() {
int OpenVpnController::enable() {
- // Validate configuration file
-
- // Validate key file
-
- if (startServiceDaemon())
+ if (validateConfig()) {
+ LOGE("Error validating configuration file");
return -1;
+ }
- errno = -ENOSYS;
- return -1;
-}
+ if (mServiceManager->start("openvpn"))
+ return -1;
-int OpenVpnController::startServiceDaemon() {
- char status[PROPERTY_VALUE_MAX];
- int count = 100;
-
- property_set("ctl.start", "openvpn");
- sched_yield();
-
- while (count-- > 0) {
- if (property_get(DAEMON_PROP_NAME, status, NULL)) {
- if (strcmp(status, "ok") == 0)
- return 0;
- else if (strcmp(DAEMON_PROP_NAME, "failed") == 0)
- return -1;
- }
- usleep(200000);
- }
- property_set(DAEMON_PROP_NAME, "timeout");
- return -1;
+ return 0;
}
-int OpenVpnController::stopServiceDaemon() {
- char status[PROPERTY_VALUE_MAX] = {'\0'};
- int count = 50;
-
- if (property_get(DAEMON_PROP_NAME, status, NULL) &&
- !strcmp(status, "stopped")) {
- LOGD("Service already stopped");
- return 0;
- }
+int OpenVpnController::disable() {
- property_set("ctl.stop", "openvpn");
- sched_yield();
+ if (mServiceManager->stop("openvpn"))
+ return -1;
+ return 0;
+}
- while (count-- > 0) {
- if (property_get(DAEMON_PROP_NAME, status, NULL)) {
- if (!strcmp(status, "stopped"))
- break;
- }
- usleep(100000);
- }
+int OpenVpnController::validateConfig() {
+ unlink(DAEMON_CONFIG_FILE);
- if (!count) {
- LOGD("Timed out waiting for openvpn to stop");
- errno = ETIMEDOUT;
+ FILE *fp = fopen(DAEMON_CONFIG_FILE, "w");
+ if (!fp)
return -1;
- }
+ fprintf(fp, "remote %s 1194\n", inet_ntoa(getVpnGateway()));
+ fclose(fp);
return 0;
}
-
-int OpenVpnController::disable() {
- errno = -ENOSYS;
- return -1;
-}
diff --git a/nexus/OpenVpnController.h b/nexus/OpenVpnController.h
index 1ecc3fb..7bcc098 100644
--- a/nexus/OpenVpnController.h
+++ b/nexus/OpenVpnController.h
@@ -19,11 +19,15 @@
#include "VpnController.h"
+class ServiceManager;
+
class OpenVpnController : public VpnController {
+private:
+ ServiceManager *mServiceManager;
public:
OpenVpnController();
- virtual ~OpenVpnController() {}
+ virtual ~OpenVpnController();
int start();
int stop();
@@ -33,8 +37,7 @@ public:
protected:
private:
- int startServiceDaemon();
- int stopServiceDaemon();
+ int validateConfig();
};
#endif
diff --git a/nexus/Supplicant.cpp b/nexus/Supplicant.cpp
index 22964bb..6737d91 100644
--- a/nexus/Supplicant.cpp
+++ b/nexus/Supplicant.cpp
@@ -25,12 +25,7 @@
#include "private/android_filesystem_config.h"
-#undef HAVE_LIBC_SYSTEM_PROPERTIES
-
-#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
-#endif
+#include <sysutils/ServiceManager.h>
#include "Supplicant.h"
#include "SupplicantListener.h"
@@ -44,12 +39,10 @@
#define IFACE_DIR "/data/system/wpa_supplicant"
#define DRIVER_PROP_NAME "wlan.driver.status"
-#define SUPPLICANT_NAME "wpa_supplicant"
-#define SUPP_PROP_NAME "init.svc.wpa_supplicant"
+#define SUPPLICANT_SERVICE_NAME "wpa_supplicant"
#define SUPP_CONFIG_TEMPLATE "/system/etc/wifi/wpa_supplicant.conf"
#define SUPP_CONFIG_FILE "/data/misc/wifi/wpa_supplicant.conf"
-
Supplicant::Supplicant() {
mCtrl = NULL;
mMonitor = NULL;
@@ -57,62 +50,25 @@ Supplicant::Supplicant() {
mState = SupplicantState::UNKNOWN;
- mLatestScanResults = new ScanResultCollection();
+ mServiceManager = new ServiceManager();
+ mLatestScanResults = new ScanResultCollection();
pthread_mutex_init(&mLatestScanResultsLock, NULL);
}
+Supplicant::~Supplicant() {
+ delete mServiceManager;
+}
+
int Supplicant::start() {
if (setupConfig()) {
LOGW("Unable to setup supplicant.conf");
}
-
- char status[PROPERTY_VALUE_MAX] = {'\0'};
- int count = 200;
-#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
- const prop_info *pi;
- unsigned int serial = 0;
-#endif
-
- if (property_get(SUPP_PROP_NAME, status, NULL) &&
- !strcmp(status, "running")) {
- } else {
-#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
- pi = __system_property_find(SUPP_PROP_NAME);
- if (pi != NULL)
- serial = pi->serial;
-#endif
-
- LOGD("Starting Supplicant");
- property_set("ctl.start", SUPPLICANT_NAME);
- sched_yield();
- while (count--) {
-#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
- if (!pi)
- pi = __system_property_find(SUPP_PROP_NAME);
- if (pi) {
- __system_property_read(pi, NULL, status);
- if (strcmp(status, "running") == 0)
- break;
- else if (pi->serial != serial &&
- strcmp(status, "stopped") == 0) {
- errno = EIO;
- return -1;
- }
- }
-#else
- if (property_get(SUPP_PROP_NAME, status, NULL)) {
- if (!strcmp(status, "running"))
- break;
- }
-#endif
- usleep(100000);
- }
- if (!count) {
- errno = ETIMEDOUT;
- return -1;
- }
+
+ if (mServiceManager->start(SUPPLICANT_SERVICE_NAME)) {
+ LOGE("Error starting supplicant (%s)", strerror(errno));
+ return -1;
}
wpa_ctrl_cleanup();
@@ -125,30 +81,13 @@ int Supplicant::start() {
int Supplicant::stop() {
- char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
- int count = 50;
-
if (mListener->stopListener()) {
LOGW("Unable to stop supplicant listener (%s)", strerror(errno));
return -1;
}
- if (property_get(SUPP_PROP_NAME, supp_status, NULL)
- && strcmp(supp_status, "stopped") == 0) {
- LOGD("Supplicant already stopped");
- return 0;
- }
-
- LOGD("Stopping Supplicant");
- property_set("ctl.stop", SUPPLICANT_NAME);
- sched_yield();
-
- while (count-- > 0) {
- if (property_get(SUPP_PROP_NAME, supp_status, NULL)) {
- if (strcmp(supp_status, "stopped") == 0)
- break;
- }
- usleep(100000);
+ if (mServiceManager->stop(SUPPLICANT_SERVICE_NAME)) {
+ LOGW("Error stopping supplicant (%s)", strerror(errno));
}
if (mCtrl) {
@@ -160,35 +99,15 @@ int Supplicant::stop() {
mMonitor = NULL;
}
- if (!count) {
- LOGD("Timed out waiting for supplicant to stop");
- errno = ETIMEDOUT;
- return -1;
- }
-
- LOGD("Supplicant shutdown");
-
return 0;
}
bool Supplicant::isStarted() {
- char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
-
- property_get(SUPP_PROP_NAME, supp_status, NULL);
-
- if (!strcmp(supp_status, "running"))
- return true;
-
- return false;
+ return mServiceManager->isRunning(SUPPLICANT_SERVICE_NAME);
}
int Supplicant::connectToSupplicant() {
- char ifname[256];
- char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
-
- LOGD("connectToSupplicant()");
- if (!property_get(SUPP_PROP_NAME, supp_status, NULL)
- || strcmp(supp_status, "running") != 0) {
+ if (!isStarted()) {
LOGE("Supplicant not running, cannot connect");
return -1;
}
@@ -229,7 +148,7 @@ int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len)
return -1;
}
- LOGD("sendCommand(): -> '%s'", cmd);
+// LOGD("sendCommand(): -> '%s'", cmd);
int rc;
if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) {
@@ -245,7 +164,7 @@ int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len)
!strncmp(cmd, "SCAN_RESULTS", 12))
reply[*reply_len] = '\0';
- LOGD("sendCommand(): <- '%s'", reply);
+// LOGD("sendCommand(): <- '%s'", reply);
return 0;
}
diff --git a/nexus/Supplicant.h b/nexus/Supplicant.h
index 4a7ec3a..2ea0892 100644
--- a/nexus/Supplicant.h
+++ b/nexus/Supplicant.h
@@ -19,6 +19,7 @@
struct wpa_ctrl;
class SupplicantListener;
class SupplicantEvent;
+class ServiceManager;
#include <pthread.h>
@@ -31,13 +32,14 @@ private:
struct wpa_ctrl *mMonitor;
SupplicantListener *mListener;
int mState;
+ ServiceManager *mServiceManager;
ScanResultCollection *mLatestScanResults;
pthread_mutex_t mLatestScanResultsLock;
public:
Supplicant();
- virtual ~Supplicant() {}
+ virtual ~Supplicant();
int start();
int stop();
@@ -50,7 +52,6 @@ public:
int removeNetwork(int networkId);
WifiNetworkCollection *createNetworkList();
-
int getState() { return mState; }
diff --git a/nexus/VpnController.cpp b/nexus/VpnController.cpp
index 17bfe41..cd24c19 100644
--- a/nexus/VpnController.cpp
+++ b/nexus/VpnController.cpp
@@ -13,7 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#include <string.h>
#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
#include "VpnController.h"
VpnController::VpnController() :
@@ -21,21 +27,34 @@ VpnController::VpnController() :
}
int VpnController::start() {
- errno = -ENOSYS;
+ errno = ENOSYS;
return -1;
}
int VpnController::stop() {
- errno = -ENOSYS;
+ errno = ENOSYS;
return -1;
}
int VpnController::enable() {
- errno = -ENOSYS;
+ errno = ENOSYS;
return -1;
}
int VpnController::disable() {
- errno = -ENOSYS;
+ errno = ENOSYS;
return -1;
}
+
+int VpnController::setVpnGateway(const char *vpnGw) {
+ if (!inet_aton(vpnGw, &mVpnGateway)) {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+int VpnController::setVpnGateway(struct in_addr *vpnGw) {
+ memcpy(&mVpnGateway, vpnGw, sizeof(struct in_addr));
+ return 0;
+}
diff --git a/nexus/VpnController.h b/nexus/VpnController.h
index 049fe6e..4088e6a 100644
--- a/nexus/VpnController.h
+++ b/nexus/VpnController.h
@@ -16,9 +16,15 @@
#ifndef _VPN_CONTROLLER_H
#define _VPN_CONTROLLER_H
+#include <netinet/in.h>
+
#include "Controller.h"
class VpnController : public Controller {
+ /*
+ * Gateway of the VPN server to connect to
+ */
+ struct in_addr mVpnGateway;
public:
VpnController();
@@ -30,6 +36,10 @@ public:
virtual int enable();
virtual int disable();
+ struct in_addr &getVpnGateway() { return mVpnGateway; }
+ int setVpnGateway(const char *vpnGw);
+ int setVpnGateway(struct in_addr *vpnGw);
+
protected:
};