summaryrefslogtreecommitdiffstats
path: root/nexus/Supplicant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'nexus/Supplicant.cpp')
-rw-r--r--nexus/Supplicant.cpp232
1 files changed, 199 insertions, 33 deletions
diff --git a/nexus/Supplicant.cpp b/nexus/Supplicant.cpp
index 6737d91..e69f2c0 100644
--- a/nexus/Supplicant.cpp
+++ b/nexus/Supplicant.cpp
@@ -32,8 +32,10 @@
#include "SupplicantState.h"
#include "SupplicantEvent.h"
#include "ScanResult.h"
+#include "PropertyManager.h"
#include "NetworkManager.h"
#include "ErrorCode.h"
+#include "WifiController.h"
#include "libwpa_client/wpa_ctrl.h"
@@ -43,21 +45,29 @@
#define SUPP_CONFIG_TEMPLATE "/system/etc/wifi/wpa_supplicant.conf"
#define SUPP_CONFIG_FILE "/data/misc/wifi/wpa_supplicant.conf"
-Supplicant::Supplicant() {
+Supplicant::Supplicant(WifiController *wc, PropertyManager *propmngr) {
+ mController = wc;
+ mPropMngr = propmngr;
+ mInterfaceName = NULL;
mCtrl = NULL;
mMonitor = NULL;
mListener = NULL;
-
+
mState = SupplicantState::UNKNOWN;
mServiceManager = new ServiceManager();
mLatestScanResults = new ScanResultCollection();
pthread_mutex_init(&mLatestScanResultsLock, NULL);
+
+ mNetworks = new WifiNetworkCollection();
+ pthread_mutex_init(&mNetworksLock, NULL);
}
Supplicant::~Supplicant() {
delete mServiceManager;
+ if (mInterfaceName)
+ free(mInterfaceName);
}
int Supplicant::start() {
@@ -65,7 +75,7 @@ int Supplicant::start() {
if (setupConfig()) {
LOGW("Unable to setup supplicant.conf");
}
-
+
if (mServiceManager->start(SUPPLICANT_SERVICE_NAME)) {
LOGE("Error starting supplicant (%s)", strerror(errno));
return -1;
@@ -76,11 +86,20 @@ int Supplicant::start() {
LOGE("Error connecting to supplicant (%s)\n", strerror(errno));
return -1;
}
+
+ if (retrieveInterfaceName()) {
+ LOGE("Error retrieving interface name (%s)\n", strerror(errno));
+ return -1;
+ }
+
+ mPropMngr->registerProperty("wifi.supplicant.state", this);
return 0;
}
int Supplicant::stop() {
+ mPropMngr->unregisterProperty("wifi.supplicant.state");
+
if (mListener->stopListener()) {
LOGW("Unable to stop supplicant listener (%s)", strerror(errno));
return -1;
@@ -106,13 +125,55 @@ bool Supplicant::isStarted() {
return mServiceManager->isRunning(SUPPLICANT_SERVICE_NAME);
}
-int Supplicant::connectToSupplicant() {
- if (!isStarted()) {
- LOGE("Supplicant not running, cannot connect");
+int Supplicant::refreshNetworkList() {
+ char *reply;
+ size_t len = 4096;
+
+ if (!(reply = (char *) malloc(len))) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if (sendCommand("LIST_NETWORKS", reply, &len)) {
+ free(reply);
return -1;
}
- mCtrl = wpa_ctrl_open("tiwlan0");
+ char *linep;
+ char *linep_next = NULL;
+
+ if (!strtok_r(reply, "\n", &linep_next)) {
+ LOGW("Malformatted network list\n");
+ } else {
+ pthread_mutex_lock(&mNetworksLock);
+ if (!mNetworks->empty()) {
+ WifiNetworkCollection::iterator i;
+
+ for (i = mNetworks->begin(); i !=mNetworks->end(); ++i)
+ delete *i;
+ mNetworks->clear();
+ }
+
+ while((linep = strtok_r(NULL, "\n", &linep_next))) {
+ WifiNetwork *wn = new WifiNetwork(mController, this, linep);
+ mNetworks->push_back(wn);
+ if (wn->refresh())
+ LOGW("Unable to refresh network id %d", wn->getNetworkId());
+ }
+
+ LOGD("Loaded %d networks\n", mNetworks->size());
+ pthread_mutex_unlock(&mNetworksLock);
+ }
+
+ free(reply);
+ return 0;
+}
+
+int Supplicant::connectToSupplicant() {
+ if (!isStarted())
+ LOGW("Supplicant service not running");
+
+ mCtrl = wpa_ctrl_open("tiwlan0"); // XXX:
if (mCtrl == NULL) {
LOGE("Unable to open connection to supplicant on \"%s\": %s",
"tiwlan0", strerror(errno));
@@ -132,7 +193,7 @@ int Supplicant::connectToSupplicant() {
}
mListener = new SupplicantListener(this, mMonitor);
-
+
if (mListener->startListener()) {
LOGE("Error - unable to start supplicant listener");
stop();
@@ -151,20 +212,17 @@ int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len)
// 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)) {
- LOGW("sendCommand(): <- '%s'", reply);
+ strcpy(reply, "FAIL");
errno = EIO;
return -1;
}
- if (!strncmp(cmd, "PING", 4) ||
- !strncmp(cmd, "SCAN_RESULTS", 12))
- reply[*reply_len] = '\0';
-
-// LOGD("sendCommand(): <- '%s'", reply);
+// LOGD("sendCommand(): <- '%s'", reply);
return 0;
}
@@ -187,6 +245,22 @@ int Supplicant::triggerScan(bool active) {
return 0;
}
+int Supplicant::set(const char *name, const char *value) {
+ const char *n = name + strlen("wifi.supplicant.");
+
+ errno = -EROFS;
+ return -1;
+}
+
+const char *Supplicant::get(const char *name, char *buffer, size_t max) {
+ const char *n = name + strlen("wifi.supplicant.");
+
+ if (!strcasecmp(n, "state"))
+ return SupplicantState::toString(mState, buffer, max);
+ errno = ENOENT;
+ return NULL;
+}
+
int Supplicant::onConnectedEvent(SupplicantEvent *evt) {
LOGD("onConnectedEvent(%s)", evt->getEvent());
return 0;
@@ -237,12 +311,12 @@ int Supplicant::onScanResultsEvent(SupplicantEvent *evt) {
char *reply;
if (!(reply = (char *) malloc(4096))) {
- errno = -ENOMEM;
+ errno = ENOMEM;
return -1;
}
size_t len = 4096;
-
+
if (sendCommand("SCAN_RESULTS", reply, &len)) {
LOGW("onScanResultsEvent(%s): Error getting scan results (%s)",
evt->getEvent(), strerror(errno));
@@ -272,7 +346,7 @@ int Supplicant::onScanResultsEvent(SupplicantEvent *evt) {
while((linep = strtok_r(NULL, "\n", &linep_next)))
mLatestScanResults->push_back(new ScanResult(linep));
-
+
char tmp[128];
sprintf(tmp, "Scan results ready (%d)", mLatestScanResults->size());
NetworkManager::Instance()->getBroadcaster()->
@@ -323,43 +397,78 @@ ScanResultCollection *Supplicant::createLatestScanResults() {
ScanResultCollection::iterator i;
pthread_mutex_lock(&mLatestScanResultsLock);
- for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i) {
+ for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i)
d->push_back((*i)->clone());
- }
pthread_mutex_unlock(&mLatestScanResultsLock);
return d;
}
-WifiNetworkCollection *Supplicant::createNetworkList() {
- WifiNetworkCollection *d = new WifiNetworkCollection();
- return d;
-}
-
-int Supplicant::addNetwork() {
- char reply[32];
+WifiNetwork *Supplicant::createNetwork() {
+ char reply[255];
size_t len = sizeof(reply) -1;
- memset(reply, 0, sizeof(reply));
if (sendCommand("ADD_NETWORK", reply, &len))
- return -1;
+ return NULL;
+
+ if (reply[strlen(reply) -1] == '\n')
+ reply[strlen(reply) -1] = '\0';
- return atoi(reply);
+ WifiNetwork *wn = new WifiNetwork(mController, this, atoi(reply));
+ pthread_mutex_lock(&mNetworksLock);
+ mNetworks->push_back(wn);
+ pthread_mutex_unlock(&mNetworksLock);
+ return wn;
}
-int Supplicant::removeNetwork(int networkId) {
+int Supplicant::removeNetwork(WifiNetwork *wn) {
char req[64];
- sprintf(req, "REMOVE_NETWORK %d", networkId);
+ sprintf(req, "REMOVE_NETWORK %d", wn->getNetworkId());
char reply[32];
size_t len = sizeof(reply) -1;
- memset(reply, 0, sizeof(reply));
-
+
if (sendCommand(req, reply, &len))
return -1;
+
+ pthread_mutex_lock(&mNetworksLock);
+ WifiNetworkCollection::iterator it;
+ for (it = mNetworks->begin(); it != mNetworks->end(); ++it) {
+ if ((*it) == wn) {
+ mNetworks->erase(it);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&mNetworksLock);
return 0;
}
+WifiNetwork *Supplicant::lookupNetwork(int networkId) {
+ pthread_mutex_lock(&mNetworksLock);
+ WifiNetworkCollection::iterator it;
+ for (it = mNetworks->begin(); it != mNetworks->end(); ++it) {
+ if ((*it)->getNetworkId() == networkId) {
+ pthread_mutex_unlock(&mNetworksLock);
+ return *it;
+ }
+ }
+ pthread_mutex_unlock(&mNetworksLock);
+ errno = ENOENT;
+ return NULL;
+}
+
+WifiNetworkCollection *Supplicant::createNetworkList() {
+ WifiNetworkCollection *d = new WifiNetworkCollection();
+ WifiNetworkCollection::iterator i;
+
+ pthread_mutex_lock(&mNetworksLock);
+ for (i = mNetworks->begin(); i != mNetworks->end(); ++i)
+ d->push_back((*i)->clone());
+
+ pthread_mutex_unlock(&mNetworksLock);
+ return d;
+}
+
int Supplicant::setupConfig() {
char buf[2048];
int srcfd, destfd;
@@ -407,3 +516,60 @@ int Supplicant::setupConfig() {
}
return 0;
}
+
+int Supplicant::setNetworkVar(int networkId, const char *var, const char *val) {
+ char reply[255];
+ size_t len = sizeof(reply) -1;
+
+ char *tmp;
+ asprintf(&tmp, "SET_NETWORK %d %s \"%s\"", networkId, var, val);
+ if (sendCommand(tmp, reply, &len)) {
+ free(tmp);
+ return -1;
+ }
+ free(tmp);
+ return 0;
+}
+
+const char *Supplicant::getNetworkVar(int networkId, const char *var,
+ char *buffer, size_t max) {
+ size_t len = max - 1;
+ char *tmp;
+
+ asprintf(&tmp, "GET_NETWORK %d %s", networkId, var);
+ if (sendCommand(tmp, buffer, &len)) {
+ free(tmp);
+ return NULL;
+ }
+ free(tmp);
+ return buffer;
+}
+
+int Supplicant::enableNetwork(int networkId, bool enabled) {
+ char req[64];
+
+ if (enabled)
+ sprintf(req, "ENABLE_NETWORK %d", networkId);
+ else
+ sprintf(req, "DISABLE_NETWORK %d", networkId);
+
+ char reply[16];
+ size_t len = sizeof(reply) -1;
+
+ if (sendCommand(req, reply, &len))
+ return -1;
+ return 0;
+}
+
+
+int Supplicant::retrieveInterfaceName() {
+ char reply[255];
+ size_t len = sizeof(reply) -1;
+
+ if (sendCommand("INTERFACES", reply, &len))
+ return -1;
+
+ reply[strlen(reply)-1] = '\0';
+ mInterfaceName = strdup(reply);
+ return 0;
+}