system/corennnnn
Revisión | e1156972e157e969fa9a9efd7c04d02061f090a2 (tree) |
---|---|
Tiempo | 2009-05-12 01:03:29 |
Autor | Android (Google) Code Review <android-gerrit@goog...> |
Commiter | The Android Open Source Project |
am c73d9e4: Merge changes 1341,1342 into donut
Merge commit 'c73d9e43a0c98a87222ef0c8749d6abba06c7778'
* commit 'c73d9e43a0c98a87222ef0c8749d6abba06c7778':
@@ -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 |
@@ -18,6 +18,7 @@ | ||
18 | 18 | |
19 | 19 | #include "../../../frameworks/base/include/utils/List.h" |
20 | 20 | |
21 | +class SocketClient; | |
21 | 22 | |
22 | 23 | class FrameworkCommand { |
23 | 24 | private: |
@@ -28,7 +29,7 @@ public: | ||
28 | 29 | FrameworkCommand(const char *cmd); |
29 | 30 | virtual ~FrameworkCommand() { } |
30 | 31 | |
31 | - virtual int runCommand(char *data); | |
32 | + virtual int runCommand(SocketClient *c, char *data) = 0; | |
32 | 33 | |
33 | 34 | const char *getCommand() { return mCommand; } |
34 | 35 | }; |
@@ -19,6 +19,8 @@ | ||
19 | 19 | #include "SocketListener.h" |
20 | 20 | #include "FrameworkCommand.h" |
21 | 21 | |
22 | +class SocketClient; | |
23 | + | |
22 | 24 | class FrameworkListener : public SocketListener { |
23 | 25 | private: |
24 | 26 | FrameworkCommandCollection *mCommands; |
@@ -29,9 +31,9 @@ public: | ||
29 | 31 | |
30 | 32 | protected: |
31 | 33 | void registerCmd(FrameworkCommand *cmd); |
32 | - virtual bool onDataAvailable(int socket); | |
34 | + virtual bool onDataAvailable(SocketClient *c); | |
33 | 35 | |
34 | 36 | private: |
35 | - void dispatchCommand(char *cmd); | |
37 | + void dispatchCommand(SocketClient *c, char *cmd); | |
36 | 38 | }; |
37 | 39 | #endif |
@@ -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 |
@@ -27,6 +27,6 @@ public: | ||
27 | 27 | NetlinkListener(int socket); |
28 | 28 | virtual ~NetlinkListener() {} |
29 | 29 | protected: |
30 | - virtual bool onDataAvailable(int socket); | |
30 | + virtual bool onDataAvailable(SocketClient *cli); | |
31 | 31 | }; |
32 | 32 | #endif |
@@ -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 |
@@ -16,20 +16,35 @@ | ||
16 | 16 | #ifndef _SOCKETLISTENER_H |
17 | 17 | #define _SOCKETLISTENER_H |
18 | 18 | |
19 | +#include <pthread.h> | |
20 | + | |
21 | +#include <sysutils/SocketClient.h> | |
22 | + | |
19 | 23 | 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; | |
24 | 31 | |
25 | 32 | 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); | |
28 | 35 | |
29 | 36 | 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); | |
31 | 42 | |
32 | 43 | 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(); | |
34 | 49 | }; |
35 | 50 | #endif |
@@ -3,12 +3,12 @@ LOCAL_PATH:= $(call my-dir) | ||
3 | 3 | include $(CLEAR_VARS) |
4 | 4 | |
5 | 5 | LOCAL_SRC_FILES:= \ |
6 | - src/FrameworkManager.cpp \ | |
7 | 6 | src/SocketListener.cpp \ |
8 | 7 | src/FrameworkListener.cpp \ |
9 | 8 | src/NetlinkListener.cpp \ |
10 | 9 | src/NetlinkEvent.cpp \ |
11 | 10 | src/FrameworkCommand.cpp \ |
11 | + src/SocketClient.cpp \ | |
12 | 12 | |
13 | 13 | LOCAL_MODULE:= libsysutils |
14 | 14 |
@@ -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 | + |
@@ -25,7 +25,7 @@ FrameworkCommand::FrameworkCommand(const char *cmd) { | ||
25 | 25 | mCommand = cmd; |
26 | 26 | } |
27 | 27 | |
28 | -int FrameworkCommand::runCommand(char *data) { | |
28 | +int FrameworkCommand::runCommand(SocketClient *c, char *data) { | |
29 | 29 | LOGW("Command %s has no run handler!", getCommand()); |
30 | 30 | errno = ENOSYS; |
31 | 31 | return -1; |
@@ -22,17 +22,18 @@ | ||
22 | 22 | |
23 | 23 | #include <sysutils/FrameworkListener.h> |
24 | 24 | #include <sysutils/FrameworkCommand.h> |
25 | +#include <sysutils/SocketClient.h> | |
25 | 26 | |
26 | 27 | FrameworkListener::FrameworkListener(const char *socketName) : |
27 | 28 | SocketListener(socketName, true) { |
28 | 29 | mCommands = new FrameworkCommandCollection(); |
29 | 30 | } |
30 | 31 | |
31 | -bool FrameworkListener::onDataAvailable(int socket) { | |
32 | +bool FrameworkListener::onDataAvailable(SocketClient *c) { | |
32 | 33 | char buffer[101]; |
33 | 34 | int len; |
34 | 35 | |
35 | - if ((len = read(socket, buffer, sizeof(buffer) -1)) < 0) { | |
36 | + if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) { | |
36 | 37 | LOGE("read() failed (%s)", strerror(errno)); |
37 | 38 | return errno; |
38 | 39 | } else if (!len) { |
@@ -47,7 +48,7 @@ bool FrameworkListener::onDataAvailable(int socket) { | ||
47 | 48 | |
48 | 49 | for (i = 0; i < len; i++) { |
49 | 50 | if (buffer[i] == '\0') { |
50 | - dispatchCommand(buffer + start); | |
51 | + dispatchCommand(c, buffer + start); | |
51 | 52 | start = i + 1; |
52 | 53 | } |
53 | 54 | } |
@@ -58,14 +59,22 @@ void FrameworkListener::registerCmd(FrameworkCommand *cmd) { | ||
58 | 59 | mCommands->push_back(cmd); |
59 | 60 | } |
60 | 61 | |
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 | + | |
62 | 71 | FrameworkCommandCollection::iterator i; |
63 | 72 | |
64 | 73 | for (i = mCommands->begin(); i != mCommands->end(); ++i) { |
65 | 74 | FrameworkCommand *c = *i; |
66 | 75 | |
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)) { | |
69 | 78 | LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno)); |
70 | 79 | } |
71 | 80 | return; |
@@ -73,5 +82,6 @@ void FrameworkListener::dispatchCommand(char *cmd) { | ||
73 | 82 | } |
74 | 83 | |
75 | 84 | LOGE("No cmd handlers defined for '%s'", cmd); |
85 | + cli->sendMsg("UNKNOWN_CMD"); | |
86 | + return; | |
76 | 87 | } |
77 | - |
@@ -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 | -} |
@@ -29,8 +29,9 @@ NetlinkListener::NetlinkListener(int socket) : | ||
29 | 29 | SocketListener(socket, false) { |
30 | 30 | } |
31 | 31 | |
32 | -bool NetlinkListener::onDataAvailable(int socket) | |
32 | +bool NetlinkListener::onDataAvailable(SocketClient *cli) | |
33 | 33 | { |
34 | + int socket = cli->getSocket(); | |
34 | 35 | LOGD("NetlinkListener::onDataAvailable()"); |
35 | 36 | |
36 | 37 | int count; |
@@ -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 | + |
@@ -24,26 +24,28 @@ | ||
24 | 24 | |
25 | 25 | #define LOG_TAG "SocketListener" |
26 | 26 | #include <cutils/log.h> |
27 | - | |
28 | 27 | #include <cutils/sockets.h> |
29 | 28 | |
30 | 29 | #include <sysutils/SocketListener.h> |
30 | +#include <sysutils/SocketClient.h> | |
31 | 31 | |
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; | |
35 | 34 | mSocketName = socketName; |
36 | 35 | mSock = -1; |
36 | + pthread_mutex_init(&mClientsLock, NULL); | |
37 | + mClients = new SocketClientCollection(); | |
37 | 38 | } |
38 | 39 | |
39 | -SocketListener::SocketListener(int socketFd, bool acceptClients) { | |
40 | - mAcceptClients = acceptClients; | |
41 | - mCsock = -1; | |
40 | +SocketListener::SocketListener(int socketFd, bool listen) { | |
41 | + mListen = listen; | |
42 | 42 | mSocketName = NULL; |
43 | 43 | mSock = socketFd; |
44 | + pthread_mutex_init(&mClientsLock, NULL); | |
45 | + mClients = new SocketClientCollection(); | |
44 | 46 | } |
45 | 47 | |
46 | -int SocketListener::run() { | |
48 | +int SocketListener::startListener() { | |
47 | 49 | |
48 | 50 | if (!mSocketName && mSock == -1) { |
49 | 51 | errno = EINVAL; |
@@ -56,72 +58,155 @@ int SocketListener::run() { | ||
56 | 58 | } |
57 | 59 | } |
58 | 60 | |
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"); | |
64 | 67 | } |
65 | 68 | |
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 | + | |
66 | 107 | while(1) { |
108 | + SocketClientCollection::iterator it; | |
67 | 109 | fd_set read_fds; |
68 | 110 | struct timeval to; |
69 | - int max = 0; | |
70 | 111 | int rc = 0; |
71 | 112 | |
72 | 113 | to.tv_sec = 60 * 60; |
73 | 114 | to.tv_usec = 0; |
74 | 115 | |
116 | + int max = 0; | |
117 | + | |
75 | 118 | FD_ZERO(&read_fds); |
76 | 119 | |
77 | - if ((mAcceptClients == false) || | |
78 | - (mAcceptClients == true && mCsock == -1)) { | |
79 | - FD_SET(mSock, &read_fds); | |
120 | + if (mListen) { | |
80 | 121 | max = mSock; |
81 | - } else if (mCsock != -1) { | |
82 | - FD_SET(mCsock, &read_fds); | |
83 | - max = mCsock; | |
122 | + FD_SET(mSock, &read_fds); | |
84 | 123 | } |
85 | 124 | |
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 | + | |
86 | 137 | if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) { |
87 | 138 | LOGE("select failed (%s)", strerror(errno)); |
88 | - return -errno; | |
89 | - } else if (!rc) | |
139 | + sleep(1); | |
90 | 140 | 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; | |
110 | 159 | } |
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 | + } | |
120 | 183 | } |
184 | + pthread_mutex_unlock(&mClientsLock); | |
185 | + } while (0); | |
121 | 186 | } |
122 | - return 0; | |
123 | 187 | } |
124 | 188 | |
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); | |
127 | 211 | } |
212 | + |
@@ -19,6 +19,7 @@ LOCAL_SRC_FILES:= \ | ||
19 | 19 | SupplicantListener.cpp \ |
20 | 20 | VpnController.cpp \ |
21 | 21 | ScanResult.cpp \ |
22 | + WifiScanner.cpp \ | |
22 | 23 | |
23 | 24 | LOCAL_MODULE:= nexus |
24 | 25 |
@@ -19,60 +19,64 @@ | ||
19 | 19 | #define LOG_TAG "CommandListener" |
20 | 20 | #include <cutils/log.h> |
21 | 21 | |
22 | +#include <sysutils/SocketClient.h> | |
23 | + | |
22 | 24 | #include "CommandListener.h" |
23 | 25 | #include "Controller.h" |
24 | 26 | #include "NetworkManager.h" |
25 | 27 | #include "WifiController.h" |
26 | 28 | |
27 | -CommandListener::CommandListener(NetworkManager *netman) : | |
29 | +CommandListener::CommandListener() : | |
28 | 30 | 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()); | |
34 | 35 | |
35 | - registerCmd(new VpnEnableCmd(netman)); | |
36 | - registerCmd(new VpnDisableCmd(netman)); | |
36 | + registerCmd(new VpnEnableCmd()); | |
37 | + registerCmd(new VpnDisableCmd()); | |
37 | 38 | } |
38 | 39 | |
39 | 40 | /* ------------- |
40 | 41 | * Wifi Commands |
41 | 42 | * ------------ */ |
42 | 43 | |
43 | -CommandListener::WifiEnableCmd::WifiEnableCmd(NetworkManager *netman) : | |
44 | - NexusCommand("wifi_enable", netman) { | |
44 | +CommandListener::WifiEnableCmd::WifiEnableCmd() : | |
45 | + NexusCommand("wifi_enable") { | |
45 | 46 | } |
46 | 47 | |
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"); | |
49 | 50 | char buffer[32]; |
50 | 51 | |
51 | 52 | sprintf(buffer, "WIFI_ENABLE:%d", (c->enable() ? errno : 0)); |
52 | - mNetman->getFrameworkManager()->sendMsg(buffer); | |
53 | + | |
54 | + cli->sendMsg(buffer); | |
53 | 55 | return 0; |
54 | 56 | } |
55 | 57 | |
56 | -CommandListener::WifiDisableCmd::WifiDisableCmd(NetworkManager *netman) : | |
57 | - NexusCommand("wifi_disable", netman) { | |
58 | +CommandListener::WifiDisableCmd::WifiDisableCmd() : | |
59 | + NexusCommand("wifi_disable") { | |
58 | 60 | } |
59 | 61 | |
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"); | |
62 | 64 | char buffer[32]; |
63 | 65 | |
64 | 66 | sprintf(buffer, "WIFI_DISABLE:%d", (c->disable() ? errno : 0)); |
65 | - mNetman->getFrameworkManager()->sendMsg(buffer); | |
67 | + cli->sendMsg(buffer); | |
66 | 68 | return 0; |
67 | 69 | } |
68 | 70 | |
69 | -CommandListener::WifiScanCmd::WifiScanCmd(NetworkManager *netman) : | |
70 | - NexusCommand("wifi_scan", netman) { | |
71 | +CommandListener::WifiScanCmd::WifiScanCmd() : | |
72 | + NexusCommand("wifi_scan") { | |
71 | 73 | } |
72 | 74 | |
73 | -int CommandListener::WifiScanCmd::runCommand(char *data) { | |
75 | +int CommandListener::WifiScanCmd::runCommand(SocketClient *cli, char *data) { | |
74 | 76 | LOGD("WifiScanCmd(%s)", data); |
75 | - WifiController *wc = (WifiController *) mNetman->findController("WIFI"); | |
77 | + | |
78 | + WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI"); | |
79 | + | |
76 | 80 | char buffer[32]; |
77 | 81 | int mode = 0; |
78 | 82 | char *bword, *last; |
@@ -90,35 +94,62 @@ int CommandListener::WifiScanCmd::runCommand(char *data) { | ||
90 | 94 | mode = atoi(bword); |
91 | 95 | |
92 | 96 | 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"); | |
94 | 125 | return 0; |
95 | 126 | } |
96 | 127 | |
97 | 128 | /* ------------ |
98 | 129 | * Vpn Commands |
99 | 130 | * ------------ */ |
100 | -CommandListener::VpnEnableCmd::VpnEnableCmd(NetworkManager *netman) : | |
101 | - NexusCommand("vpn_enable", netman) { | |
131 | +CommandListener::VpnEnableCmd::VpnEnableCmd() : | |
132 | + NexusCommand("vpn_enable") { | |
102 | 133 | } |
103 | 134 | |
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"); | |
106 | 137 | char buffer[32]; |
107 | 138 | |
108 | 139 | sprintf(buffer, "VPN_ENABLE:%d", (c->enable() ? errno : 0)); |
109 | - mNetman->getFrameworkManager()->sendMsg(buffer); | |
140 | + cli->sendMsg(buffer); | |
110 | 141 | return 0; |
111 | 142 | } |
112 | 143 | |
113 | -CommandListener::VpnDisableCmd::VpnDisableCmd(NetworkManager *netman) : | |
114 | - NexusCommand("vpn_disable", netman) { | |
144 | +CommandListener::VpnDisableCmd::VpnDisableCmd() : | |
145 | + NexusCommand("vpn_disable") { | |
115 | 146 | } |
116 | 147 | |
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"); | |
119 | 150 | char buffer[32]; |
120 | 151 | |
121 | 152 | sprintf(buffer, "VPN_DISABLE:%d", (c->disable() ? errno : 0)); |
122 | - mNetman->getFrameworkManager()->sendMsg(buffer); | |
153 | + cli->sendMsg(buffer); | |
123 | 154 | return 0; |
124 | 155 | } |
@@ -19,50 +19,52 @@ | ||
19 | 19 | #include <sysutils/FrameworkListener.h> |
20 | 20 | #include "NexusCommand.h" |
21 | 21 | |
22 | -class NetworkManager; | |
23 | - | |
24 | 22 | class CommandListener : public FrameworkListener { |
25 | -protected: | |
26 | - NetworkManager *mNetman; | |
27 | - | |
28 | 23 | public: |
29 | - CommandListener(NetworkManager *netman); | |
24 | + CommandListener(); | |
30 | 25 | virtual ~CommandListener() {} |
31 | 26 | |
32 | 27 | private: |
33 | 28 | class WifiEnableCmd : public NexusCommand { |
34 | 29 | public: |
35 | - WifiEnableCmd(NetworkManager *); | |
30 | + WifiEnableCmd(); | |
36 | 31 | virtual ~WifiEnableCmd() {} |
37 | - int runCommand(char *data); | |
32 | + int runCommand(SocketClient *c, char *data); | |
38 | 33 | }; |
39 | 34 | |
40 | 35 | class WifiDisableCmd : public NexusCommand { |
41 | 36 | public: |
42 | - WifiDisableCmd(NetworkManager *); | |
37 | + WifiDisableCmd(); | |
43 | 38 | virtual ~WifiDisableCmd() {} |
44 | - int runCommand(char *data); | |
39 | + int runCommand(SocketClient *c, char *data); | |
45 | 40 | }; |
46 | 41 | |
47 | 42 | class WifiScanCmd : public NexusCommand { |
48 | 43 | public: |
49 | - WifiScanCmd(NetworkManager *); | |
44 | + WifiScanCmd(); | |
50 | 45 | 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); | |
52 | 54 | }; |
53 | 55 | |
54 | 56 | class VpnEnableCmd : public NexusCommand { |
55 | 57 | public: |
56 | - VpnEnableCmd(NetworkManager *); | |
58 | + VpnEnableCmd(); | |
57 | 59 | virtual ~VpnEnableCmd() {} |
58 | - int runCommand(char *data); | |
60 | + int runCommand(SocketClient *c, char *data); | |
59 | 61 | }; |
60 | 62 | |
61 | 63 | class VpnDisableCmd : public NexusCommand { |
62 | 64 | public: |
63 | - VpnDisableCmd(NetworkManager *); | |
65 | + VpnDisableCmd(); | |
64 | 66 | virtual ~VpnDisableCmd() {} |
65 | - int runCommand(char *data); | |
67 | + int runCommand(SocketClient *c, char *data); | |
66 | 68 | }; |
67 | 69 | |
68 | 70 | }; |
@@ -21,36 +21,30 @@ | ||
21 | 21 | #include <cutils/log.h> |
22 | 22 | |
23 | 23 | #include "NetworkManager.h" |
24 | -#include "CommandListener.h" | |
25 | -#include "LoopController.h" | |
26 | -#include "VpnController.h" | |
27 | 24 | |
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 | +} | |
29 | 32 | |
30 | 33 | NetworkManager::NetworkManager() { |
31 | - mListener = new CommandListener(this); | |
32 | - mFm = new FrameworkManager(mListener); | |
34 | + mBroadcaster = NULL; | |
33 | 35 | mControllers = new ControllerCollection(); |
34 | 36 | } |
35 | 37 | |
36 | 38 | 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 | - | |
45 | 39 | if (startControllers()) { |
46 | 40 | LOGW("Unable to start all controllers (%s)", strerror(errno)); |
47 | 41 | } |
48 | - mFm->run(); | |
49 | 42 | return 0; |
50 | 43 | } |
51 | 44 | |
52 | -void NetworkManager::addController(Controller *c) { | |
45 | +int NetworkManager::attachController(Controller *c) { | |
53 | 46 | mControllers->push_back(c); |
47 | + return 0; | |
54 | 48 | } |
55 | 49 | |
56 | 50 | int NetworkManager::startControllers() { |
@@ -16,31 +16,36 @@ | ||
16 | 16 | #ifndef _NETWORKMANAGER_H |
17 | 17 | #define _NETWORKMANAGER_H |
18 | 18 | |
19 | -#include "Controller.h" | |
19 | +#include <sysutils/SocketListener.h> | |
20 | 20 | |
21 | -#include <sysutils/FrameworkManager.h> | |
21 | +#include "Controller.h" | |
22 | 22 | |
23 | 23 | class NetworkManager { |
24 | 24 | private: |
25 | - FrameworkListener *mListener; | |
26 | - FrameworkManager *mFm; | |
25 | + static NetworkManager *sInstance; | |
26 | + | |
27 | +private: | |
27 | 28 | ControllerCollection *mControllers; |
29 | + SocketListener *mBroadcaster; | |
28 | 30 | |
29 | 31 | public: |
30 | - NetworkManager(); | |
31 | 32 | virtual ~NetworkManager() {} |
32 | 33 | |
33 | 34 | int run(); |
34 | 35 | |
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 | + | |
35 | 45 | private: |
36 | - void addController(Controller *c); | |
37 | 46 | int startControllers(); |
38 | 47 | int stopControllers(); |
39 | - | |
40 | -public: | |
41 | - Controller *findController(const char *name); | |
42 | - ControllerCollection *getControllers() { return mControllers; } | |
43 | - FrameworkManager *getFrameworkManager() { return mFm; } | |
48 | + NetworkManager(); | |
44 | 49 | |
45 | 50 | public: |
46 | 51 | // XXX: Extract these into an interface |
@@ -15,7 +15,6 @@ | ||
15 | 15 | */ |
16 | 16 | #include "NexusCommand.h" |
17 | 17 | |
18 | -NexusCommand::NexusCommand(const char *cmd, NetworkManager *netman) : | |
18 | +NexusCommand::NexusCommand(const char *cmd) : | |
19 | 19 | FrameworkCommand(cmd) { |
20 | - mNetman = netman; | |
21 | 20 | } |
@@ -18,14 +18,9 @@ | ||
18 | 18 | |
19 | 19 | #include <sysutils/FrameworkCommand.h> |
20 | 20 | |
21 | -class NetworkManager; | |
22 | - | |
23 | 21 | class NexusCommand : public FrameworkCommand { |
24 | -protected: | |
25 | - NetworkManager *mNetman; | |
26 | - | |
27 | 22 | public: |
28 | - NexusCommand(const char *cmd, NetworkManager *netman); | |
23 | + NexusCommand(const char *cmd); | |
29 | 24 | virtual ~NexusCommand() {} |
30 | 25 | }; |
31 | 26 |
@@ -38,6 +38,7 @@ public: | ||
38 | 38 | |
39 | 39 | const char *getBssid() { return mBssid; } |
40 | 40 | uint32_t getFreq() { return mFreq; } |
41 | + int getLevel() { return mLevel; } | |
41 | 42 | const char *getFlags() { return mFlags; } |
42 | 43 | const char *getSsid() { return mSsid; } |
43 | 44 | }; |
@@ -13,6 +13,8 @@ | ||
13 | 13 | * See the License for the specific language governing permissions and |
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | + | |
17 | +#include <stdlib.h> | |
16 | 18 | #include <errno.h> |
17 | 19 | |
18 | 20 | #define LOG_TAG "Supplicant" |
@@ -31,6 +33,7 @@ | ||
31 | 33 | #include "SupplicantState.h" |
32 | 34 | #include "SupplicantEvent.h" |
33 | 35 | #include "ScanResult.h" |
36 | +#include "NetworkManager.h" | |
34 | 37 | |
35 | 38 | #include "libwpa_client/wpa_ctrl.h" |
36 | 39 |
@@ -52,7 +55,6 @@ Supplicant::Supplicant() { | ||
52 | 55 | } |
53 | 56 | |
54 | 57 | int Supplicant::start() { |
55 | - LOGD("start():"); | |
56 | 58 | // XXX: Validate supplicant config file |
57 | 59 | |
58 | 60 | char status[PROPERTY_VALUE_MAX] = {'\0'}; |
@@ -63,47 +65,47 @@ int Supplicant::start() { | ||
63 | 65 | #endif |
64 | 66 | |
65 | 67 | 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 { | |
71 | 71 | #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; | |
75 | 75 | #endif |
76 | 76 | |
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--) { | |
80 | 81 | #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 | + } | |
91 | 93 | } |
92 | - } | |
93 | 94 | #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 | + } | |
98 | 99 | #endif |
99 | - usleep(100000); | |
100 | + usleep(100000); | |
101 | + } | |
102 | + if (!count) { | |
103 | + errno = ETIMEDOUT; | |
104 | + return -1; | |
105 | + } | |
100 | 106 | } |
101 | 107 | |
102 | - if (!count) { | |
103 | - errno = ETIMEDOUT; | |
104 | - return -1; | |
105 | - } | |
106 | - | |
108 | + wpa_ctrl_cleanup(); | |
107 | 109 | if (connectToSupplicant()) { |
108 | 110 | LOGE("Error connecting to supplicant (%s)\n", strerror(errno)); |
109 | 111 | return -1; |
@@ -112,7 +114,6 @@ int Supplicant::start() { | ||
112 | 114 | } |
113 | 115 | |
114 | 116 | int Supplicant::stop() { |
115 | - LOGD("stop()"); | |
116 | 117 | |
117 | 118 | char supp_status[PROPERTY_VALUE_MAX] = {'\0'}; |
118 | 119 | int count = 50; |
@@ -124,9 +125,11 @@ int Supplicant::stop() { | ||
124 | 125 | |
125 | 126 | if (property_get(SUPP_PROP_NAME, supp_status, NULL) |
126 | 127 | && strcmp(supp_status, "stopped") == 0) { |
128 | + LOGD("Supplicant already stopped"); | |
127 | 129 | return 0; |
128 | 130 | } |
129 | 131 | |
132 | + LOGD("Stopping Supplicant"); | |
130 | 133 | property_set("ctl.stop", SUPPLICANT_NAME); |
131 | 134 | sched_yield(); |
132 | 135 |
@@ -153,24 +156,29 @@ int Supplicant::stop() { | ||
153 | 156 | return -1; |
154 | 157 | } |
155 | 158 | |
156 | - LOGD("Stopped OK"); | |
159 | + LOGD("Supplicant shutdown"); | |
157 | 160 | |
158 | 161 | return 0; |
159 | 162 | } |
160 | 163 | |
161 | 164 | bool Supplicant::isStarted() { |
162 | 165 | 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; | |
168 | 175 | } |
169 | 176 | |
170 | 177 | int Supplicant::connectToSupplicant() { |
171 | 178 | char ifname[256]; |
172 | 179 | char supp_status[PROPERTY_VALUE_MAX] = {'\0'}; |
173 | 180 | |
181 | + LOGD("connectToSupplicant()"); | |
174 | 182 | if (!property_get(SUPP_PROP_NAME, supp_status, NULL) |
175 | 183 | || strcmp(supp_status, "running") != 0) { |
176 | 184 | LOGE("Supplicant not running, cannot connect"); |
@@ -213,13 +221,14 @@ int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len) | ||
213 | 221 | return -1; |
214 | 222 | } |
215 | 223 | |
216 | - LOGD("sendCommand(): -> '%s'", cmd); | |
224 | +// LOGD("sendCommand(): -> '%s'", cmd); | |
217 | 225 | |
218 | 226 | int rc; |
219 | 227 | if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) { |
220 | 228 | errno = ETIMEDOUT; |
221 | 229 | return -1; |
222 | 230 | } else if (rc < 0 || !strncmp(reply, "FAIL", 4)) { |
231 | + LOGW("sendCommand(): <- '%s'", reply); | |
223 | 232 | errno = EIO; |
224 | 233 | return -1; |
225 | 234 | } |
@@ -228,7 +237,7 @@ int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len) | ||
228 | 237 | !strncmp(cmd, "SCAN_RESULTS", 12)) |
229 | 238 | reply[*reply_len] = '\0'; |
230 | 239 | |
231 | - LOGD("sendCommand(): <- '%s'", reply); | |
240 | +// LOGD("sendCommand(): <- '%s'", reply); | |
232 | 241 | return 0; |
233 | 242 | } |
234 | 243 |
@@ -332,12 +341,16 @@ int Supplicant::onScanResultsEvent(SupplicantEvent *evt) { | ||
332 | 341 | |
333 | 342 | if (!strtok_r(reply, "\n", &linep_next)) { |
334 | 343 | free(reply); |
335 | - return 0;; | |
344 | + pthread_mutex_unlock(&mLatestScanResultsLock); | |
345 | + return 0; | |
336 | 346 | } |
337 | 347 | |
338 | 348 | while((linep = strtok_r(NULL, "\n", &linep_next))) |
339 | 349 | 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); | |
341 | 354 | pthread_mutex_unlock(&mLatestScanResultsLock); |
342 | 355 | free(reply); |
343 | 356 | } else { |
@@ -347,8 +360,24 @@ int Supplicant::onScanResultsEvent(SupplicantEvent *evt) { | ||
347 | 360 | } |
348 | 361 | |
349 | 362 | 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); | |
352 | 381 | return 0; |
353 | 382 | } |
354 | 383 |
@@ -363,7 +392,7 @@ int Supplicant::onDriverStateEvent(SupplicantEvent *evt) { | ||
363 | 392 | } |
364 | 393 | |
365 | 394 | // XXX: Use a cursor + smartptr instead |
366 | -const ScanResultCollection *Supplicant::getLatestScanResults() { | |
395 | +ScanResultCollection *Supplicant::createLatestScanResults() { | |
367 | 396 | ScanResultCollection *d = new ScanResultCollection(); |
368 | 397 | ScanResultCollection::iterator i; |
369 | 398 |
@@ -46,7 +46,7 @@ public: | ||
46 | 46 | |
47 | 47 | int getState() { return mState; } |
48 | 48 | |
49 | - const ScanResultCollection *getLatestScanResults(); | |
49 | + ScanResultCollection *createLatestScanResults(); | |
50 | 50 | |
51 | 51 | // XXX: Extract these into an interface |
52 | 52 | public: |
@@ -30,31 +30,9 @@ SupplicantListener::SupplicantListener(Supplicant *supplicant, struct wpa_ctrl * | ||
30 | 30 | SocketListener(wpa_ctrl_get_fd(monitor), false) { |
31 | 31 | mSupplicant = supplicant; |
32 | 32 | mMonitor = monitor; |
33 | - mThread = NULL; | |
34 | 33 | } |
35 | 34 | |
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) { | |
58 | 36 | char buf[255]; |
59 | 37 | size_t buflen = sizeof(buf); |
60 | 38 | int rc; |
@@ -62,7 +40,7 @@ bool SupplicantListener::onDataAvailable(int socket) { | ||
62 | 40 | |
63 | 41 | if ((rc = wpa_ctrl_recv(mMonitor, buf, &nread))) { |
64 | 42 | LOGE("wpa_ctrl_recv failed (%s)", strerror(errno)); |
65 | - return -errno; | |
43 | + return false; | |
66 | 44 | } |
67 | 45 | |
68 | 46 | buf[nread] = '\0'; |
@@ -108,7 +86,9 @@ bool SupplicantListener::onDataAvailable(int socket) { | ||
108 | 86 | |
109 | 87 | delete evt; |
110 | 88 | |
111 | - if (rc) | |
89 | + if (rc) { | |
90 | + LOGW("Handler %d (%s) error: %s", evt->getType(), evt->getEvent(), strerror(errno)); | |
112 | 91 | return false; |
92 | + } | |
113 | 93 | return true; |
114 | 94 | } |
@@ -16,33 +16,27 @@ | ||
16 | 16 | #ifndef _SUPPLICANTLISTENER_H__ |
17 | 17 | #define _SUPPLICANTLISTENER_H__ |
18 | 18 | |
19 | -#include <pthread.h> | |
20 | - | |
21 | 19 | #include <sysutils/SocketListener.h> |
22 | 20 | |
23 | 21 | struct wpa_ctrl; |
24 | 22 | class Supplicant; |
23 | +class SocketClient; | |
25 | 24 | |
26 | 25 | class SupplicantListener: public SocketListener { |
27 | 26 | private: |
28 | 27 | struct wpa_ctrl *mMonitor; |
29 | 28 | Supplicant *mSupplicant; |
30 | - pthread_t mThread; | |
31 | 29 | |
32 | 30 | public: |
33 | 31 | SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *monitor); |
34 | 32 | virtual ~SupplicantListener() {} |
35 | - int startListener(); | |
36 | - int stopListener(); | |
37 | 33 | |
38 | 34 | struct wpa_ctrl *getMonitor() { return mMonitor; } |
39 | 35 | Supplicant *getSupplicant() { return mSupplicant; } |
40 | 36 | |
41 | 37 | protected: |
42 | - virtual bool onDataAvailable(int socket); | |
38 | + virtual bool onDataAvailable(SocketClient *c); | |
43 | 39 | |
44 | -private: | |
45 | - static void *threadStart(void *obj); | |
46 | 40 | }; |
47 | 41 | |
48 | 42 | #endif |
@@ -18,16 +18,16 @@ | ||
18 | 18 | |
19 | 19 | class SupplicantState { |
20 | 20 | 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; | |
31 | 31 | }; |
32 | 32 | |
33 | 33 | #endif |
@@ -65,3 +65,17 @@ int TiwlanWifiController::loadFirmware() { | ||
65 | 65 | property_set(DRIVER_PROP_NAME, "timeout"); |
66 | 66 | return -1; |
67 | 67 | } |
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 | +} |
@@ -27,5 +27,6 @@ public: | ||
27 | 27 | virtual int powerDown(); |
28 | 28 | virtual bool isPoweredUp(); |
29 | 29 | virtual int loadFirmware(); |
30 | + virtual bool isFirmwareLoaded(); | |
30 | 31 | }; |
31 | 32 | #endif |
@@ -21,6 +21,8 @@ | ||
21 | 21 | |
22 | 22 | #include "Supplicant.h" |
23 | 23 | #include "WifiController.h" |
24 | +#include "WifiScanner.h" | |
25 | +#include "NetworkManager.h" | |
24 | 26 | |
25 | 27 | WifiController::WifiController(char *modpath, char *modname, char *modargs) : |
26 | 28 | Controller("WIFI") { |
@@ -29,6 +31,7 @@ WifiController::WifiController(char *modpath, char *modname, char *modargs) : | ||
29 | 31 | strncpy(mModuleArgs, modargs, sizeof(mModuleArgs)); |
30 | 32 | |
31 | 33 | mSupplicant = new Supplicant(); |
34 | + mScanner = new WifiScanner(mSupplicant, 10); | |
32 | 35 | mCurrentScanMode = 0; |
33 | 36 | } |
34 | 37 |
@@ -42,26 +45,36 @@ int WifiController::stop() { | ||
42 | 45 | } |
43 | 46 | |
44 | 47 | 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 | + } | |
48 | 54 | } |
49 | - | |
55 | + | |
50 | 56 | if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) { |
57 | + sendStatusBroadcast("LOADING_DRIVER"); | |
51 | 58 | if (loadKernelModule(mModulePath, mModuleArgs)) { |
52 | 59 | LOGE("Kernel module load failed (%s)", strerror(errno)); |
53 | 60 | goto out_powerdown; |
54 | 61 | } |
55 | 62 | } |
56 | 63 | |
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 | + } | |
60 | 70 | } |
61 | 71 | |
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 | + } | |
65 | 78 | } |
66 | 79 | |
67 | 80 | return 0; |
@@ -80,24 +93,38 @@ out_powerdown: | ||
80 | 93 | return -1; |
81 | 94 | } |
82 | 95 | |
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 | + | |
83 | 103 | int WifiController::disable() { |
84 | - LOGD("disable()"); | |
85 | 104 | |
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?"); | |
90 | 113 | |
91 | 114 | if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) { |
115 | + sendStatusBroadcast("UNLOADING_DRIVER"); | |
92 | 116 | if (unloadKernelModule(mModuleName)) { |
93 | 117 | LOGE("Unable to unload module (%s)", strerror(errno)); |
94 | 118 | return -1; |
95 | 119 | } |
96 | 120 | } |
97 | 121 | |
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 | + } | |
101 | 128 | } |
102 | 129 | return 0; |
103 | 130 | } |
@@ -106,7 +133,7 @@ int WifiController::loadFirmware() { | ||
106 | 133 | return 0; |
107 | 134 | } |
108 | 135 | |
109 | -int WifiController::setScanMode(int mode) { | |
136 | +int WifiController::setScanMode(uint32_t mode) { | |
110 | 137 | int rc = 0; |
111 | 138 | |
112 | 139 | if (mCurrentScanMode == mode) |
@@ -114,21 +141,15 @@ int WifiController::setScanMode(int mode) { | ||
114 | 141 | |
115 | 142 | if (!(mode & SCAN_ENABLE_MASK)) { |
116 | 143 | if (mCurrentScanMode & SCAN_REPEAT_MASK) |
117 | - stopPeriodicScan(); | |
144 | + mScanner->stopPeriodicScan(); | |
118 | 145 | } else if (mode & SCAN_REPEAT_MASK) |
119 | - rc = startPeriodicScan(); | |
146 | + rc = mScanner->startPeriodicScan(mode & SCAN_ACTIVE_MASK); | |
120 | 147 | else |
121 | 148 | rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK); |
122 | 149 | |
123 | 150 | return rc; |
124 | 151 | } |
125 | 152 | |
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(); | |
134 | 155 | } |
@@ -22,6 +22,9 @@ | ||
22 | 22 | |
23 | 23 | class NetInterface; |
24 | 24 | class Supplicant; |
25 | +class WifiScanner; | |
26 | + | |
27 | +#include "ScanResult.h" | |
25 | 28 | |
26 | 29 | class WifiController : public Controller { |
27 | 30 | public: |
@@ -40,8 +43,8 @@ private: | ||
40 | 43 | char mModulePath[255]; |
41 | 44 | char mModuleName[64]; |
42 | 45 | char mModuleArgs[255]; |
43 | - int mCurrentScanMode; | |
44 | - | |
46 | + uint32_t mCurrentScanMode; | |
47 | + WifiScanner *mScanner; | |
45 | 48 | |
46 | 49 | public: |
47 | 50 | WifiController(char *modpath, char *modname, char *modargs); |
@@ -53,6 +56,8 @@ public: | ||
53 | 56 | int enable(); |
54 | 57 | int disable(); |
55 | 58 | |
59 | + ScanResultCollection *createScanResults(); | |
60 | + | |
56 | 61 | int getType(); |
57 | 62 | |
58 | 63 | char *getModulePath() { return mModulePath; } |
@@ -62,17 +67,17 @@ public: | ||
62 | 67 | Supplicant *getSupplicant() { return mSupplicant; } |
63 | 68 | |
64 | 69 | int getScanMode() { return mCurrentScanMode; } |
65 | - int setScanMode(int mode); | |
70 | + int setScanMode(uint32_t mode); | |
66 | 71 | |
67 | 72 | protected: |
68 | 73 | virtual int powerUp() = 0; |
69 | 74 | virtual int powerDown() = 0; |
70 | 75 | virtual int loadFirmware(); |
76 | + | |
77 | + virtual bool isFirmwareLoaded() = 0; | |
71 | 78 | virtual bool isPoweredUp() = 0; |
72 | 79 | |
73 | -private: | |
74 | - int startPeriodicScan(); | |
75 | - int stopPeriodicScan(); | |
80 | + void sendStatusBroadcast(const char *msg); | |
76 | 81 | }; |
77 | 82 | |
78 | 83 | #endif |
@@ -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 | +} |
@@ -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 |
@@ -20,22 +20,44 @@ | ||
20 | 20 | |
21 | 21 | #include "cutils/log.h" |
22 | 22 | #include "NetworkManager.h" |
23 | +#include "CommandListener.h" | |
23 | 24 | |
24 | -int main() { | |
25 | - NetworkManager *nm; | |
25 | +#include "LoopController.h" | |
26 | +#include "VpnController.h" | |
27 | +#include "TiwlanWifiController.h" | |
26 | 28 | |
29 | +int main() { | |
27 | 30 | LOGI("Nexus version 0.1 firing up"); |
28 | 31 | |
29 | - if (!(nm = new NetworkManager())) { | |
32 | + CommandListener *cl = new CommandListener(); | |
33 | + | |
34 | + NetworkManager *nm; | |
35 | + if (!(nm = NetworkManager::Instance())) { | |
30 | 36 | LOGE("Unable to create NetworkManager"); |
31 | 37 | exit (-1); |
32 | 38 | }; |
33 | 39 | |
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()) { | |
35 | 48 | LOGE("Unable to Run NetworkManager (%s)", strerror(errno)); |
36 | 49 | exit (1); |
37 | 50 | } |
38 | 51 | |
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 | + | |
39 | 61 | LOGI("Nexus exiting"); |
40 | 62 | exit(0); |
41 | 63 | } |
@@ -65,14 +65,13 @@ int main(int argc, char **argv) { | ||
65 | 65 | |
66 | 66 | buffer[strlen(buffer) -1] = 0; |
67 | 67 | |
68 | - printf("sending '%s'\n", buffer); | |
69 | 68 | if (write(sock, buffer, strlen(buffer) +1) < 0) { |
70 | 69 | fprintf(stderr, "Error writing data (%s)\n", strerror(errno)); |
71 | 70 | exit(2); |
72 | 71 | } |
73 | 72 | |
74 | 73 | wait: |
75 | - to.tv_sec = 5; | |
74 | + to.tv_sec = 10; | |
76 | 75 | to.tv_usec = 0; |
77 | 76 | FD_ZERO(&read_fds); |
78 | 77 | FD_SET(sock, &read_fds); |
@@ -88,12 +87,11 @@ wait: | ||
88 | 87 | printf("{response timeout}\n"); |
89 | 88 | continue; |
90 | 89 | } 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) { | |
93 | 91 | fprintf(stderr, "Error reading response (%s)\n", strerror(errno)); |
94 | 92 | exit(2); |
95 | 93 | } |
96 | - printf(" |%s|\n", buffer); | |
94 | + printf(" %s\n", buffer); | |
97 | 95 | goto wait; |
98 | 96 | } |
99 | 97 | } |