diff --git a/nexus/Android.mk b/nexus/Android.mk index e76cb27e7..7cf4a1fa1 100644 --- a/nexus/Android.mk +++ b/nexus/Android.mk @@ -19,6 +19,7 @@ LOCAL_SRC_FILES:= \ SupplicantListener.cpp \ VpnController.cpp \ ScanResult.cpp \ + WifiScanner.cpp \ LOCAL_MODULE:= nexus diff --git a/nexus/CommandListener.cpp b/nexus/CommandListener.cpp index cdb1db51f..02ede1523 100644 --- a/nexus/CommandListener.cpp +++ b/nexus/CommandListener.cpp @@ -19,60 +19,64 @@ #define LOG_TAG "CommandListener" #include +#include + #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; } diff --git a/nexus/CommandListener.h b/nexus/CommandListener.h index 261c0936a..064eab890 100644 --- a/nexus/CommandListener.h +++ b/nexus/CommandListener.h @@ -19,50 +19,52 @@ #include #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); }; }; diff --git a/nexus/NetworkManager.cpp b/nexus/NetworkManager.cpp index 9c649459d..3b823d15d 100644 --- a/nexus/NetworkManager.cpp +++ b/nexus/NetworkManager.cpp @@ -21,36 +21,30 @@ #include #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() { diff --git a/nexus/NetworkManager.h b/nexus/NetworkManager.h index 8f362a95f..0ac4a4dbb 100644 --- a/nexus/NetworkManager.h +++ b/nexus/NetworkManager.h @@ -16,31 +16,36 @@ #ifndef _NETWORKMANAGER_H #define _NETWORKMANAGER_H -#include "Controller.h" +#include -#include +#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 diff --git a/nexus/NexusCommand.cpp b/nexus/NexusCommand.cpp index 090113c09..92bb1c31b 100644 --- a/nexus/NexusCommand.cpp +++ b/nexus/NexusCommand.cpp @@ -15,7 +15,6 @@ */ #include "NexusCommand.h" -NexusCommand::NexusCommand(const char *cmd, NetworkManager *netman) : +NexusCommand::NexusCommand(const char *cmd) : FrameworkCommand(cmd) { - mNetman = netman; } diff --git a/nexus/NexusCommand.h b/nexus/NexusCommand.h index 204541c1d..1482998c1 100644 --- a/nexus/NexusCommand.h +++ b/nexus/NexusCommand.h @@ -18,14 +18,9 @@ #include -class NetworkManager; - class NexusCommand : public FrameworkCommand { -protected: - NetworkManager *mNetman; - public: - NexusCommand(const char *cmd, NetworkManager *netman); + NexusCommand(const char *cmd); virtual ~NexusCommand() {} }; diff --git a/nexus/ScanResult.h b/nexus/ScanResult.h index 79b2b659f..f70a1a906 100644 --- a/nexus/ScanResult.h +++ b/nexus/ScanResult.h @@ -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; } }; diff --git a/nexus/Supplicant.cpp b/nexus/Supplicant.cpp index 215a8b347..d809e6eb6 100644 --- a/nexus/Supplicant.cpp +++ b/nexus/Supplicant.cpp @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include #include #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; diff --git a/nexus/Supplicant.h b/nexus/Supplicant.h index 46a9e86ce..2a25ea27e 100644 --- a/nexus/Supplicant.h +++ b/nexus/Supplicant.h @@ -46,7 +46,7 @@ public: int getState() { return mState; } - const ScanResultCollection *getLatestScanResults(); + ScanResultCollection *createLatestScanResults(); // XXX: Extract these into an interface public: diff --git a/nexus/SupplicantListener.cpp b/nexus/SupplicantListener.cpp index 16306b5b6..76e99456e 100644 --- a/nexus/SupplicantListener.cpp +++ b/nexus/SupplicantListener.cpp @@ -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(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; } diff --git a/nexus/SupplicantListener.h b/nexus/SupplicantListener.h index 3d27a6810..95bad9a28 100644 --- a/nexus/SupplicantListener.h +++ b/nexus/SupplicantListener.h @@ -16,33 +16,27 @@ #ifndef _SUPPLICANTLISTENER_H__ #define _SUPPLICANTLISTENER_H__ -#include - #include 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 diff --git a/nexus/SupplicantState.h b/nexus/SupplicantState.h index f2cf6039c..e85dcb505 100644 --- a/nexus/SupplicantState.h +++ b/nexus/SupplicantState.h @@ -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 diff --git a/nexus/TiwlanWifiController.cpp b/nexus/TiwlanWifiController.cpp index ec83825b8..10606a103 100644 --- a/nexus/TiwlanWifiController.cpp +++ b/nexus/TiwlanWifiController.cpp @@ -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; +} diff --git a/nexus/TiwlanWifiController.h b/nexus/TiwlanWifiController.h index a93d61004..f17ef51f5 100644 --- a/nexus/TiwlanWifiController.h +++ b/nexus/TiwlanWifiController.h @@ -27,5 +27,6 @@ public: virtual int powerDown(); virtual bool isPoweredUp(); virtual int loadFirmware(); + virtual bool isFirmwareLoaded(); }; #endif diff --git a/nexus/WifiController.cpp b/nexus/WifiController.cpp index 8a7e33f9e..806141cf8 100644 --- a/nexus/WifiController.cpp +++ b/nexus/WifiController.cpp @@ -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(); } diff --git a/nexus/WifiController.h b/nexus/WifiController.h index 6d0051323..38aea816b 100644 --- a/nexus/WifiController.h +++ b/nexus/WifiController.h @@ -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 diff --git a/nexus/WifiScanner.cpp b/nexus/WifiScanner.cpp new file mode 100644 index 000000000..590d89572 --- /dev/null +++ b/nexus/WifiScanner.cpp @@ -0,0 +1,96 @@ +#include +#include + +#define LOG_TAG "WifiScanner" +#include + +#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(obj); + me->run(); + pthread_exit(NULL); + return NULL; +} + +void WifiScanner::threadCleanup(void *obj) { + WifiScanner *me = reinterpret_cast(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); +} diff --git a/nexus/WifiScanner.h b/nexus/WifiScanner.h new file mode 100644 index 000000000..9ba130920 --- /dev/null +++ b/nexus/WifiScanner.h @@ -0,0 +1,36 @@ +#ifndef _WIFISCANNER_H +#define _WIFISCANNER_H + +#include + +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 diff --git a/nexus/main.cpp b/nexus/main.cpp index a26a14d37..0a0b43fa3 100644 --- a/nexus/main.cpp +++ b/nexus/main.cpp @@ -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); } diff --git a/nexus/nexctl.c b/nexus/nexctl.c index 6d117c778..c326558af 100644 --- a/nexus/nexctl.c +++ b/nexus/nexctl.c @@ -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; } }