• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

Revisiónc73d9e43a0c98a87222ef0c8749d6abba06c7778 (tree)
Tiempo2009-05-12 01:01:15
AutorAndroid (Google) Code Review <android-gerrit@goog...>
CommiterAndroid (Google) Code Review

Log Message

Merge changes 1341,1342 into donut

* changes:

libsysutils: Add multiple client support and fix some bugs
nexus: Implement wifi scanner and fix a lot of bugs

Cambiar Resumen

Diferencia incremental

--- /dev/null
+++ b/include/sysutils/FrameworkClient.h
@@ -0,0 +1,21 @@
1+#ifndef _FRAMEWORK_CLIENT_H
2+#define _FRAMEWORK_CLIENT_H
3+
4+#include "../../../frameworks/base/include/utils/List.h"
5+
6+#include <pthread.h>
7+
8+class FrameworkClient {
9+ int mSocket;
10+ pthread_mutex_t mWriteMutex;
11+
12+public:
13+ FrameworkClient(int sock);
14+ virtual ~FrameworkClient() {}
15+
16+ int sendMsg(char *msg);
17+ int sendMsg(char *msg, char *data);
18+};
19+
20+typedef android::List<FrameworkClient *> FrameworkClientCollection;
21+#endif
--- a/include/sysutils/FrameworkCommand.h
+++ b/include/sysutils/FrameworkCommand.h
@@ -18,6 +18,7 @@
1818
1919 #include "../../../frameworks/base/include/utils/List.h"
2020
21+class SocketClient;
2122
2223 class FrameworkCommand {
2324 private:
@@ -28,7 +29,7 @@ public:
2829 FrameworkCommand(const char *cmd);
2930 virtual ~FrameworkCommand() { }
3031
31- virtual int runCommand(char *data);
32+ virtual int runCommand(SocketClient *c, char *data) = 0;
3233
3334 const char *getCommand() { return mCommand; }
3435 };
--- a/include/sysutils/FrameworkListener.h
+++ b/include/sysutils/FrameworkListener.h
@@ -19,6 +19,8 @@
1919 #include "SocketListener.h"
2020 #include "FrameworkCommand.h"
2121
22+class SocketClient;
23+
2224 class FrameworkListener : public SocketListener {
2325 private:
2426 FrameworkCommandCollection *mCommands;
@@ -29,9 +31,9 @@ public:
2931
3032 protected:
3133 void registerCmd(FrameworkCommand *cmd);
32- virtual bool onDataAvailable(int socket);
34+ virtual bool onDataAvailable(SocketClient *c);
3335
3436 private:
35- void dispatchCommand(char *cmd);
37+ void dispatchCommand(SocketClient *c, char *cmd);
3638 };
3739 #endif
--- a/include/sysutils/FrameworkManager.h
+++ /dev/null
@@ -1,40 +0,0 @@
1-/*
2- * Copyright (C) 2008 The Android Open Source Project
3- *
4- * Licensed under the Apache License, Version 2.0 (the "License");
5- * you may not use this file except in compliance with the License.
6- * You may obtain a copy of the License at
7- *
8- * http://www.apache.org/licenses/LICENSE-2.0
9- *
10- * Unless required by applicable law or agreed to in writing, software
11- * distributed under the License is distributed on an "AS IS" BASIS,
12- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13- * See the License for the specific language governing permissions and
14- * limitations under the License.
15- */
16-#ifndef _FRAMEWORKMANAGER_H
17-#define _FRAMEWORKMANAGER_H
18-
19-#include <pthread.h>
20-
21-class FrameworkListener;
22-
23-class FrameworkManager {
24- int mDoorbell; // Socket used to accept connections from framework
25- int mFwSock; // Socket used to communicate with framework
26- const char *mSocketName;
27-
28- FrameworkListener *mListener;
29-
30- pthread_mutex_t mWriteMutex;
31-
32-public:
33- FrameworkManager(FrameworkListener *Listener);
34- virtual ~FrameworkManager() {}
35-
36- int run();
37- int sendMsg(char *msg);
38- int sendMsg(char *msg, char *data);
39-};
40-#endif
--- a/include/sysutils/NetlinkListener.h
+++ b/include/sysutils/NetlinkListener.h
@@ -27,6 +27,6 @@ public:
2727 NetlinkListener(int socket);
2828 virtual ~NetlinkListener() {}
2929 protected:
30- virtual bool onDataAvailable(int socket);
30+ virtual bool onDataAvailable(SocketClient *cli);
3131 };
3232 #endif
--- /dev/null
+++ b/include/sysutils/SocketClient.h
@@ -0,0 +1,23 @@
1+#ifndef _SOCKET_CLIENT_H
2+#define _SOCKET_CLIENT_H
3+
4+#include "../../../frameworks/base/include/utils/List.h"
5+
6+#include <pthread.h>
7+
8+class SocketClient {
9+ int mSocket;
10+ pthread_mutex_t mWriteMutex;
11+
12+public:
13+ SocketClient(int sock);
14+ virtual ~SocketClient() {}
15+
16+ int getSocket() { return mSocket; }
17+
18+ int sendMsg(char *msg);
19+ int sendMsg(char *msg, char *data);
20+};
21+
22+typedef android::List<SocketClient *> SocketClientCollection;
23+#endif
--- a/include/sysutils/SocketListener.h
+++ b/include/sysutils/SocketListener.h
@@ -16,20 +16,35 @@
1616 #ifndef _SOCKETLISTENER_H
1717 #define _SOCKETLISTENER_H
1818
19+#include <pthread.h>
20+
21+#include <sysutils/SocketClient.h>
22+
1923 class SocketListener {
20- int mSock;
21- int mCsock;
22- int mAcceptClients;
23- const char *mSocketName;
24+ int mSock;
25+ const char *mSocketName;
26+ SocketClientCollection *mClients;
27+ pthread_mutex_t mClientsLock;
28+ bool mListen;
29+ int mCtrlPipe[2];
30+ pthread_t mThread;
2431
2532 public:
26- SocketListener(const char *socketName, bool acceptClients);
27- SocketListener(int socketFd, bool acceptClients);
33+ SocketListener(const char *socketNames, bool listen);
34+ SocketListener(int socketFd, bool listen);
2835
2936 virtual ~SocketListener() {}
30- virtual int run();
37+ int startListener();
38+ int stopListener();
39+
40+ void sendBroadcast(char *msg);
41+ void sendBroadcast(char *msg, char *data);
3142
3243 protected:
33- virtual bool onDataAvailable(int socket);
44+ virtual bool onDataAvailable(SocketClient *c) = 0;
45+
46+private:
47+ static void *threadStart(void *obj);
48+ void runListener();
3449 };
3550 #endif
--- a/libsysutils/Android.mk
+++ b/libsysutils/Android.mk
@@ -3,12 +3,12 @@ LOCAL_PATH:= $(call my-dir)
33 include $(CLEAR_VARS)
44
55 LOCAL_SRC_FILES:= \
6- src/FrameworkManager.cpp \
76 src/SocketListener.cpp \
87 src/FrameworkListener.cpp \
98 src/NetlinkListener.cpp \
109 src/NetlinkEvent.cpp \
1110 src/FrameworkCommand.cpp \
11+ src/SocketClient.cpp \
1212
1313 LOCAL_MODULE:= libsysutils
1414
--- /dev/null
+++ b/libsysutils/src/FrameworkClient.cpp
@@ -0,0 +1,41 @@
1+#include <alloca.h>
2+#include <errno.h>
3+#include <sys/types.h>
4+#include <pthread.h>
5+
6+#define LOG_TAG "FrameworkClient"
7+#include <cutils/log.h>
8+
9+#include <sysutils/FrameworkClient.h>
10+
11+FrameworkClient::FrameworkClient(int socket) {
12+ mSocket = socket;
13+ pthread_mutex_init(&mWriteMutex, NULL);
14+}
15+
16+int FrameworkClient::sendMsg(char *msg) {
17+ LOGD("FrameworkClient::sendMsg(%s)", msg);
18+ if (mSocket < 0) {
19+ errno = EHOSTUNREACH;
20+ return -1;
21+ }
22+
23+ pthread_mutex_lock(&mWriteMutex);
24+ if (write(mSocket, msg, strlen(msg) +1) < 0) {
25+ LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno));
26+ }
27+ pthread_mutex_unlock(&mWriteMutex);
28+ return 0;
29+}
30+
31+int FrameworkClient::sendMsg(char *msg, char *data) {
32+ char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1);
33+ if (!buffer) {
34+ errno = -ENOMEM;
35+ return -1;
36+ }
37+ strcpy(buffer, msg);
38+ strcat(buffer, data);
39+ return sendMsg(buffer);
40+}
41+
--- a/libsysutils/src/FrameworkCommand.cpp
+++ b/libsysutils/src/FrameworkCommand.cpp
@@ -25,7 +25,7 @@ FrameworkCommand::FrameworkCommand(const char *cmd) {
2525 mCommand = cmd;
2626 }
2727
28-int FrameworkCommand::runCommand(char *data) {
28+int FrameworkCommand::runCommand(SocketClient *c, char *data) {
2929 LOGW("Command %s has no run handler!", getCommand());
3030 errno = ENOSYS;
3131 return -1;
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -22,17 +22,18 @@
2222
2323 #include <sysutils/FrameworkListener.h>
2424 #include <sysutils/FrameworkCommand.h>
25+#include <sysutils/SocketClient.h>
2526
2627 FrameworkListener::FrameworkListener(const char *socketName) :
2728 SocketListener(socketName, true) {
2829 mCommands = new FrameworkCommandCollection();
2930 }
3031
31-bool FrameworkListener::onDataAvailable(int socket) {
32+bool FrameworkListener::onDataAvailable(SocketClient *c) {
3233 char buffer[101];
3334 int len;
3435
35- if ((len = read(socket, buffer, sizeof(buffer) -1)) < 0) {
36+ if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) {
3637 LOGE("read() failed (%s)", strerror(errno));
3738 return errno;
3839 } else if (!len) {
@@ -47,7 +48,7 @@ bool FrameworkListener::onDataAvailable(int socket) {
4748
4849 for (i = 0; i < len; i++) {
4950 if (buffer[i] == '\0') {
50- dispatchCommand(buffer + start);
51+ dispatchCommand(c, buffer + start);
5152 start = i + 1;
5253 }
5354 }
@@ -58,14 +59,22 @@ void FrameworkListener::registerCmd(FrameworkCommand *cmd) {
5859 mCommands->push_back(cmd);
5960 }
6061
61-void FrameworkListener::dispatchCommand(char *cmd) {
62+void FrameworkListener::dispatchCommand(SocketClient *cli, char *cmd) {
63+
64+ char *cm, *last;
65+
66+ if (!(cm = strtok_r(cmd, ":", &last))) {
67+ cli->sendMsg("BAD_MSG");
68+ return;
69+ }
70+
6271 FrameworkCommandCollection::iterator i;
6372
6473 for (i = mCommands->begin(); i != mCommands->end(); ++i) {
6574 FrameworkCommand *c = *i;
6675
67- if (!strncmp(cmd, c->getCommand(), strlen(c->getCommand()))) {
68- if (c->runCommand(cmd)) {
76+ if (!strcmp(cm, c->getCommand())) {
77+ if (c->runCommand(cli, cmd)) {
6978 LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno));
7079 }
7180 return;
@@ -73,5 +82,6 @@ void FrameworkListener::dispatchCommand(char *cmd) {
7382 }
7483
7584 LOGE("No cmd handlers defined for '%s'", cmd);
85+ cli->sendMsg("UNKNOWN_CMD");
86+ return;
7687 }
77-
--- a/libsysutils/src/FrameworkManager.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
1-/*
2- * Copyright (C) 2008 The Android Open Source Project
3- *
4- * Licensed under the Apache License, Version 2.0 (the "License");
5- * you may not use this file except in compliance with the License.
6- * You may obtain a copy of the License at
7- *
8- * http://www.apache.org/licenses/LICENSE-2.0
9- *
10- * Unless required by applicable law or agreed to in writing, software
11- * distributed under the License is distributed on an "AS IS" BASIS,
12- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13- * See the License for the specific language governing permissions and
14- * limitations under the License.
15- */
16-#include <stdio.h>
17-#include <errno.h>
18-#include <stdlib.h>
19-#include <sys/socket.h>
20-#include <sys/select.h>
21-#include <sys/time.h>
22-#include <sys/types.h>
23-#include <sys/un.h>
24-
25-#include <cutils/config_utils.h>
26-#include <cutils/cpu_info.h>
27-#include <cutils/properties.h>
28-#include <cutils/sockets.h>
29-
30-#define LOG_TAG "FrameworkManager"
31-#include <cutils/log.h>
32-
33-#include <sysutils/FrameworkManager.h>
34-#include <sysutils/FrameworkListener.h>
35-
36-FrameworkManager::FrameworkManager(FrameworkListener *Listener) {
37- mDoorbell = -1;
38- mFwSock = -1;
39- mListener = Listener;
40-
41- pthread_mutex_init(&mWriteMutex, NULL);
42-}
43-
44-int FrameworkManager::run() {
45-
46- if (mListener->run()) {
47- LOGE("Error running listener (%s)", strerror(errno));
48- return -1;
49- }
50-
51- return 0;
52-}
53-
54-/* ========
55- * Privates
56- * ========
57- */
58-
59-int FrameworkManager::sendMsg(char *msg) {
60- LOGD("FrameworkManager::sendMsg(%s)", msg);
61- if (mFwSock < 0) {
62- errno = EHOSTUNREACH;
63- return -1;
64- }
65-
66- pthread_mutex_lock(&mWriteMutex);
67- if (write(mFwSock, msg, strlen(msg) +1) < 0) {
68- LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno));
69- }
70- pthread_mutex_unlock(&mWriteMutex);
71- return 0;
72-}
73-
74-int FrameworkManager::sendMsg(char *msg, char *data) {
75- char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1);
76- if (!buffer) {
77- errno = -ENOMEM;
78- return -1;
79- }
80- strcpy(buffer, msg);
81- strcat(buffer, data);
82- return sendMsg(buffer);
83-}
--- a/libsysutils/src/NetlinkListener.cpp
+++ b/libsysutils/src/NetlinkListener.cpp
@@ -29,8 +29,9 @@ NetlinkListener::NetlinkListener(int socket) :
2929 SocketListener(socket, false) {
3030 }
3131
32-bool NetlinkListener::onDataAvailable(int socket)
32+bool NetlinkListener::onDataAvailable(SocketClient *cli)
3333 {
34+ int socket = cli->getSocket();
3435 LOGD("NetlinkListener::onDataAvailable()");
3536
3637 int count;
--- /dev/null
+++ b/libsysutils/src/SocketClient.cpp
@@ -0,0 +1,41 @@
1+#include <alloca.h>
2+#include <errno.h>
3+#include <sys/types.h>
4+#include <pthread.h>
5+
6+#define LOG_TAG "SocketClient"
7+#include <cutils/log.h>
8+
9+#include <sysutils/SocketClient.h>
10+
11+SocketClient::SocketClient(int socket) {
12+ mSocket = socket;
13+ pthread_mutex_init(&mWriteMutex, NULL);
14+}
15+
16+int SocketClient::sendMsg(char *msg) {
17+ LOGD("SocketClient::sendMsg(%s)", msg);
18+ if (mSocket < 0) {
19+ errno = EHOSTUNREACH;
20+ return -1;
21+ }
22+
23+ pthread_mutex_lock(&mWriteMutex);
24+ if (write(mSocket, msg, strlen(msg) +1) < 0) {
25+ LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno));
26+ }
27+ pthread_mutex_unlock(&mWriteMutex);
28+ return 0;
29+}
30+
31+int SocketClient::sendMsg(char *msg, char *data) {
32+ char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1);
33+ if (!buffer) {
34+ errno = -ENOMEM;
35+ return -1;
36+ }
37+ strcpy(buffer, msg);
38+ strcat(buffer, data);
39+ return sendMsg(buffer);
40+}
41+
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -24,26 +24,28 @@
2424
2525 #define LOG_TAG "SocketListener"
2626 #include <cutils/log.h>
27-
2827 #include <cutils/sockets.h>
2928
3029 #include <sysutils/SocketListener.h>
30+#include <sysutils/SocketClient.h>
3131
32-SocketListener::SocketListener(const char *socketName, bool acceptClients) {
33- mAcceptClients = acceptClients;
34- mCsock = -1;
32+SocketListener::SocketListener(const char *socketName, bool listen) {
33+ mListen = listen;
3534 mSocketName = socketName;
3635 mSock = -1;
36+ pthread_mutex_init(&mClientsLock, NULL);
37+ mClients = new SocketClientCollection();
3738 }
3839
39-SocketListener::SocketListener(int socketFd, bool acceptClients) {
40- mAcceptClients = acceptClients;
41- mCsock = -1;
40+SocketListener::SocketListener(int socketFd, bool listen) {
41+ mListen = listen;
4242 mSocketName = NULL;
4343 mSock = socketFd;
44+ pthread_mutex_init(&mClientsLock, NULL);
45+ mClients = new SocketClientCollection();
4446 }
4547
46-int SocketListener::run() {
48+int SocketListener::startListener() {
4749
4850 if (!mSocketName && mSock == -1) {
4951 errno = EINVAL;
@@ -56,72 +58,155 @@ int SocketListener::run() {
5658 }
5759 }
5860
59- if (mAcceptClients) {
60- if (listen(mSock, 4) < 0) {
61- LOGE("Unable to listen on socket (%s)", strerror(errno));
62- return -1;
63- }
61+ if (mListen && listen(mSock, 4) < 0) {
62+ LOGE("Unable to listen on socket (%s)", strerror(errno));
63+ return -1;
64+ } else if (!mListen) {
65+ mClients->push_back(new SocketClient(mSock));
66+ LOGD("Created phantom client");
6467 }
6568
69+ if (pipe(mCtrlPipe))
70+ return -1;
71+
72+ if (pthread_create(&mThread, NULL, SocketListener::threadStart, this))
73+ return -1;
74+
75+ return 0;
76+}
77+
78+int SocketListener::stopListener() {
79+ char c = 0;
80+
81+ if (write(mCtrlPipe[1], &c, 1) != 1) {
82+ LOGE("Error writing to control pipe (%s)", strerror(errno));
83+ return -1;
84+ }
85+
86+ LOGD("Signaled listener thread - waiting for it to die");
87+ void *ret;
88+ if (pthread_join(mThread, &ret)) {
89+ LOGE("Error joining to listener thread (%s)", strerror(errno));
90+ return -1;
91+ }
92+ LOGD("Listener stopped");
93+ return 0;
94+}
95+
96+void *SocketListener::threadStart(void *obj) {
97+ SocketListener *me = reinterpret_cast<SocketListener *>(obj);
98+
99+ me->runListener();
100+ LOGD("Listener thread shutting down");
101+ pthread_exit(NULL);
102+ return NULL;
103+}
104+
105+void SocketListener::runListener() {
106+
66107 while(1) {
108+ SocketClientCollection::iterator it;
67109 fd_set read_fds;
68110 struct timeval to;
69- int max = 0;
70111 int rc = 0;
71112
72113 to.tv_sec = 60 * 60;
73114 to.tv_usec = 0;
74115
116+ int max = 0;
117+
75118 FD_ZERO(&read_fds);
76119
77- if ((mAcceptClients == false) ||
78- (mAcceptClients == true && mCsock == -1)) {
79- FD_SET(mSock, &read_fds);
120+ if (mListen) {
80121 max = mSock;
81- } else if (mCsock != -1) {
82- FD_SET(mCsock, &read_fds);
83- max = mCsock;
122+ FD_SET(mSock, &read_fds);
84123 }
85124
125+ FD_SET(mCtrlPipe[0], &read_fds);
126+ if (mCtrlPipe[0] > max)
127+ max = mCtrlPipe[0];
128+
129+ pthread_mutex_lock(&mClientsLock);
130+ for (it = mClients->begin(); it != mClients->end(); ++it) {
131+ FD_SET((*it)->getSocket(), &read_fds);
132+ if ((*it)->getSocket() > max)
133+ max = (*it)->getSocket();
134+ }
135+ pthread_mutex_unlock(&mClientsLock);
136+
86137 if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) {
87138 LOGE("select failed (%s)", strerror(errno));
88- return -errno;
89- } else if (!rc)
139+ sleep(1);
90140 continue;
91- else if (FD_ISSET(mSock, &read_fds)) {
92- /*
93- * If we're accepting client connections then
94- * accept and gobble the event. Otherwise
95- * pass it on to the handlers.
96- */
97- if (mAcceptClients) {
98- struct sockaddr addr;
99- socklen_t alen = sizeof(addr);
100-
101- if ((mCsock = accept(mSock, &addr, &alen)) < 0) {
102- LOGE("accept failed (%s)", strerror(errno));
103- return -errno;
104- }
105- LOGD("SocketListener client connection accepted");
106- } else if (!onDataAvailable(mSock)) {
107- LOGW("SocketListener closing listening socket (Will shut down)");
108- close(mSock);
109- return -ESHUTDOWN;
141+ } else if (!rc) {
142+ LOGD("select timeout");
143+ continue;
144+ }
145+
146+ if (FD_ISSET(mCtrlPipe[0], &read_fds)) {
147+ LOGD("Control message received");
148+ break;
149+ }
150+ if (mListen && FD_ISSET(mSock, &read_fds)) {
151+ struct sockaddr addr;
152+ socklen_t alen = sizeof(addr);
153+ int c;
154+
155+ if ((c = accept(mSock, &addr, &alen)) < 0) {
156+ LOGE("accept failed (%s)", strerror(errno));
157+ sleep(1);
158+ continue;
110159 }
111- } else if ((FD_ISSET(mCsock, &read_fds)) &&
112- !onDataAvailable(mCsock)) {
113- /*
114- * Once mCsock == -1, we'll start
115- * accepting connections on mSock again.
116- */
117- LOGD("SocketListener closing client socket");
118- close(mCsock);
119- mCsock = -1;
160+ LOGD("SocketListener client connection accepted");
161+ pthread_mutex_lock(&mClientsLock);
162+ mClients->push_back(new SocketClient(c));
163+ pthread_mutex_unlock(&mClientsLock);
164+ }
165+
166+ do {
167+ pthread_mutex_lock(&mClientsLock);
168+ for (it = mClients->begin(); it != mClients->end(); ++it) {
169+ int fd = (*it)->getSocket();
170+ if (FD_ISSET(fd, &read_fds)) {
171+ pthread_mutex_unlock(&mClientsLock);
172+ if (!onDataAvailable(*it)) {
173+ LOGD("SocketListener closing client socket");
174+ close(fd);
175+ pthread_mutex_lock(&mClientsLock);
176+ delete *it;
177+ it = mClients->erase(it);
178+ pthread_mutex_unlock(&mClientsLock);
179+ }
180+ FD_CLR(fd, &read_fds);
181+ continue;
182+ }
120183 }
184+ pthread_mutex_unlock(&mClientsLock);
185+ } while (0);
121186 }
122- return 0;
123187 }
124188
125-bool SocketListener::onDataAvailable(int socket) {
126- return false;
189+void SocketListener::sendBroadcast(char *msg) {
190+ pthread_mutex_lock(&mClientsLock);
191+ SocketClientCollection::iterator i;
192+
193+ for (i = mClients->begin(); i != mClients->end(); ++i) {
194+ if ((*i)->sendMsg(msg)) {
195+ LOGW("Error sending broadcast (%s)", strerror(errno));
196+ }
197+ }
198+ pthread_mutex_unlock(&mClientsLock);
199+}
200+
201+void SocketListener::sendBroadcast(char *msg, char *data) {
202+ pthread_mutex_lock(&mClientsLock);
203+ SocketClientCollection::iterator i;
204+
205+ for (i = mClients->begin(); i != mClients->end(); ++i) {
206+ if ((*i)->sendMsg(msg, data)) {
207+ LOGW("Error sending broadcast (%s)", strerror(errno));
208+ }
209+ }
210+ pthread_mutex_unlock(&mClientsLock);
127211 }
212+
--- a/nexus/Android.mk
+++ b/nexus/Android.mk
@@ -19,6 +19,7 @@ LOCAL_SRC_FILES:= \
1919 SupplicantListener.cpp \
2020 VpnController.cpp \
2121 ScanResult.cpp \
22+ WifiScanner.cpp \
2223
2324 LOCAL_MODULE:= nexus
2425
--- a/nexus/CommandListener.cpp
+++ b/nexus/CommandListener.cpp
@@ -19,60 +19,64 @@
1919 #define LOG_TAG "CommandListener"
2020 #include <cutils/log.h>
2121
22+#include <sysutils/SocketClient.h>
23+
2224 #include "CommandListener.h"
2325 #include "Controller.h"
2426 #include "NetworkManager.h"
2527 #include "WifiController.h"
2628
27-CommandListener::CommandListener(NetworkManager *netman) :
29+CommandListener::CommandListener() :
2830 FrameworkListener("nexus") {
29- mNetman = netman;
30-
31- registerCmd(new WifiEnableCmd(netman));
32- registerCmd(new WifiDisableCmd(netman));
33- registerCmd(new WifiScanCmd(netman));
31+ registerCmd(new WifiEnableCmd());
32+ registerCmd(new WifiDisableCmd());
33+ registerCmd(new WifiScanCmd());
34+ registerCmd(new WifiScanResultsCmd());
3435
35- registerCmd(new VpnEnableCmd(netman));
36- registerCmd(new VpnDisableCmd(netman));
36+ registerCmd(new VpnEnableCmd());
37+ registerCmd(new VpnDisableCmd());
3738 }
3839
3940 /* -------------
4041 * Wifi Commands
4142 * ------------ */
4243
43-CommandListener::WifiEnableCmd::WifiEnableCmd(NetworkManager *netman) :
44- NexusCommand("wifi_enable", netman) {
44+CommandListener::WifiEnableCmd::WifiEnableCmd() :
45+ NexusCommand("wifi_enable") {
4546 }
4647
47-int CommandListener::WifiEnableCmd::runCommand(char *data) {
48- Controller *c = mNetman->findController("WIFI");
48+int CommandListener::WifiEnableCmd::runCommand(SocketClient *cli, char *data) {
49+ Controller *c = NetworkManager::Instance()->findController("WIFI");
4950 char buffer[32];
5051
5152 sprintf(buffer, "WIFI_ENABLE:%d", (c->enable() ? errno : 0));
52- mNetman->getFrameworkManager()->sendMsg(buffer);
53+
54+ cli->sendMsg(buffer);
5355 return 0;
5456 }
5557
56-CommandListener::WifiDisableCmd::WifiDisableCmd(NetworkManager *netman) :
57- NexusCommand("wifi_disable", netman) {
58+CommandListener::WifiDisableCmd::WifiDisableCmd() :
59+ NexusCommand("wifi_disable") {
5860 }
5961
60-int CommandListener::WifiDisableCmd::runCommand(char *data) {
61- Controller *c = mNetman->findController("WIFI");
62+int CommandListener::WifiDisableCmd::runCommand(SocketClient *cli, char *data) {
63+ Controller *c = NetworkManager::Instance()->findController("WIFI");
6264 char buffer[32];
6365
6466 sprintf(buffer, "WIFI_DISABLE:%d", (c->disable() ? errno : 0));
65- mNetman->getFrameworkManager()->sendMsg(buffer);
67+ cli->sendMsg(buffer);
6668 return 0;
6769 }
6870
69-CommandListener::WifiScanCmd::WifiScanCmd(NetworkManager *netman) :
70- NexusCommand("wifi_scan", netman) {
71+CommandListener::WifiScanCmd::WifiScanCmd() :
72+ NexusCommand("wifi_scan") {
7173 }
7274
73-int CommandListener::WifiScanCmd::runCommand(char *data) {
75+int CommandListener::WifiScanCmd::runCommand(SocketClient *cli, char *data) {
7476 LOGD("WifiScanCmd(%s)", data);
75- WifiController *wc = (WifiController *) mNetman->findController("WIFI");
77+
78+ WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI");
79+
7680 char buffer[32];
7781 int mode = 0;
7882 char *bword, *last;
@@ -90,35 +94,62 @@ int CommandListener::WifiScanCmd::runCommand(char *data) {
9094 mode = atoi(bword);
9195
9296 sprintf(buffer, "WIFI_SCAN:%d", (wc->setScanMode(mode) ? errno : 0));
93- mNetman->getFrameworkManager()->sendMsg(buffer);
97+ cli->sendMsg(buffer);
98+ return 0;
99+}
100+
101+CommandListener::WifiScanResultsCmd::WifiScanResultsCmd() :
102+ NexusCommand("wifi_scan_results") {
103+}
104+
105+int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, char *data) {
106+ NetworkManager *nm = NetworkManager::Instance();
107+
108+ WifiController *wc = (WifiController *) nm->findController("WIFI");
109+
110+ ScanResultCollection *src = wc->createScanResults();
111+ ScanResultCollection::iterator it;
112+ char buffer[256];
113+
114+ for(it = src->begin(); it != src->end(); ++it) {
115+ sprintf(buffer, "WIFI_SCAN_RESULT:%s:%u:%d:%s:%s",
116+ (*it)->getBssid(), (*it)->getFreq(), (*it)->getLevel(),
117+ (*it)->getFlags(), (*it)->getSsid());
118+ cli->sendMsg(buffer);
119+ delete (*it);
120+ it = src->erase(it);
121+ }
122+
123+ delete src;
124+ cli->sendMsg("WIFI_SCAN_RESULT:0");
94125 return 0;
95126 }
96127
97128 /* ------------
98129 * Vpn Commands
99130 * ------------ */
100-CommandListener::VpnEnableCmd::VpnEnableCmd(NetworkManager *netman) :
101- NexusCommand("vpn_enable", netman) {
131+CommandListener::VpnEnableCmd::VpnEnableCmd() :
132+ NexusCommand("vpn_enable") {
102133 }
103134
104-int CommandListener::VpnEnableCmd::runCommand(char *data) {
105- Controller *c = mNetman->findController("VPN");
135+int CommandListener::VpnEnableCmd::runCommand(SocketClient *cli, char *data) {
136+ Controller *c = NetworkManager::Instance()->findController("VPN");
106137 char buffer[32];
107138
108139 sprintf(buffer, "VPN_ENABLE:%d", (c->enable() ? errno : 0));
109- mNetman->getFrameworkManager()->sendMsg(buffer);
140+ cli->sendMsg(buffer);
110141 return 0;
111142 }
112143
113-CommandListener::VpnDisableCmd::VpnDisableCmd(NetworkManager *netman) :
114- NexusCommand("vpn_disable", netman) {
144+CommandListener::VpnDisableCmd::VpnDisableCmd() :
145+ NexusCommand("vpn_disable") {
115146 }
116147
117-int CommandListener::VpnDisableCmd::runCommand(char *data) {
118- Controller *c = mNetman->findController("VPN");
148+int CommandListener::VpnDisableCmd::runCommand(SocketClient *cli, char *data) {
149+ Controller *c = NetworkManager::Instance()->findController("VPN");
119150 char buffer[32];
120151
121152 sprintf(buffer, "VPN_DISABLE:%d", (c->disable() ? errno : 0));
122- mNetman->getFrameworkManager()->sendMsg(buffer);
153+ cli->sendMsg(buffer);
123154 return 0;
124155 }
--- a/nexus/CommandListener.h
+++ b/nexus/CommandListener.h
@@ -19,50 +19,52 @@
1919 #include <sysutils/FrameworkListener.h>
2020 #include "NexusCommand.h"
2121
22-class NetworkManager;
23-
2422 class CommandListener : public FrameworkListener {
25-protected:
26- NetworkManager *mNetman;
27-
2823 public:
29- CommandListener(NetworkManager *netman);
24+ CommandListener();
3025 virtual ~CommandListener() {}
3126
3227 private:
3328 class WifiEnableCmd : public NexusCommand {
3429 public:
35- WifiEnableCmd(NetworkManager *);
30+ WifiEnableCmd();
3631 virtual ~WifiEnableCmd() {}
37- int runCommand(char *data);
32+ int runCommand(SocketClient *c, char *data);
3833 };
3934
4035 class WifiDisableCmd : public NexusCommand {
4136 public:
42- WifiDisableCmd(NetworkManager *);
37+ WifiDisableCmd();
4338 virtual ~WifiDisableCmd() {}
44- int runCommand(char *data);
39+ int runCommand(SocketClient *c, char *data);
4540 };
4641
4742 class WifiScanCmd : public NexusCommand {
4843 public:
49- WifiScanCmd(NetworkManager *);
44+ WifiScanCmd();
5045 virtual ~WifiScanCmd() {}
51- int runCommand(char *data);
46+ int runCommand(SocketClient *c, char *data);
47+ };
48+
49+ class WifiScanResultsCmd : public NexusCommand {
50+ public:
51+ WifiScanResultsCmd();
52+ virtual ~WifiScanResultsCmd() {}
53+ int runCommand(SocketClient *c, char *data);
5254 };
5355
5456 class VpnEnableCmd : public NexusCommand {
5557 public:
56- VpnEnableCmd(NetworkManager *);
58+ VpnEnableCmd();
5759 virtual ~VpnEnableCmd() {}
58- int runCommand(char *data);
60+ int runCommand(SocketClient *c, char *data);
5961 };
6062
6163 class VpnDisableCmd : public NexusCommand {
6264 public:
63- VpnDisableCmd(NetworkManager *);
65+ VpnDisableCmd();
6466 virtual ~VpnDisableCmd() {}
65- int runCommand(char *data);
67+ int runCommand(SocketClient *c, char *data);
6668 };
6769
6870 };
--- a/nexus/NetworkManager.cpp
+++ b/nexus/NetworkManager.cpp
@@ -21,36 +21,30 @@
2121 #include <cutils/log.h>
2222
2323 #include "NetworkManager.h"
24-#include "CommandListener.h"
25-#include "LoopController.h"
26-#include "VpnController.h"
2724
28-#include "TiwlanWifiController.h"
25+NetworkManager *NetworkManager::sInstance = NULL;
26+
27+NetworkManager *NetworkManager::Instance() {
28+ if (!sInstance)
29+ sInstance = new NetworkManager();
30+ return sInstance;
31+}
2932
3033 NetworkManager::NetworkManager() {
31- mListener = new CommandListener(this);
32- mFm = new FrameworkManager(mListener);
34+ mBroadcaster = NULL;
3335 mControllers = new ControllerCollection();
3436 }
3537
3638 int NetworkManager::run() {
37- LOGD("NetworkManager::start()");
38-
39- // XXX: Factory needed
40- addController(new LoopController());
41- addController(new TiwlanWifiController("/system/lib/modules/wlan.ko", "wlan", ""));
42- addController(new VpnController());
43- //addController(new GenericController("rmnet0"));
44-
4539 if (startControllers()) {
4640 LOGW("Unable to start all controllers (%s)", strerror(errno));
4741 }
48- mFm->run();
4942 return 0;
5043 }
5144
52-void NetworkManager::addController(Controller *c) {
45+int NetworkManager::attachController(Controller *c) {
5346 mControllers->push_back(c);
47+ return 0;
5448 }
5549
5650 int NetworkManager::startControllers() {
--- a/nexus/NetworkManager.h
+++ b/nexus/NetworkManager.h
@@ -16,31 +16,36 @@
1616 #ifndef _NETWORKMANAGER_H
1717 #define _NETWORKMANAGER_H
1818
19-#include "Controller.h"
19+#include <sysutils/SocketListener.h>
2020
21-#include <sysutils/FrameworkManager.h>
21+#include "Controller.h"
2222
2323 class NetworkManager {
2424 private:
25- FrameworkListener *mListener;
26- FrameworkManager *mFm;
25+ static NetworkManager *sInstance;
26+
27+private:
2728 ControllerCollection *mControllers;
29+ SocketListener *mBroadcaster;
2830
2931 public:
30- NetworkManager();
3132 virtual ~NetworkManager() {}
3233
3334 int run();
3435
36+ int attachController(Controller *controller);
37+
38+ Controller *findController(const char *name);
39+
40+ void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
41+ SocketListener *getBroadcaster() { return mBroadcaster; }
42+
43+ static NetworkManager *Instance();
44+
3545 private:
36- void addController(Controller *c);
3746 int startControllers();
3847 int stopControllers();
39-
40-public:
41- Controller *findController(const char *name);
42- ControllerCollection *getControllers() { return mControllers; }
43- FrameworkManager *getFrameworkManager() { return mFm; }
48+ NetworkManager();
4449
4550 public:
4651 // XXX: Extract these into an interface
--- a/nexus/NexusCommand.cpp
+++ b/nexus/NexusCommand.cpp
@@ -15,7 +15,6 @@
1515 */
1616 #include "NexusCommand.h"
1717
18-NexusCommand::NexusCommand(const char *cmd, NetworkManager *netman) :
18+NexusCommand::NexusCommand(const char *cmd) :
1919 FrameworkCommand(cmd) {
20- mNetman = netman;
2120 }
--- a/nexus/NexusCommand.h
+++ b/nexus/NexusCommand.h
@@ -18,14 +18,9 @@
1818
1919 #include <sysutils/FrameworkCommand.h>
2020
21-class NetworkManager;
22-
2321 class NexusCommand : public FrameworkCommand {
24-protected:
25- NetworkManager *mNetman;
26-
2722 public:
28- NexusCommand(const char *cmd, NetworkManager *netman);
23+ NexusCommand(const char *cmd);
2924 virtual ~NexusCommand() {}
3025 };
3126
--- a/nexus/ScanResult.h
+++ b/nexus/ScanResult.h
@@ -38,6 +38,7 @@ public:
3838
3939 const char *getBssid() { return mBssid; }
4040 uint32_t getFreq() { return mFreq; }
41+ int getLevel() { return mLevel; }
4142 const char *getFlags() { return mFlags; }
4243 const char *getSsid() { return mSsid; }
4344 };
--- a/nexus/Supplicant.cpp
+++ b/nexus/Supplicant.cpp
@@ -13,6 +13,8 @@
1313 * See the License for the specific language governing permissions and
1414 * limitations under the License.
1515 */
16+
17+#include <stdlib.h>
1618 #include <errno.h>
1719
1820 #define LOG_TAG "Supplicant"
@@ -31,6 +33,7 @@
3133 #include "SupplicantState.h"
3234 #include "SupplicantEvent.h"
3335 #include "ScanResult.h"
36+#include "NetworkManager.h"
3437
3538 #include "libwpa_client/wpa_ctrl.h"
3639
@@ -52,7 +55,6 @@ Supplicant::Supplicant() {
5255 }
5356
5457 int Supplicant::start() {
55- LOGD("start():");
5658 // XXX: Validate supplicant config file
5759
5860 char status[PROPERTY_VALUE_MAX] = {'\0'};
@@ -63,47 +65,47 @@ int Supplicant::start() {
6365 #endif
6466
6567 if (property_get(SUPP_PROP_NAME, status, NULL) &&
66- strcmp(status, "running") == 0) {
67- return 0;
68- }
69-
70- wpa_ctrl_cleanup();
68+ !strcmp(status, "running")) {
69+ LOGD("Supplicant already started");
70+ } else {
7171 #ifdef HAVE_LIBC_SYSTEM_PROPERTIES
72- pi = __system_property_find(SUPP_PROP_NAME);
73- if (pi != NULL)
74- serial = pi->serial;
72+ pi = __system_property_find(SUPP_PROP_NAME);
73+ if (pi != NULL)
74+ serial = pi->serial;
7575 #endif
7676
77- property_set("ctl.start", SUPPLICANT_NAME);
78- sched_yield();
79- while (count--) {
77+ LOGD("Starting Supplicant");
78+ property_set("ctl.start", SUPPLICANT_NAME);
79+ sched_yield();
80+ while (count--) {
8081 #ifdef HAVE_LIBC_SYSTEM_PROPERTIES
81- if (!pi)
82- pi = __system_property_find(SUPP_PROP_NAME);
83- if (pi) {
84- __system_property_read(pi, NULL, status);
85- if (strcmp(status, "running") == 0)
86- return 0;
87- else if (pi->serial != serial &&
88- strcmp(status, "stopped") == 0) {
89- errno = EIO;
90- return -1;
82+ if (!pi)
83+ pi = __system_property_find(SUPP_PROP_NAME);
84+ if (pi) {
85+ __system_property_read(pi, NULL, status);
86+ if (strcmp(status, "running") == 0)
87+ break;
88+ else if (pi->serial != serial &&
89+ strcmp(status, "stopped") == 0) {
90+ errno = EIO;
91+ return -1;
92+ }
9193 }
92- }
9394 #else
94- if (property_get(SUPP_PROP_NAME, status, NULL)) {
95- if (strcmp(status, "running") == 0)
96- break;
97- }
95+ if (property_get(SUPP_PROP_NAME, status, NULL)) {
96+ if (strcmp(status, "running") == 0)
97+ break;
98+ }
9899 #endif
99- usleep(100000);
100+ usleep(100000);
101+ }
102+ if (!count) {
103+ errno = ETIMEDOUT;
104+ return -1;
105+ }
100106 }
101107
102- if (!count) {
103- errno = ETIMEDOUT;
104- return -1;
105- }
106-
108+ wpa_ctrl_cleanup();
107109 if (connectToSupplicant()) {
108110 LOGE("Error connecting to supplicant (%s)\n", strerror(errno));
109111 return -1;
@@ -112,7 +114,6 @@ int Supplicant::start() {
112114 }
113115
114116 int Supplicant::stop() {
115- LOGD("stop()");
116117
117118 char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
118119 int count = 50;
@@ -124,9 +125,11 @@ int Supplicant::stop() {
124125
125126 if (property_get(SUPP_PROP_NAME, supp_status, NULL)
126127 && strcmp(supp_status, "stopped") == 0) {
128+ LOGD("Supplicant already stopped");
127129 return 0;
128130 }
129131
132+ LOGD("Stopping Supplicant");
130133 property_set("ctl.stop", SUPPLICANT_NAME);
131134 sched_yield();
132135
@@ -153,24 +156,29 @@ int Supplicant::stop() {
153156 return -1;
154157 }
155158
156- LOGD("Stopped OK");
159+ LOGD("Supplicant shutdown");
157160
158161 return 0;
159162 }
160163
161164 bool Supplicant::isStarted() {
162165 char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
163- if (!property_get(SUPP_PROP_NAME, supp_status, NULL) ||
164- !strcmp(supp_status, "running")) {
165- return false;
166- }
167- return true;
166+
167+ int rc = property_get(SUPP_PROP_NAME, supp_status, NULL);
168+
169+ LOGD("rc = %d, property = '%s'", rc, supp_status);
170+
171+ if (!strcmp(supp_status, "running"))
172+ return true;
173+
174+ return false;
168175 }
169176
170177 int Supplicant::connectToSupplicant() {
171178 char ifname[256];
172179 char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
173180
181+ LOGD("connectToSupplicant()");
174182 if (!property_get(SUPP_PROP_NAME, supp_status, NULL)
175183 || strcmp(supp_status, "running") != 0) {
176184 LOGE("Supplicant not running, cannot connect");
@@ -213,13 +221,14 @@ int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len)
213221 return -1;
214222 }
215223
216- LOGD("sendCommand(): -> '%s'", cmd);
224+// LOGD("sendCommand(): -> '%s'", cmd);
217225
218226 int rc;
219227 if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) {
220228 errno = ETIMEDOUT;
221229 return -1;
222230 } else if (rc < 0 || !strncmp(reply, "FAIL", 4)) {
231+ LOGW("sendCommand(): <- '%s'", reply);
223232 errno = EIO;
224233 return -1;
225234 }
@@ -228,7 +237,7 @@ int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len)
228237 !strncmp(cmd, "SCAN_RESULTS", 12))
229238 reply[*reply_len] = '\0';
230239
231- LOGD("sendCommand(): <- '%s'", reply);
240+// LOGD("sendCommand(): <- '%s'", reply);
232241 return 0;
233242 }
234243
@@ -332,12 +341,16 @@ int Supplicant::onScanResultsEvent(SupplicantEvent *evt) {
332341
333342 if (!strtok_r(reply, "\n", &linep_next)) {
334343 free(reply);
335- return 0;;
344+ pthread_mutex_unlock(&mLatestScanResultsLock);
345+ return 0;
336346 }
337347
338348 while((linep = strtok_r(NULL, "\n", &linep_next)))
339349 mLatestScanResults->push_back(new ScanResult(linep));
340-
350+
351+ char tmp[32];
352+ sprintf(tmp, "WIFI_SCAN_RESULTS_READY:%d", mLatestScanResults->size());
353+ NetworkManager::Instance()->getBroadcaster()->sendBroadcast(tmp);
341354 pthread_mutex_unlock(&mLatestScanResultsLock);
342355 free(reply);
343356 } else {
@@ -347,8 +360,24 @@ int Supplicant::onScanResultsEvent(SupplicantEvent *evt) {
347360 }
348361
349362 int Supplicant::onStateChangeEvent(SupplicantEvent *evt) {
350- LOGD("onStateChangeEvent(%s)", evt->getEvent());
351- // XXX: Update mState
363+ char *bword, *last;
364+ char *tmp = strdup(evt->getEvent());
365+
366+ if (!(bword = strtok_r(tmp, " ", &last))) {
367+ LOGE("Malformatted state update (%s)", evt->getEvent());
368+ free(tmp);
369+ return 0;
370+ }
371+
372+ if (!(bword = strtok_r(NULL, " ", &last))) {
373+ LOGE("Malformatted state update (%s)", evt->getEvent());
374+ free(tmp);
375+ return 0;
376+ }
377+
378+ mState = atoi(&bword[strlen("state=")]);
379+ LOGD("State changed to %d", mState);
380+ free(tmp);
352381 return 0;
353382 }
354383
@@ -363,7 +392,7 @@ int Supplicant::onDriverStateEvent(SupplicantEvent *evt) {
363392 }
364393
365394 // XXX: Use a cursor + smartptr instead
366-const ScanResultCollection *Supplicant::getLatestScanResults() {
395+ScanResultCollection *Supplicant::createLatestScanResults() {
367396 ScanResultCollection *d = new ScanResultCollection();
368397 ScanResultCollection::iterator i;
369398
--- a/nexus/Supplicant.h
+++ b/nexus/Supplicant.h
@@ -46,7 +46,7 @@ public:
4646
4747 int getState() { return mState; }
4848
49- const ScanResultCollection *getLatestScanResults();
49+ ScanResultCollection *createLatestScanResults();
5050
5151 // XXX: Extract these into an interface
5252 public:
--- a/nexus/SupplicantListener.cpp
+++ b/nexus/SupplicantListener.cpp
@@ -30,31 +30,9 @@ SupplicantListener::SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *
3030 SocketListener(wpa_ctrl_get_fd(monitor), false) {
3131 mSupplicant = supplicant;
3232 mMonitor = monitor;
33- mThread = NULL;
3433 }
3534
36-int SupplicantListener::startListener() {
37- LOGD("startListener()");
38- pthread_attr_t attr;
39- pthread_attr_init(&attr);
40- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
41-
42- return pthread_create(&mThread, &attr, &SupplicantListener::threadStart, this);
43-}
44-
45-int SupplicantListener::stopListener() {
46- errno = -ENOSYS;
47- return -1;
48-}
49-
50-void *SupplicantListener::threadStart(void *obj) {
51- LOGD("threadStart(): Worker thread started");
52- reinterpret_cast<SupplicantListener *>(obj)->run();
53- LOGD("threadStart(): Worker thread exited");
54- return NULL;
55-}
56-
57-bool SupplicantListener::onDataAvailable(int socket) {
35+bool SupplicantListener::onDataAvailable(SocketClient *cli) {
5836 char buf[255];
5937 size_t buflen = sizeof(buf);
6038 int rc;
@@ -62,7 +40,7 @@ bool SupplicantListener::onDataAvailable(int socket) {
6240
6341 if ((rc = wpa_ctrl_recv(mMonitor, buf, &nread))) {
6442 LOGE("wpa_ctrl_recv failed (%s)", strerror(errno));
65- return -errno;
43+ return false;
6644 }
6745
6846 buf[nread] = '\0';
@@ -108,7 +86,9 @@ bool SupplicantListener::onDataAvailable(int socket) {
10886
10987 delete evt;
11088
111- if (rc)
89+ if (rc) {
90+ LOGW("Handler %d (%s) error: %s", evt->getType(), evt->getEvent(), strerror(errno));
11291 return false;
92+ }
11393 return true;
11494 }
--- a/nexus/SupplicantListener.h
+++ b/nexus/SupplicantListener.h
@@ -16,33 +16,27 @@
1616 #ifndef _SUPPLICANTLISTENER_H__
1717 #define _SUPPLICANTLISTENER_H__
1818
19-#include <pthread.h>
20-
2119 #include <sysutils/SocketListener.h>
2220
2321 struct wpa_ctrl;
2422 class Supplicant;
23+class SocketClient;
2524
2625 class SupplicantListener: public SocketListener {
2726 private:
2827 struct wpa_ctrl *mMonitor;
2928 Supplicant *mSupplicant;
30- pthread_t mThread;
3129
3230 public:
3331 SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *monitor);
3432 virtual ~SupplicantListener() {}
35- int startListener();
36- int stopListener();
3733
3834 struct wpa_ctrl *getMonitor() { return mMonitor; }
3935 Supplicant *getSupplicant() { return mSupplicant; }
4036
4137 protected:
42- virtual bool onDataAvailable(int socket);
38+ virtual bool onDataAvailable(SocketClient *c);
4339
44-private:
45- static void *threadStart(void *obj);
4640 };
4741
4842 #endif
--- a/nexus/SupplicantState.h
+++ b/nexus/SupplicantState.h
@@ -18,16 +18,16 @@
1818
1919 class SupplicantState {
2020 public:
21- static const int UNKNOWN = 0;
22- static const int DISCONNECTED = 1;
23- static const int INACTIVE = 2;
24- static const int SCANNING = 3;
25- static const int ASSOCIATING = 4;
26- static const int ASSOCIATED = 5;
27- static const int FOURWAY_HANDSHAKE = 6;
28- static const int GROUP_HANDSHAKE = 7;
29- static const int COMPLETED = 8;
30- static const int IDLE = 9;
21+ static const int UNKNOWN = -1;
22+ static const int DISCONNECTED = 0;
23+ static const int INACTIVE = 1;
24+ static const int SCANNING = 2;
25+ static const int ASSOCIATING = 3;
26+ static const int ASSOCIATED = 4;
27+ static const int FOURWAY_HANDSHAKE = 5;
28+ static const int GROUP_HANDSHAKE = 6;
29+ static const int COMPLETED = 7;
30+ static const int IDLE = 8;
3131 };
3232
3333 #endif
--- a/nexus/TiwlanWifiController.cpp
+++ b/nexus/TiwlanWifiController.cpp
@@ -65,3 +65,17 @@ int TiwlanWifiController::loadFirmware() {
6565 property_set(DRIVER_PROP_NAME, "timeout");
6666 return -1;
6767 }
68+
69+bool TiwlanWifiController::isFirmwareLoaded() {
70+ char driver_status[PROPERTY_VALUE_MAX];
71+ if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
72+ if (!strcmp(driver_status, "ok"))
73+ return true;
74+ else {
75+ LOGD("Driver status '%s'", driver_status);
76+ return false;
77+ }
78+ }
79+ LOGW("Unable to get property '%s'", DRIVER_PROP_NAME);
80+ return false;
81+}
--- a/nexus/TiwlanWifiController.h
+++ b/nexus/TiwlanWifiController.h
@@ -27,5 +27,6 @@ public:
2727 virtual int powerDown();
2828 virtual bool isPoweredUp();
2929 virtual int loadFirmware();
30+ virtual bool isFirmwareLoaded();
3031 };
3132 #endif
--- a/nexus/WifiController.cpp
+++ b/nexus/WifiController.cpp
@@ -21,6 +21,8 @@
2121
2222 #include "Supplicant.h"
2323 #include "WifiController.h"
24+#include "WifiScanner.h"
25+#include "NetworkManager.h"
2426
2527 WifiController::WifiController(char *modpath, char *modname, char *modargs) :
2628 Controller("WIFI") {
@@ -29,6 +31,7 @@ WifiController::WifiController(char *modpath, char *modname, char *modargs) :
2931 strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
3032
3133 mSupplicant = new Supplicant();
34+ mScanner = new WifiScanner(mSupplicant, 10);
3235 mCurrentScanMode = 0;
3336 }
3437
@@ -42,26 +45,36 @@ int WifiController::stop() {
4245 }
4346
4447 int WifiController::enable() {
45- if (!isPoweredUp() && powerUp()) {
46- LOGE("Powerup failed (%s)", strerror(errno));
47- return -1;
48+ if (!isPoweredUp()) {
49+ sendStatusBroadcast("POWERING_UP");
50+ if (powerUp()) {
51+ LOGE("Powerup failed (%s)", strerror(errno));
52+ return -1;
53+ }
4854 }
49-
55+
5056 if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
57+ sendStatusBroadcast("LOADING_DRIVER");
5158 if (loadKernelModule(mModulePath, mModuleArgs)) {
5259 LOGE("Kernel module load failed (%s)", strerror(errno));
5360 goto out_powerdown;
5461 }
5562 }
5663
57- if (loadFirmware()) {
58- LOGE("Firmware load failed (%s)", strerror(errno));
59- goto out_powerdown;
64+ if (!isFirmwareLoaded()) {
65+ sendStatusBroadcast("LOADING_FIRMWARE");
66+ if (loadFirmware()) {
67+ LOGE("Firmware load failed (%s)", strerror(errno));
68+ goto out_powerdown;
69+ }
6070 }
6171
62- if (!mSupplicant->isStarted() && mSupplicant->start()) {
63- LOGE("Supplicant start failed (%s)", strerror(errno));
64- goto out_unloadmodule;
72+ if (!mSupplicant->isStarted()) {
73+ sendStatusBroadcast("STARTING_SUPPLICANT");
74+ if (mSupplicant->start()) {
75+ LOGE("Supplicant start failed (%s)", strerror(errno));
76+ goto out_unloadmodule;
77+ }
6578 }
6679
6780 return 0;
@@ -80,24 +93,38 @@ out_powerdown:
8093 return -1;
8194 }
8295
96+void WifiController::sendStatusBroadcast(const char *msg) {
97+ char tmp[255];
98+
99+ sprintf(tmp, "WIFI_STATUS:%s", msg);
100+ NetworkManager::Instance()->getBroadcaster()->sendBroadcast(tmp);
101+}
102+
83103 int WifiController::disable() {
84- LOGD("disable()");
85104
86- if (mSupplicant->isStarted() && mSupplicant->stop()) {
87- LOGE("Supplicant stop failed (%s)", strerror(errno));
88- return -1;
89- }
105+ if (mSupplicant->isStarted()) {
106+ sendStatusBroadcast("STOPPING_SUPPLICANT");
107+ if (mSupplicant->stop()) {
108+ LOGE("Supplicant stop failed (%s)", strerror(errno));
109+ return -1;
110+ }
111+ } else
112+ LOGW("disable(): Supplicant not running?");
90113
91114 if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
115+ sendStatusBroadcast("UNLOADING_DRIVER");
92116 if (unloadKernelModule(mModuleName)) {
93117 LOGE("Unable to unload module (%s)", strerror(errno));
94118 return -1;
95119 }
96120 }
97121
98- if (isPoweredUp() && powerDown()) {
99- LOGE("Powerdown failed (%s)", strerror(errno));
100- return -1;
122+ if (isPoweredUp()) {
123+ sendStatusBroadcast("POWERING_DOWN");
124+ if (powerDown()) {
125+ LOGE("Powerdown failed (%s)", strerror(errno));
126+ return -1;
127+ }
101128 }
102129 return 0;
103130 }
@@ -106,7 +133,7 @@ int WifiController::loadFirmware() {
106133 return 0;
107134 }
108135
109-int WifiController::setScanMode(int mode) {
136+int WifiController::setScanMode(uint32_t mode) {
110137 int rc = 0;
111138
112139 if (mCurrentScanMode == mode)
@@ -114,21 +141,15 @@ int WifiController::setScanMode(int mode) {
114141
115142 if (!(mode & SCAN_ENABLE_MASK)) {
116143 if (mCurrentScanMode & SCAN_REPEAT_MASK)
117- stopPeriodicScan();
144+ mScanner->stopPeriodicScan();
118145 } else if (mode & SCAN_REPEAT_MASK)
119- rc = startPeriodicScan();
146+ rc = mScanner->startPeriodicScan(mode & SCAN_ACTIVE_MASK);
120147 else
121148 rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
122149
123150 return rc;
124151 }
125152
126-int WifiController::startPeriodicScan() {
127- errno = -ENOSYS;
128- return -1;
129-}
130-
131-int WifiController::stopPeriodicScan() {
132- errno = -ENOSYS;
133- return -1;
153+ScanResultCollection *WifiController::createScanResults() {
154+ return mSupplicant->createLatestScanResults();
134155 }
--- a/nexus/WifiController.h
+++ b/nexus/WifiController.h
@@ -22,6 +22,9 @@
2222
2323 class NetInterface;
2424 class Supplicant;
25+class WifiScanner;
26+
27+#include "ScanResult.h"
2528
2629 class WifiController : public Controller {
2730 public:
@@ -40,8 +43,8 @@ private:
4043 char mModulePath[255];
4144 char mModuleName[64];
4245 char mModuleArgs[255];
43- int mCurrentScanMode;
44-
46+ uint32_t mCurrentScanMode;
47+ WifiScanner *mScanner;
4548
4649 public:
4750 WifiController(char *modpath, char *modname, char *modargs);
@@ -53,6 +56,8 @@ public:
5356 int enable();
5457 int disable();
5558
59+ ScanResultCollection *createScanResults();
60+
5661 int getType();
5762
5863 char *getModulePath() { return mModulePath; }
@@ -62,17 +67,17 @@ public:
6267 Supplicant *getSupplicant() { return mSupplicant; }
6368
6469 int getScanMode() { return mCurrentScanMode; }
65- int setScanMode(int mode);
70+ int setScanMode(uint32_t mode);
6671
6772 protected:
6873 virtual int powerUp() = 0;
6974 virtual int powerDown() = 0;
7075 virtual int loadFirmware();
76+
77+ virtual bool isFirmwareLoaded() = 0;
7178 virtual bool isPoweredUp() = 0;
7279
73-private:
74- int startPeriodicScan();
75- int stopPeriodicScan();
80+ void sendStatusBroadcast(const char *msg);
7681 };
7782
7883 #endif
--- /dev/null
+++ b/nexus/WifiScanner.cpp
@@ -0,0 +1,96 @@
1+#include <errno.h>
2+#include <pthread.h>
3+
4+#define LOG_TAG "WifiScanner"
5+#include <cutils/log.h>
6+
7+#include "WifiScanner.h"
8+#include "Supplicant.h"
9+
10+extern "C" int pthread_cancel(pthread_t thread);
11+
12+WifiScanner::WifiScanner(Supplicant *suppl, int period) {
13+ mSuppl = suppl;
14+ mPeriod = period;
15+ mActive = false;
16+ mWorkerRunning = false;
17+ mAbortRequest = false;
18+ pthread_mutex_init(&mAbortRequestLock, NULL);
19+ pthread_mutex_init(&mWorkerLock, NULL);
20+}
21+
22+int WifiScanner::startPeriodicScan(bool active) {
23+ mActive = active;
24+
25+ pthread_mutex_lock(&mWorkerLock);
26+ if (mWorkerRunning) {
27+ errno = EBUSY;
28+ return -1;
29+ }
30+
31+ pthread_attr_t attr;
32+ pthread_attr_init(&attr);
33+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
34+
35+ if (pthread_create(&mWorker, &attr, WifiScanner::threadStart, this))
36+ return -1;
37+
38+ return 0;
39+}
40+
41+void *WifiScanner::threadStart(void *obj) {
42+ WifiScanner *me = reinterpret_cast<WifiScanner *>(obj);
43+ me->run();
44+ pthread_exit(NULL);
45+ return NULL;
46+}
47+
48+void WifiScanner::threadCleanup(void *obj) {
49+ WifiScanner *me = reinterpret_cast<WifiScanner *>(obj);
50+
51+ me->mWorkerRunning = false;
52+ pthread_mutex_unlock(&me->mWorkerLock);
53+
54+ if (me->mAbortRequest) {
55+ me->mAbortRequest = false;
56+ pthread_mutex_unlock(&me->mAbortRequestLock);
57+ }
58+}
59+
60+int WifiScanner::stopPeriodicScan() {
61+ pthread_mutex_lock(&mAbortRequestLock);
62+ pthread_mutex_lock(&mWorkerLock);
63+ if (mWorkerRunning)
64+ mAbortRequest = true;
65+ pthread_mutex_unlock(&mWorkerLock);
66+ pthread_mutex_unlock(&mAbortRequestLock);
67+
68+ return 0;
69+}
70+
71+void WifiScanner::run() {
72+ LOGD("Thread started");
73+
74+ mWorkerRunning = true;
75+ pthread_cleanup_push(WifiScanner::threadCleanup, this);
76+ pthread_mutex_unlock(&mWorkerLock);
77+
78+ while(1) {
79+ LOGD("Triggering periodic scan");
80+ if (mSuppl->triggerScan(mActive)) {
81+ LOGW("Error triggering scan (%s)", strerror(errno));
82+ }
83+
84+ sleep(mPeriod);
85+ pthread_mutex_lock(&mAbortRequestLock);
86+ if (mAbortRequest) {
87+ LOGD("Abort request!");
88+ goto out;
89+ }
90+ pthread_mutex_unlock(&mAbortRequestLock);
91+ }
92+
93+out:
94+ pthread_cleanup_pop(1);
95+ pthread_mutex_unlock(&mWorkerLock);
96+}
--- /dev/null
+++ b/nexus/WifiScanner.h
@@ -0,0 +1,36 @@
1+#ifndef _WIFISCANNER_H
2+#define _WIFISCANNER_H
3+
4+#include <pthread.h>
5+
6+class Supplicant;
7+
8+class WifiScanner {
9+ pthread_t mWorker;
10+ pthread_mutex_t mWorkerLock;
11+ bool mWorkerRunning;
12+ bool mAbortRequest;
13+ pthread_mutex_t mAbortRequestLock;
14+
15+ Supplicant *mSuppl;
16+ int mPeriod;
17+ bool mActive;
18+
19+
20+public:
21+ WifiScanner(Supplicant *suppl, int period);
22+ virtual ~WifiScanner() {}
23+
24+ int getPeriod() { return mPeriod; }
25+
26+ int startPeriodicScan(bool active);
27+ int stopPeriodicScan();
28+
29+private:
30+ static void *threadStart(void *obj);
31+ static void threadCleanup(void *obj);
32+
33+ void run();
34+};
35+
36+#endif
--- a/nexus/main.cpp
+++ b/nexus/main.cpp
@@ -20,22 +20,44 @@
2020
2121 #include "cutils/log.h"
2222 #include "NetworkManager.h"
23+#include "CommandListener.h"
2324
24-int main() {
25- NetworkManager *nm;
25+#include "LoopController.h"
26+#include "VpnController.h"
27+#include "TiwlanWifiController.h"
2628
29+int main() {
2730 LOGI("Nexus version 0.1 firing up");
2831
29- if (!(nm = new NetworkManager())) {
32+ CommandListener *cl = new CommandListener();
33+
34+ NetworkManager *nm;
35+ if (!(nm = NetworkManager::Instance())) {
3036 LOGE("Unable to create NetworkManager");
3137 exit (-1);
3238 };
3339
34- if (nm->run()) {
40+ nm->setBroadcaster((SocketListener *) cl);
41+
42+ nm->attachController(new LoopController());
43+ nm->attachController(new TiwlanWifiController("/system/lib/modules/wlan.ko", "wlan", ""));
44+ nm->attachController(new VpnController());
45+
46+
47+ if (NetworkManager::Instance()->run()) {
3548 LOGE("Unable to Run NetworkManager (%s)", strerror(errno));
3649 exit (1);
3750 }
3851
52+ if (cl->startListener()) {
53+ LOGE("Unable to start CommandListener (%s)", strerror(errno));
54+ exit (1);
55+ }
56+
57+ while(1) {
58+ sleep(1000);
59+ }
60+
3961 LOGI("Nexus exiting");
4062 exit(0);
4163 }
--- a/nexus/nexctl.c
+++ b/nexus/nexctl.c
@@ -65,14 +65,13 @@ int main(int argc, char **argv) {
6565
6666 buffer[strlen(buffer) -1] = 0;
6767
68- printf("sending '%s'\n", buffer);
6968 if (write(sock, buffer, strlen(buffer) +1) < 0) {
7069 fprintf(stderr, "Error writing data (%s)\n", strerror(errno));
7170 exit(2);
7271 }
7372
7473 wait:
75- to.tv_sec = 5;
74+ to.tv_sec = 10;
7675 to.tv_usec = 0;
7776 FD_ZERO(&read_fds);
7877 FD_SET(sock, &read_fds);
@@ -88,12 +87,11 @@ wait:
8887 printf("{response timeout}\n");
8988 continue;
9089 } else if (FD_ISSET(sock, &read_fds)) {
91-printf("got data!\n");
92- if ((rc = read(sock, buffer, sizeof(buffer)-1)) < 0) {
90+ if ((rc = read(sock, buffer, sizeof(buffer)-1)) <= 0) {
9391 fprintf(stderr, "Error reading response (%s)\n", strerror(errno));
9492 exit(2);
9593 }
96- printf(" |%s|\n", buffer);
94+ printf(" %s\n", buffer);
9795 goto wait;
9896 }
9997 }