nexus: Implement wifi scanner and fix a lot of bugs

Signed-off-by: San Mehat <san@google.com>
This commit is contained in:
San Mehat 2009-05-07 11:37:10 -07:00
parent b3779558dc
commit 1441e769b2
21 changed files with 450 additions and 226 deletions

View File

@ -19,6 +19,7 @@ LOCAL_SRC_FILES:= \
SupplicantListener.cpp \
VpnController.cpp \
ScanResult.cpp \
WifiScanner.cpp \
LOCAL_MODULE:= nexus

View File

@ -19,60 +19,64 @@
#define LOG_TAG "CommandListener"
#include <cutils/log.h>
#include <sysutils/SocketClient.h>
#include "CommandListener.h"
#include "Controller.h"
#include "NetworkManager.h"
#include "WifiController.h"
CommandListener::CommandListener(NetworkManager *netman) :
CommandListener::CommandListener() :
FrameworkListener("nexus") {
mNetman = netman;
registerCmd(new WifiEnableCmd());
registerCmd(new WifiDisableCmd());
registerCmd(new WifiScanCmd());
registerCmd(new WifiScanResultsCmd());
registerCmd(new WifiEnableCmd(netman));
registerCmd(new WifiDisableCmd(netman));
registerCmd(new WifiScanCmd(netman));
registerCmd(new VpnEnableCmd(netman));
registerCmd(new VpnDisableCmd(netman));
registerCmd(new VpnEnableCmd());
registerCmd(new VpnDisableCmd());
}
/* -------------
* Wifi Commands
* ------------ */
CommandListener::WifiEnableCmd::WifiEnableCmd(NetworkManager *netman) :
NexusCommand("wifi_enable", netman) {
CommandListener::WifiEnableCmd::WifiEnableCmd() :
NexusCommand("wifi_enable") {
}
int CommandListener::WifiEnableCmd::runCommand(char *data) {
Controller *c = mNetman->findController("WIFI");
int CommandListener::WifiEnableCmd::runCommand(SocketClient *cli, char *data) {
Controller *c = NetworkManager::Instance()->findController("WIFI");
char buffer[32];
sprintf(buffer, "WIFI_ENABLE:%d", (c->enable() ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
cli->sendMsg(buffer);
return 0;
}
CommandListener::WifiDisableCmd::WifiDisableCmd(NetworkManager *netman) :
NexusCommand("wifi_disable", netman) {
CommandListener::WifiDisableCmd::WifiDisableCmd() :
NexusCommand("wifi_disable") {
}
int CommandListener::WifiDisableCmd::runCommand(char *data) {
Controller *c = mNetman->findController("WIFI");
int CommandListener::WifiDisableCmd::runCommand(SocketClient *cli, char *data) {
Controller *c = NetworkManager::Instance()->findController("WIFI");
char buffer[32];
sprintf(buffer, "WIFI_DISABLE:%d", (c->disable() ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
cli->sendMsg(buffer);
return 0;
}
CommandListener::WifiScanCmd::WifiScanCmd(NetworkManager *netman) :
NexusCommand("wifi_scan", netman) {
CommandListener::WifiScanCmd::WifiScanCmd() :
NexusCommand("wifi_scan") {
}
int CommandListener::WifiScanCmd::runCommand(char *data) {
int CommandListener::WifiScanCmd::runCommand(SocketClient *cli, char *data) {
LOGD("WifiScanCmd(%s)", data);
WifiController *wc = (WifiController *) mNetman->findController("WIFI");
WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI");
char buffer[32];
int mode = 0;
char *bword, *last;
@ -90,35 +94,62 @@ int CommandListener::WifiScanCmd::runCommand(char *data) {
mode = atoi(bword);
sprintf(buffer, "WIFI_SCAN:%d", (wc->setScanMode(mode) ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
cli->sendMsg(buffer);
return 0;
}
CommandListener::WifiScanResultsCmd::WifiScanResultsCmd() :
NexusCommand("wifi_scan_results") {
}
int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, char *data) {
NetworkManager *nm = NetworkManager::Instance();
WifiController *wc = (WifiController *) nm->findController("WIFI");
ScanResultCollection *src = wc->createScanResults();
ScanResultCollection::iterator it;
char buffer[256];
for(it = src->begin(); it != src->end(); ++it) {
sprintf(buffer, "WIFI_SCAN_RESULT:%s:%u:%d:%s:%s",
(*it)->getBssid(), (*it)->getFreq(), (*it)->getLevel(),
(*it)->getFlags(), (*it)->getSsid());
cli->sendMsg(buffer);
delete (*it);
it = src->erase(it);
}
delete src;
cli->sendMsg("WIFI_SCAN_RESULT:0");
return 0;
}
/* ------------
* Vpn Commands
* ------------ */
CommandListener::VpnEnableCmd::VpnEnableCmd(NetworkManager *netman) :
NexusCommand("vpn_enable", netman) {
CommandListener::VpnEnableCmd::VpnEnableCmd() :
NexusCommand("vpn_enable") {
}
int CommandListener::VpnEnableCmd::runCommand(char *data) {
Controller *c = mNetman->findController("VPN");
int CommandListener::VpnEnableCmd::runCommand(SocketClient *cli, char *data) {
Controller *c = NetworkManager::Instance()->findController("VPN");
char buffer[32];
sprintf(buffer, "VPN_ENABLE:%d", (c->enable() ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
cli->sendMsg(buffer);
return 0;
}
CommandListener::VpnDisableCmd::VpnDisableCmd(NetworkManager *netman) :
NexusCommand("vpn_disable", netman) {
CommandListener::VpnDisableCmd::VpnDisableCmd() :
NexusCommand("vpn_disable") {
}
int CommandListener::VpnDisableCmd::runCommand(char *data) {
Controller *c = mNetman->findController("VPN");
int CommandListener::VpnDisableCmd::runCommand(SocketClient *cli, char *data) {
Controller *c = NetworkManager::Instance()->findController("VPN");
char buffer[32];
sprintf(buffer, "VPN_DISABLE:%d", (c->disable() ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
cli->sendMsg(buffer);
return 0;
}

View File

@ -19,50 +19,52 @@
#include <sysutils/FrameworkListener.h>
#include "NexusCommand.h"
class NetworkManager;
class CommandListener : public FrameworkListener {
protected:
NetworkManager *mNetman;
public:
CommandListener(NetworkManager *netman);
CommandListener();
virtual ~CommandListener() {}
private:
class WifiEnableCmd : public NexusCommand {
public:
WifiEnableCmd(NetworkManager *);
WifiEnableCmd();
virtual ~WifiEnableCmd() {}
int runCommand(char *data);
int runCommand(SocketClient *c, char *data);
};
class WifiDisableCmd : public NexusCommand {
public:
WifiDisableCmd(NetworkManager *);
WifiDisableCmd();
virtual ~WifiDisableCmd() {}
int runCommand(char *data);
int runCommand(SocketClient *c, char *data);
};
class WifiScanCmd : public NexusCommand {
public:
WifiScanCmd(NetworkManager *);
WifiScanCmd();
virtual ~WifiScanCmd() {}
int runCommand(char *data);
int runCommand(SocketClient *c, char *data);
};
class WifiScanResultsCmd : public NexusCommand {
public:
WifiScanResultsCmd();
virtual ~WifiScanResultsCmd() {}
int runCommand(SocketClient *c, char *data);
};
class VpnEnableCmd : public NexusCommand {
public:
VpnEnableCmd(NetworkManager *);
VpnEnableCmd();
virtual ~VpnEnableCmd() {}
int runCommand(char *data);
int runCommand(SocketClient *c, char *data);
};
class VpnDisableCmd : public NexusCommand {
public:
VpnDisableCmd(NetworkManager *);
VpnDisableCmd();
virtual ~VpnDisableCmd() {}
int runCommand(char *data);
int runCommand(SocketClient *c, char *data);
};
};

View File

@ -21,36 +21,30 @@
#include <cutils/log.h>
#include "NetworkManager.h"
#include "CommandListener.h"
#include "LoopController.h"
#include "VpnController.h"
#include "TiwlanWifiController.h"
NetworkManager *NetworkManager::sInstance = NULL;
NetworkManager *NetworkManager::Instance() {
if (!sInstance)
sInstance = new NetworkManager();
return sInstance;
}
NetworkManager::NetworkManager() {
mListener = new CommandListener(this);
mFm = new FrameworkManager(mListener);
mBroadcaster = NULL;
mControllers = new ControllerCollection();
}
int NetworkManager::run() {
LOGD("NetworkManager::start()");
// XXX: Factory needed
addController(new LoopController());
addController(new TiwlanWifiController("/system/lib/modules/wlan.ko", "wlan", ""));
addController(new VpnController());
//addController(new GenericController("rmnet0"));
if (startControllers()) {
LOGW("Unable to start all controllers (%s)", strerror(errno));
}
mFm->run();
return 0;
}
void NetworkManager::addController(Controller *c) {
int NetworkManager::attachController(Controller *c) {
mControllers->push_back(c);
return 0;
}
int NetworkManager::startControllers() {

View File

@ -16,31 +16,36 @@
#ifndef _NETWORKMANAGER_H
#define _NETWORKMANAGER_H
#include "Controller.h"
#include <sysutils/SocketListener.h>
#include <sysutils/FrameworkManager.h>
#include "Controller.h"
class NetworkManager {
private:
FrameworkListener *mListener;
FrameworkManager *mFm;
static NetworkManager *sInstance;
private:
ControllerCollection *mControllers;
SocketListener *mBroadcaster;
public:
NetworkManager();
virtual ~NetworkManager() {}
int run();
int attachController(Controller *controller);
Controller *findController(const char *name);
void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
SocketListener *getBroadcaster() { return mBroadcaster; }
static NetworkManager *Instance();
private:
void addController(Controller *c);
int startControllers();
int stopControllers();
public:
Controller *findController(const char *name);
ControllerCollection *getControllers() { return mControllers; }
FrameworkManager *getFrameworkManager() { return mFm; }
NetworkManager();
public:
// XXX: Extract these into an interface

View File

@ -15,7 +15,6 @@
*/
#include "NexusCommand.h"
NexusCommand::NexusCommand(const char *cmd, NetworkManager *netman) :
NexusCommand::NexusCommand(const char *cmd) :
FrameworkCommand(cmd) {
mNetman = netman;
}

View File

@ -18,14 +18,9 @@
#include <sysutils/FrameworkCommand.h>
class NetworkManager;
class NexusCommand : public FrameworkCommand {
protected:
NetworkManager *mNetman;
public:
NexusCommand(const char *cmd, NetworkManager *netman);
NexusCommand(const char *cmd);
virtual ~NexusCommand() {}
};

View File

@ -38,6 +38,7 @@ public:
const char *getBssid() { return mBssid; }
uint32_t getFreq() { return mFreq; }
int getLevel() { return mLevel; }
const char *getFlags() { return mFlags; }
const char *getSsid() { return mSsid; }
};

View File

@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <errno.h>
#define LOG_TAG "Supplicant"
@ -31,6 +33,7 @@
#include "SupplicantState.h"
#include "SupplicantEvent.h"
#include "ScanResult.h"
#include "NetworkManager.h"
#include "libwpa_client/wpa_ctrl.h"
@ -52,7 +55,6 @@ Supplicant::Supplicant() {
}
int Supplicant::start() {
LOGD("start():");
// XXX: Validate supplicant config file
char status[PROPERTY_VALUE_MAX] = {'\0'};
@ -63,47 +65,47 @@ int Supplicant::start() {
#endif
if (property_get(SUPP_PROP_NAME, status, NULL) &&
strcmp(status, "running") == 0) {
return 0;
!strcmp(status, "running")) {
LOGD("Supplicant already started");
} 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") == 0)
break;
}
#endif
usleep(100000);
}
if (!count) {
errno = ETIMEDOUT;
return -1;
}
}
wpa_ctrl_cleanup();
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
pi = __system_property_find(SUPP_PROP_NAME);
if (pi != NULL)
serial = pi->serial;
#endif
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)
return 0;
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") == 0)
break;
}
#endif
usleep(100000);
}
if (!count) {
errno = ETIMEDOUT;
return -1;
}
if (connectToSupplicant()) {
LOGE("Error connecting to supplicant (%s)\n", strerror(errno));
return -1;
@ -112,7 +114,6 @@ int Supplicant::start() {
}
int Supplicant::stop() {
LOGD("stop()");
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
int count = 50;
@ -124,9 +125,11 @@ int Supplicant::stop() {
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();
@ -153,24 +156,29 @@ int Supplicant::stop() {
return -1;
}
LOGD("Stopped OK");
LOGD("Supplicant shutdown");
return 0;
}
bool Supplicant::isStarted() {
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
if (!property_get(SUPP_PROP_NAME, supp_status, NULL) ||
!strcmp(supp_status, "running")) {
return false;
}
return true;
int rc = property_get(SUPP_PROP_NAME, supp_status, NULL);
LOGD("rc = %d, property = '%s'", rc, supp_status);
if (!strcmp(supp_status, "running"))
return true;
return false;
}
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) {
LOGE("Supplicant not running, cannot connect");
@ -213,13 +221,14 @@ 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) {
errno = ETIMEDOUT;
return -1;
} else if (rc < 0 || !strncmp(reply, "FAIL", 4)) {
LOGW("sendCommand(): <- '%s'", reply);
errno = EIO;
return -1;
}
@ -228,7 +237,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;
}
@ -332,12 +341,16 @@ int Supplicant::onScanResultsEvent(SupplicantEvent *evt) {
if (!strtok_r(reply, "\n", &linep_next)) {
free(reply);
return 0;;
pthread_mutex_unlock(&mLatestScanResultsLock);
return 0;
}
while((linep = strtok_r(NULL, "\n", &linep_next)))
mLatestScanResults->push_back(new ScanResult(linep));
char tmp[32];
sprintf(tmp, "WIFI_SCAN_RESULTS_READY:%d", mLatestScanResults->size());
NetworkManager::Instance()->getBroadcaster()->sendBroadcast(tmp);
pthread_mutex_unlock(&mLatestScanResultsLock);
free(reply);
} else {
@ -347,8 +360,24 @@ int Supplicant::onScanResultsEvent(SupplicantEvent *evt) {
}
int Supplicant::onStateChangeEvent(SupplicantEvent *evt) {
LOGD("onStateChangeEvent(%s)", evt->getEvent());
// XXX: Update mState
char *bword, *last;
char *tmp = strdup(evt->getEvent());
if (!(bword = strtok_r(tmp, " ", &last))) {
LOGE("Malformatted state update (%s)", evt->getEvent());
free(tmp);
return 0;
}
if (!(bword = strtok_r(NULL, " ", &last))) {
LOGE("Malformatted state update (%s)", evt->getEvent());
free(tmp);
return 0;
}
mState = atoi(&bword[strlen("state=")]);
LOGD("State changed to %d", mState);
free(tmp);
return 0;
}
@ -363,7 +392,7 @@ int Supplicant::onDriverStateEvent(SupplicantEvent *evt) {
}
// XXX: Use a cursor + smartptr instead
const ScanResultCollection *Supplicant::getLatestScanResults() {
ScanResultCollection *Supplicant::createLatestScanResults() {
ScanResultCollection *d = new ScanResultCollection();
ScanResultCollection::iterator i;

View File

@ -46,7 +46,7 @@ public:
int getState() { return mState; }
const ScanResultCollection *getLatestScanResults();
ScanResultCollection *createLatestScanResults();
// XXX: Extract these into an interface
public:

View File

@ -30,31 +30,9 @@ SupplicantListener::SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *
SocketListener(wpa_ctrl_get_fd(monitor), false) {
mSupplicant = supplicant;
mMonitor = monitor;
mThread = NULL;
}
int SupplicantListener::startListener() {
LOGD("startListener()");
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
return pthread_create(&mThread, &attr, &SupplicantListener::threadStart, this);
}
int SupplicantListener::stopListener() {
errno = -ENOSYS;
return -1;
}
void *SupplicantListener::threadStart(void *obj) {
LOGD("threadStart(): Worker thread started");
reinterpret_cast<SupplicantListener *>(obj)->run();
LOGD("threadStart(): Worker thread exited");
return NULL;
}
bool SupplicantListener::onDataAvailable(int socket) {
bool SupplicantListener::onDataAvailable(SocketClient *cli) {
char buf[255];
size_t buflen = sizeof(buf);
int rc;
@ -62,7 +40,7 @@ bool SupplicantListener::onDataAvailable(int socket) {
if ((rc = wpa_ctrl_recv(mMonitor, buf, &nread))) {
LOGE("wpa_ctrl_recv failed (%s)", strerror(errno));
return -errno;
return false;
}
buf[nread] = '\0';
@ -108,7 +86,9 @@ bool SupplicantListener::onDataAvailable(int socket) {
delete evt;
if (rc)
if (rc) {
LOGW("Handler %d (%s) error: %s", evt->getType(), evt->getEvent(), strerror(errno));
return false;
}
return true;
}

View File

@ -16,33 +16,27 @@
#ifndef _SUPPLICANTLISTENER_H__
#define _SUPPLICANTLISTENER_H__
#include <pthread.h>
#include <sysutils/SocketListener.h>
struct wpa_ctrl;
class Supplicant;
class SocketClient;
class SupplicantListener: public SocketListener {
private:
struct wpa_ctrl *mMonitor;
Supplicant *mSupplicant;
pthread_t mThread;
public:
SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *monitor);
virtual ~SupplicantListener() {}
int startListener();
int stopListener();
struct wpa_ctrl *getMonitor() { return mMonitor; }
Supplicant *getSupplicant() { return mSupplicant; }
protected:
virtual bool onDataAvailable(int socket);
virtual bool onDataAvailable(SocketClient *c);
private:
static void *threadStart(void *obj);
};
#endif

View File

@ -18,16 +18,16 @@
class SupplicantState {
public:
static const int UNKNOWN = 0;
static const int DISCONNECTED = 1;
static const int INACTIVE = 2;
static const int SCANNING = 3;
static const int ASSOCIATING = 4;
static const int ASSOCIATED = 5;
static const int FOURWAY_HANDSHAKE = 6;
static const int GROUP_HANDSHAKE = 7;
static const int COMPLETED = 8;
static const int IDLE = 9;
static const int UNKNOWN = -1;
static const int DISCONNECTED = 0;
static const int INACTIVE = 1;
static const int SCANNING = 2;
static const int ASSOCIATING = 3;
static const int ASSOCIATED = 4;
static const int FOURWAY_HANDSHAKE = 5;
static const int GROUP_HANDSHAKE = 6;
static const int COMPLETED = 7;
static const int IDLE = 8;
};
#endif

View File

@ -65,3 +65,17 @@ int TiwlanWifiController::loadFirmware() {
property_set(DRIVER_PROP_NAME, "timeout");
return -1;
}
bool TiwlanWifiController::isFirmwareLoaded() {
char driver_status[PROPERTY_VALUE_MAX];
if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
if (!strcmp(driver_status, "ok"))
return true;
else {
LOGD("Driver status '%s'", driver_status);
return false;
}
}
LOGW("Unable to get property '%s'", DRIVER_PROP_NAME);
return false;
}

View File

@ -27,5 +27,6 @@ public:
virtual int powerDown();
virtual bool isPoweredUp();
virtual int loadFirmware();
virtual bool isFirmwareLoaded();
};
#endif

View File

@ -21,6 +21,8 @@
#include "Supplicant.h"
#include "WifiController.h"
#include "WifiScanner.h"
#include "NetworkManager.h"
WifiController::WifiController(char *modpath, char *modname, char *modargs) :
Controller("WIFI") {
@ -29,6 +31,7 @@ WifiController::WifiController(char *modpath, char *modname, char *modargs) :
strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
mSupplicant = new Supplicant();
mScanner = new WifiScanner(mSupplicant, 10);
mCurrentScanMode = 0;
}
@ -42,26 +45,36 @@ int WifiController::stop() {
}
int WifiController::enable() {
if (!isPoweredUp() && powerUp()) {
LOGE("Powerup failed (%s)", strerror(errno));
return -1;
if (!isPoweredUp()) {
sendStatusBroadcast("POWERING_UP");
if (powerUp()) {
LOGE("Powerup failed (%s)", strerror(errno));
return -1;
}
}
if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
sendStatusBroadcast("LOADING_DRIVER");
if (loadKernelModule(mModulePath, mModuleArgs)) {
LOGE("Kernel module load failed (%s)", strerror(errno));
goto out_powerdown;
}
}
if (loadFirmware()) {
LOGE("Firmware load failed (%s)", strerror(errno));
goto out_powerdown;
if (!isFirmwareLoaded()) {
sendStatusBroadcast("LOADING_FIRMWARE");
if (loadFirmware()) {
LOGE("Firmware load failed (%s)", strerror(errno));
goto out_powerdown;
}
}
if (!mSupplicant->isStarted() && mSupplicant->start()) {
LOGE("Supplicant start failed (%s)", strerror(errno));
goto out_unloadmodule;
if (!mSupplicant->isStarted()) {
sendStatusBroadcast("STARTING_SUPPLICANT");
if (mSupplicant->start()) {
LOGE("Supplicant start failed (%s)", strerror(errno));
goto out_unloadmodule;
}
}
return 0;
@ -80,24 +93,38 @@ out_powerdown:
return -1;
}
int WifiController::disable() {
LOGD("disable()");
void WifiController::sendStatusBroadcast(const char *msg) {
char tmp[255];
if (mSupplicant->isStarted() && mSupplicant->stop()) {
LOGE("Supplicant stop failed (%s)", strerror(errno));
return -1;
}
sprintf(tmp, "WIFI_STATUS:%s", msg);
NetworkManager::Instance()->getBroadcaster()->sendBroadcast(tmp);
}
int WifiController::disable() {
if (mSupplicant->isStarted()) {
sendStatusBroadcast("STOPPING_SUPPLICANT");
if (mSupplicant->stop()) {
LOGE("Supplicant stop failed (%s)", strerror(errno));
return -1;
}
} else
LOGW("disable(): Supplicant not running?");
if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
sendStatusBroadcast("UNLOADING_DRIVER");
if (unloadKernelModule(mModuleName)) {
LOGE("Unable to unload module (%s)", strerror(errno));
return -1;
}
}
if (isPoweredUp() && powerDown()) {
LOGE("Powerdown failed (%s)", strerror(errno));
return -1;
if (isPoweredUp()) {
sendStatusBroadcast("POWERING_DOWN");
if (powerDown()) {
LOGE("Powerdown failed (%s)", strerror(errno));
return -1;
}
}
return 0;
}
@ -106,7 +133,7 @@ int WifiController::loadFirmware() {
return 0;
}
int WifiController::setScanMode(int mode) {
int WifiController::setScanMode(uint32_t mode) {
int rc = 0;
if (mCurrentScanMode == mode)
@ -114,21 +141,15 @@ int WifiController::setScanMode(int mode) {
if (!(mode & SCAN_ENABLE_MASK)) {
if (mCurrentScanMode & SCAN_REPEAT_MASK)
stopPeriodicScan();
mScanner->stopPeriodicScan();
} else if (mode & SCAN_REPEAT_MASK)
rc = startPeriodicScan();
rc = mScanner->startPeriodicScan(mode & SCAN_ACTIVE_MASK);
else
rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
return rc;
}
int WifiController::startPeriodicScan() {
errno = -ENOSYS;
return -1;
}
int WifiController::stopPeriodicScan() {
errno = -ENOSYS;
return -1;
ScanResultCollection *WifiController::createScanResults() {
return mSupplicant->createLatestScanResults();
}

View File

@ -22,6 +22,9 @@
class NetInterface;
class Supplicant;
class WifiScanner;
#include "ScanResult.h"
class WifiController : public Controller {
public:
@ -40,8 +43,8 @@ private:
char mModulePath[255];
char mModuleName[64];
char mModuleArgs[255];
int mCurrentScanMode;
uint32_t mCurrentScanMode;
WifiScanner *mScanner;
public:
WifiController(char *modpath, char *modname, char *modargs);
@ -53,6 +56,8 @@ public:
int enable();
int disable();
ScanResultCollection *createScanResults();
int getType();
char *getModulePath() { return mModulePath; }
@ -62,17 +67,17 @@ public:
Supplicant *getSupplicant() { return mSupplicant; }
int getScanMode() { return mCurrentScanMode; }
int setScanMode(int mode);
int setScanMode(uint32_t mode);
protected:
virtual int powerUp() = 0;
virtual int powerDown() = 0;
virtual int loadFirmware();
virtual bool isFirmwareLoaded() = 0;
virtual bool isPoweredUp() = 0;
private:
int startPeriodicScan();
int stopPeriodicScan();
void sendStatusBroadcast(const char *msg);
};
#endif

96
nexus/WifiScanner.cpp Normal file
View File

@ -0,0 +1,96 @@
#include <errno.h>
#include <pthread.h>
#define LOG_TAG "WifiScanner"
#include <cutils/log.h>
#include "WifiScanner.h"
#include "Supplicant.h"
extern "C" int pthread_cancel(pthread_t thread);
WifiScanner::WifiScanner(Supplicant *suppl, int period) {
mSuppl = suppl;
mPeriod = period;
mActive = false;
mWorkerRunning = false;
mAbortRequest = false;
pthread_mutex_init(&mAbortRequestLock, NULL);
pthread_mutex_init(&mWorkerLock, NULL);
}
int WifiScanner::startPeriodicScan(bool active) {
mActive = active;
pthread_mutex_lock(&mWorkerLock);
if (mWorkerRunning) {
errno = EBUSY;
return -1;
}
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (pthread_create(&mWorker, &attr, WifiScanner::threadStart, this))
return -1;
return 0;
}
void *WifiScanner::threadStart(void *obj) {
WifiScanner *me = reinterpret_cast<WifiScanner *>(obj);
me->run();
pthread_exit(NULL);
return NULL;
}
void WifiScanner::threadCleanup(void *obj) {
WifiScanner *me = reinterpret_cast<WifiScanner *>(obj);
me->mWorkerRunning = false;
pthread_mutex_unlock(&me->mWorkerLock);
if (me->mAbortRequest) {
me->mAbortRequest = false;
pthread_mutex_unlock(&me->mAbortRequestLock);
}
}
int WifiScanner::stopPeriodicScan() {
pthread_mutex_lock(&mAbortRequestLock);
pthread_mutex_lock(&mWorkerLock);
if (mWorkerRunning)
mAbortRequest = true;
pthread_mutex_unlock(&mWorkerLock);
pthread_mutex_unlock(&mAbortRequestLock);
return 0;
}
void WifiScanner::run() {
LOGD("Thread started");
mWorkerRunning = true;
pthread_cleanup_push(WifiScanner::threadCleanup, this);
pthread_mutex_unlock(&mWorkerLock);
while(1) {
LOGD("Triggering periodic scan");
if (mSuppl->triggerScan(mActive)) {
LOGW("Error triggering scan (%s)", strerror(errno));
}
sleep(mPeriod);
pthread_mutex_lock(&mAbortRequestLock);
if (mAbortRequest) {
LOGD("Abort request!");
goto out;
}
pthread_mutex_unlock(&mAbortRequestLock);
}
out:
pthread_cleanup_pop(1);
pthread_mutex_unlock(&mWorkerLock);
}

36
nexus/WifiScanner.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef _WIFISCANNER_H
#define _WIFISCANNER_H
#include <pthread.h>
class Supplicant;
class WifiScanner {
pthread_t mWorker;
pthread_mutex_t mWorkerLock;
bool mWorkerRunning;
bool mAbortRequest;
pthread_mutex_t mAbortRequestLock;
Supplicant *mSuppl;
int mPeriod;
bool mActive;
public:
WifiScanner(Supplicant *suppl, int period);
virtual ~WifiScanner() {}
int getPeriod() { return mPeriod; }
int startPeriodicScan(bool active);
int stopPeriodicScan();
private:
static void *threadStart(void *obj);
static void threadCleanup(void *obj);
void run();
};
#endif

View File

@ -20,22 +20,44 @@
#include "cutils/log.h"
#include "NetworkManager.h"
#include "CommandListener.h"
#include "LoopController.h"
#include "VpnController.h"
#include "TiwlanWifiController.h"
int main() {
NetworkManager *nm;
LOGI("Nexus version 0.1 firing up");
if (!(nm = new NetworkManager())) {
CommandListener *cl = new CommandListener();
NetworkManager *nm;
if (!(nm = NetworkManager::Instance())) {
LOGE("Unable to create NetworkManager");
exit (-1);
};
if (nm->run()) {
nm->setBroadcaster((SocketListener *) cl);
nm->attachController(new LoopController());
nm->attachController(new TiwlanWifiController("/system/lib/modules/wlan.ko", "wlan", ""));
nm->attachController(new VpnController());
if (NetworkManager::Instance()->run()) {
LOGE("Unable to Run NetworkManager (%s)", strerror(errno));
exit (1);
}
if (cl->startListener()) {
LOGE("Unable to start CommandListener (%s)", strerror(errno));
exit (1);
}
while(1) {
sleep(1000);
}
LOGI("Nexus exiting");
exit(0);
}

View File

@ -65,14 +65,13 @@ int main(int argc, char **argv) {
buffer[strlen(buffer) -1] = 0;
printf("sending '%s'\n", buffer);
if (write(sock, buffer, strlen(buffer) +1) < 0) {
fprintf(stderr, "Error writing data (%s)\n", strerror(errno));
exit(2);
}
wait:
to.tv_sec = 5;
to.tv_sec = 10;
to.tv_usec = 0;
FD_ZERO(&read_fds);
FD_SET(sock, &read_fds);
@ -88,12 +87,11 @@ wait:
printf("{response timeout}\n");
continue;
} else if (FD_ISSET(sock, &read_fds)) {
printf("got data!\n");
if ((rc = read(sock, buffer, sizeof(buffer)-1)) < 0) {
if ((rc = read(sock, buffer, sizeof(buffer)-1)) <= 0) {
fprintf(stderr, "Error reading response (%s)\n", strerror(errno));
exit(2);
}
printf(" |%s|\n", buffer);
printf(" %s\n", buffer);
goto wait;
}
}