nexus: Cleanup the scanner and plug it all in so it works

Signed-off-by: San Mehat <san@google.com>
diff --git a/nexus/Supplicant.cpp b/nexus/Supplicant.cpp
index fd56128..9443598 100644
--- a/nexus/Supplicant.cpp
+++ b/nexus/Supplicant.cpp
@@ -314,8 +314,6 @@
 }
 
 int Supplicant::onScanResultsEvent(SupplicantEvent *evt) {
-    LOGD("onScanResultsEvent(%s)", evt->getEvent());
-
     if (!strcmp(evt->getEvent(), "Ready")) {
         char *reply;
 
diff --git a/nexus/Supplicant.h b/nexus/Supplicant.h
index 3a79623..579bfd6 100644
--- a/nexus/Supplicant.h
+++ b/nexus/Supplicant.h
@@ -38,17 +38,20 @@
     Supplicant();
     virtual ~Supplicant() {}
 
-    virtual int start();
-    virtual int stop();
-    virtual bool isStarted();
+    int start();
+    int stop();
+    bool isStarted();
+    int triggerScan(bool active);
 
-    virtual int triggerScan(bool active);
+    ScanResultCollection *createLatestScanResults();
+    WifiNetworkCollection *createWifiNetworkList();
+
 
     int getState() { return mState; }
 
-    ScanResultCollection *createLatestScanResults();
 
 // XXX: Extract these into an interface
+// handlers for SupplicantListener
 public:
     virtual int onConnectedEvent(SupplicantEvent *evt);
     virtual int onDisconnectedEvent(SupplicantEvent *evt);
diff --git a/nexus/WifiController.cpp b/nexus/WifiController.cpp
index 66c5378..f67761a 100644
--- a/nexus/WifiController.cpp
+++ b/nexus/WifiController.cpp
@@ -141,12 +141,13 @@
 
     if (!(mode & SCAN_ENABLE_MASK)) {
         if (mCurrentScanMode & SCAN_REPEAT_MASK)
-            mScanner->stopPeriodicScan();
+            mScanner->stop();
     } else if (mode & SCAN_REPEAT_MASK)
-        rc = mScanner->startPeriodicScan(mode & SCAN_ACTIVE_MASK);
+        rc = mScanner->start(mode & SCAN_ACTIVE_MASK);
     else
         rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
-    
+
+    mCurrentScanMode = mode;
     return rc;
 }
 
diff --git a/nexus/WifiScanner.cpp b/nexus/WifiScanner.cpp
index 590d895..1bc9722 100644
--- a/nexus/WifiScanner.cpp
+++ b/nexus/WifiScanner.cpp
@@ -1,3 +1,8 @@
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
 #include <errno.h>
 #include <pthread.h>
 
@@ -13,28 +18,16 @@
     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) {
+int WifiScanner::start(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))
+    if(pipe(mCtrlPipe))
         return -1;
 
+    if (pthread_create(&mThread, NULL, WifiScanner::threadStart, this))
+        return -1;
     return 0;
 }
 
@@ -45,52 +38,49 @@
     return NULL;
 }
 
-void WifiScanner::threadCleanup(void *obj) {
-    WifiScanner *me = reinterpret_cast<WifiScanner *>(obj);
+int WifiScanner::stop() {
+    char c = 0;
 
-    me->mWorkerRunning = false;
-    pthread_mutex_unlock(&me->mWorkerLock);
-
-    if (me->mAbortRequest) {
-        me->mAbortRequest = false;
-        pthread_mutex_unlock(&me->mAbortRequestLock);
+    if (write(mCtrlPipe[1], &c, 1) != 1) {
+        LOGE("Error writing to control pipe (%s)", strerror(errno));
+        return -1;
     }
-}
 
-int WifiScanner::stopPeriodicScan() {
-    pthread_mutex_lock(&mAbortRequestLock);
-    pthread_mutex_lock(&mWorkerLock);
-    if (mWorkerRunning)
-        mAbortRequest = true;
-    pthread_mutex_unlock(&mWorkerLock);
-    pthread_mutex_unlock(&mAbortRequestLock);
+    void *ret;
+    if (pthread_join(mThread, &ret)) {
+        LOGE("Error joining to scanner thread (%s)", strerror(errno));
+        return -1;
+    }
 
+    close(mCtrlPipe[0]);
+    close(mCtrlPipe[1]);
     return 0;
 }
 
 void WifiScanner::run() {
-    LOGD("Thread started");
-
-    mWorkerRunning = true;
-    pthread_cleanup_push(WifiScanner::threadCleanup, this);
-    pthread_mutex_unlock(&mWorkerLock);
+    LOGD("Starting wifi scanner (active = %d)", mActive);
 
     while(1) {
-        LOGD("Triggering periodic scan");
+        fd_set read_fds;
+        struct timeval to;
+        int rc = 0;
+
+        to.tv_sec = 0;
+        to.tv_sec = mPeriod;
+
+        FD_ZERO(&read_fds);
+        FD_SET(mCtrlPipe[0], &read_fds);
+
         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);
+        if ((rc = select(mCtrlPipe[0] + 1, &read_fds, NULL, NULL, &to)) < 0) {
+            LOGE("select failed (%s) - sleeping for one scanner period", strerror(errno));
+            sleep(mPeriod);
+            continue;
+        } else if (!rc) {
+        } else if (FD_ISSET(mCtrlPipe[0], &read_fds))
+            break;
+    } // while
 }
diff --git a/nexus/WifiScanner.h b/nexus/WifiScanner.h
index 9ba1309..4406e9f 100644
--- a/nexus/WifiScanner.h
+++ b/nexus/WifiScanner.h
@@ -6,12 +6,8 @@
 class Supplicant;
 
 class WifiScanner {
-    pthread_t       mWorker;
-    pthread_mutex_t mWorkerLock;
-    bool            mWorkerRunning;
-    bool            mAbortRequest;
-    pthread_mutex_t mAbortRequestLock;
-
+    pthread_t  mThread;
+    int        mCtrlPipe[2];
     Supplicant *mSuppl;
     int        mPeriod;
     bool       mActive;
@@ -23,12 +19,11 @@
 
     int getPeriod() { return mPeriod; }
 
-    int startPeriodicScan(bool active);
-    int stopPeriodicScan();
+    int start(bool active);
+    int stop();
 
 private:
     static void *threadStart(void *obj);
-    static void threadCleanup(void *obj);
 
     void run();
 };