system/corennnnn
修订版 | ab15ac0881517ef2a72fbcd11a39d634c678878d (tree) |
---|---|
时间 | 2009-05-08 09:46:47 |
作者 | Mathias Agopian <mathias@goog...> |
Commiter | Mathias Agopian |
Merge commit 'goog/master' into merge_master
@@ -21,6 +21,7 @@ else | ||
21 | 21 | include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \ |
22 | 22 | adb \ |
23 | 23 | libcutils \ |
24 | + libsysutils \ | |
24 | 25 | liblog \ |
25 | 26 | libnetutils \ |
26 | 27 | libpixelflinger \ |
@@ -7,7 +7,6 @@ LOCAL_PATH:= $(call my-dir) | ||
7 | 7 | |
8 | 8 | # adb host tool |
9 | 9 | # ========================================================= |
10 | -ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean (also unused with the sim) | |
11 | 10 | include $(CLEAR_VARS) |
12 | 11 | |
13 | 12 | # Default to a virtual (sockets) usb interface |
@@ -77,7 +76,6 @@ ifeq ($(HOST_OS),windows) | ||
77 | 76 | $(LOCAL_INSTALLED_MODULE): $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll |
78 | 77 | endif |
79 | 78 | |
80 | -endif | |
81 | 79 | |
82 | 80 | # adbd device daemon |
83 | 81 | # ========================================================= |
@@ -222,6 +222,7 @@ void usage(void) | ||
222 | 222 | " -p <product> specify product name\n" |
223 | 223 | " -c <cmdline> override kernel commandline\n" |
224 | 224 | " -i <vendor id> specify a custom USB vendor id\n" |
225 | + " -b <base_addr> specify a custom kernel base address\n" | |
225 | 226 | ); |
226 | 227 | exit(1); |
227 | 228 | } |
@@ -0,0 +1,37 @@ | ||
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 __FRAMEWORK_CMD_HANDLER_H | |
17 | +#define __FRAMEWORK_CMD_HANDLER_H | |
18 | + | |
19 | +#include "../../../frameworks/base/include/utils/List.h" | |
20 | + | |
21 | + | |
22 | +class FrameworkCommand { | |
23 | +private: | |
24 | + const char *mCommand; | |
25 | + | |
26 | +public: | |
27 | + | |
28 | + FrameworkCommand(const char *cmd); | |
29 | + virtual ~FrameworkCommand() { } | |
30 | + | |
31 | + virtual int runCommand(char *data); | |
32 | + | |
33 | + const char *getCommand() { return mCommand; } | |
34 | +}; | |
35 | + | |
36 | +typedef android::List<FrameworkCommand *> FrameworkCommandCollection; | |
37 | +#endif |
@@ -0,0 +1,37 @@ | ||
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 _FRAMEWORKSOCKETLISTENER_H | |
17 | +#define _FRAMEWORKSOCKETLISTENER_H | |
18 | + | |
19 | +#include "SocketListener.h" | |
20 | +#include "FrameworkCommand.h" | |
21 | + | |
22 | +class FrameworkListener : public SocketListener { | |
23 | +private: | |
24 | + FrameworkCommandCollection *mCommands; | |
25 | + | |
26 | +public: | |
27 | + FrameworkListener(const char *socketName); | |
28 | + virtual ~FrameworkListener() {} | |
29 | + | |
30 | +protected: | |
31 | + void registerCmd(FrameworkCommand *cmd); | |
32 | + virtual bool onDataAvailable(int socket); | |
33 | + | |
34 | +private: | |
35 | + void dispatchCommand(char *cmd); | |
36 | +}; | |
37 | +#endif |
@@ -0,0 +1,40 @@ | ||
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 |
@@ -0,0 +1,44 @@ | ||
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 _NETLINKEVENT_H | |
17 | +#define _NETLINKEVENT_H | |
18 | + | |
19 | +#define NL_PARAMS_MAX 32 | |
20 | + | |
21 | +class NetlinkEvent { | |
22 | + int mSeq; | |
23 | + char *mPath; | |
24 | + int mAction; | |
25 | + char *mSubsystem; | |
26 | + char *mParams[NL_PARAMS_MAX]; | |
27 | + | |
28 | +public: | |
29 | + const static int NlActionUnknown; | |
30 | + const static int NlActionAdd; | |
31 | + const static int NlActionRemove; | |
32 | + const static int NlActionChange; | |
33 | + | |
34 | + NetlinkEvent(); | |
35 | + virtual ~NetlinkEvent(); | |
36 | + | |
37 | + bool decode(char *buffer, int size); | |
38 | + const char *findParam(const char *paramName); | |
39 | + | |
40 | + const char *getSubsystem() { return mSubsystem; } | |
41 | + int getAction() { return mAction; } | |
42 | +}; | |
43 | + | |
44 | +#endif |
@@ -0,0 +1,32 @@ | ||
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 _NETLINKLISTENER_H | |
17 | +#define _NETLINKLISTENER_H | |
18 | + | |
19 | +#include "SocketListener.h" | |
20 | + | |
21 | +class NetlinkEvent; | |
22 | + | |
23 | +class NetlinkListener : public SocketListener { | |
24 | + char mBuffer[64 * 1024]; | |
25 | + | |
26 | +public: | |
27 | + NetlinkListener(int socket); | |
28 | + virtual ~NetlinkListener() {} | |
29 | +protected: | |
30 | + virtual bool onDataAvailable(int socket); | |
31 | +}; | |
32 | +#endif |
@@ -0,0 +1,35 @@ | ||
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 _SOCKETLISTENER_H | |
17 | +#define _SOCKETLISTENER_H | |
18 | + | |
19 | +class SocketListener { | |
20 | + int mSock; | |
21 | + int mCsock; | |
22 | + int mAcceptClients; | |
23 | + const char *mSocketName; | |
24 | + | |
25 | +public: | |
26 | + SocketListener(const char *socketName, bool acceptClients); | |
27 | + SocketListener(int socketFd, bool acceptClients); | |
28 | + | |
29 | + virtual ~SocketListener() {} | |
30 | + virtual int run(); | |
31 | + | |
32 | +protected: | |
33 | + virtual bool onDataAvailable(int socket); | |
34 | +}; | |
35 | +#endif |
@@ -126,6 +126,7 @@ static struct perms_ devperms[] = { | ||
126 | 126 | { "/dev/msm_audpre", 0660, AID_SYSTEM, AID_AUDIO, 0 }, |
127 | 127 | { "/dev/htc-acoustic", 0660, AID_SYSTEM, AID_AUDIO, 0 }, |
128 | 128 | { "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 }, |
129 | + { "/dev/qemu_trace", 0666, AID_SYSTEM, AID_SYSTEM, 0 }, | |
129 | 130 | { "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 }, |
130 | 131 | { "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 }, |
131 | 132 | { "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 }, |
@@ -423,7 +423,7 @@ static void msg_stop(const char *name) | ||
423 | 423 | if (svc) { |
424 | 424 | service_stop(svc); |
425 | 425 | } else { |
426 | - ERROR("no such service '%s'\n"); | |
426 | + ERROR("no such service '%s'\n", name); | |
427 | 427 | } |
428 | 428 | } |
429 | 429 |
@@ -29,7 +29,8 @@ void *read_file(const char *fn, unsigned *_sz); | ||
29 | 29 | void log_init(void); |
30 | 30 | void log_set_level(int level); |
31 | 31 | void log_close(void); |
32 | -void log_write(int level, const char *fmt, ...); | |
32 | +void log_write(int level, const char *fmt, ...) | |
33 | + __attribute__ ((format(printf, 2, 3))); | |
33 | 34 | |
34 | 35 | #define ERROR(x...) log_write(3, "<3>init: " x) |
35 | 36 | #define NOTICE(x...) log_write(5, "<5>init: " x) |
@@ -15,6 +15,8 @@ | ||
15 | 15 | ** limitations under the License. |
16 | 16 | */ |
17 | 17 | |
18 | +#include <limits.h> /* for SIZE_MAX */ | |
19 | + | |
18 | 20 | #include <cutils/jstring.h> |
19 | 21 | #include <assert.h> |
20 | 22 | #include <stdlib.h> |
@@ -26,19 +28,67 @@ | ||
26 | 28 | */ |
27 | 29 | extern size_t strnlen16to8(const char16_t* utf16Str, size_t len) |
28 | 30 | { |
29 | - size_t utf8Len = 0; | |
30 | - | |
31 | - while (len--) { | |
32 | - unsigned int uic = *utf16Str++; | |
33 | - | |
34 | - if (uic > 0x07ff) | |
35 | - utf8Len += 3; | |
36 | - else if (uic > 0x7f || uic == 0) | |
37 | - utf8Len += 2; | |
38 | - else | |
39 | - utf8Len++; | |
40 | - } | |
41 | - return utf8Len; | |
31 | + size_t utf8Len = 0; | |
32 | + | |
33 | + /* A small note on integer overflow. The result can | |
34 | + * potentially be as big as 3*len, which will overflow | |
35 | + * for len > SIZE_MAX/3. | |
36 | + * | |
37 | + * Moreover, the result of a strnlen16to8 is typically used | |
38 | + * to allocate a destination buffer to strncpy16to8 which | |
39 | + * requires one more byte to terminate the UTF-8 copy, and | |
40 | + * this is generally done by careless users by incrementing | |
41 | + * the result without checking for integer overflows, e.g.: | |
42 | + * | |
43 | + * dst = malloc(strnlen16to8(utf16,len)+1) | |
44 | + * | |
45 | + * Due to this, the following code will try to detect | |
46 | + * overflows, and never return more than (SIZE_MAX-1) | |
47 | + * when it detects one. A careless user will try to malloc | |
48 | + * SIZE_MAX bytes, which will return NULL which can at least | |
49 | + * be detected appropriately. | |
50 | + * | |
51 | + * As far as I know, this function is only used by strndup16(), | |
52 | + * but better be safe than sorry. | |
53 | + */ | |
54 | + | |
55 | + /* Fast path for the usual case where 3*len is < SIZE_MAX-1. | |
56 | + */ | |
57 | + if (len < (SIZE_MAX-1)/3) { | |
58 | + while (len--) { | |
59 | + unsigned int uic = *utf16Str++; | |
60 | + | |
61 | + if (uic > 0x07ff) | |
62 | + utf8Len += 3; | |
63 | + else if (uic > 0x7f || uic == 0) | |
64 | + utf8Len += 2; | |
65 | + else | |
66 | + utf8Len++; | |
67 | + } | |
68 | + return utf8Len; | |
69 | + } | |
70 | + | |
71 | + /* The slower but paranoid version */ | |
72 | + while (len--) { | |
73 | + unsigned int uic = *utf16Str++; | |
74 | + size_t utf8Cur = utf8Len; | |
75 | + | |
76 | + if (uic > 0x07ff) | |
77 | + utf8Len += 3; | |
78 | + else if (uic > 0x7f || uic == 0) | |
79 | + utf8Len += 2; | |
80 | + else | |
81 | + utf8Len++; | |
82 | + | |
83 | + if (utf8Len < utf8Cur) /* overflow detected */ | |
84 | + return SIZE_MAX-1; | |
85 | + } | |
86 | + | |
87 | + /* don't return SIZE_MAX to avoid common user bug */ | |
88 | + if (utf8Len == SIZE_MAX) | |
89 | + utf8Len = SIZE_MAX-1; | |
90 | + | |
91 | + return utf8Len; | |
42 | 92 | } |
43 | 93 | |
44 | 94 |
@@ -50,7 +100,7 @@ extern size_t strnlen16to8(const char16_t* utf16Str, size_t len) | ||
50 | 100 | * |
51 | 101 | * Make sure you allocate "utf8Str" with the result of strlen16to8() + 1, |
52 | 102 | * not just "len". |
53 | - * | |
103 | + * | |
54 | 104 | * Please note, a terminated \0 is always added, so your result will always |
55 | 105 | * be "strlen16to8() + 1" bytes long. |
56 | 106 | */ |
@@ -58,6 +108,10 @@ extern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len) | ||
58 | 108 | { |
59 | 109 | char* utf8cur = utf8Str; |
60 | 110 | |
111 | + /* Note on overflows: We assume the user did check the result of | |
112 | + * strnlen16to8() properly or at a minimum checked the result of | |
113 | + * its malloc(SIZE_MAX) in case of overflow. | |
114 | + */ | |
61 | 115 | while (len--) { |
62 | 116 | unsigned int uic = *utf16Str++; |
63 | 117 |
@@ -73,8 +127,8 @@ extern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len) | ||
73 | 127 | |
74 | 128 | if (uic == 0) { |
75 | 129 | break; |
76 | - } | |
77 | - } | |
130 | + } | |
131 | + } | |
78 | 132 | } |
79 | 133 | |
80 | 134 | *utf8cur = '\0'; |
@@ -85,20 +139,30 @@ extern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len) | ||
85 | 139 | /** |
86 | 140 | * Convert a UTF-16 string to UTF-8. |
87 | 141 | * |
88 | - * Make sure you allocate "dest" with the result of strblen16to8(), | |
89 | - * not just "strlen16()". | |
90 | 142 | */ |
91 | 143 | char * strndup16to8 (const char16_t* s, size_t n) |
92 | 144 | { |
93 | - char *ret; | |
145 | + char* ret; | |
146 | + size_t len; | |
94 | 147 | |
95 | 148 | if (s == NULL) { |
96 | 149 | return NULL; |
97 | 150 | } |
98 | 151 | |
99 | - ret = malloc(strnlen16to8(s, n) + 1); | |
152 | + len = strnlen16to8(s, n); | |
153 | + | |
154 | + /* We are paranoid, and we check for SIZE_MAX-1 | |
155 | + * too since it is an overflow value for our | |
156 | + * strnlen16to8 implementation. | |
157 | + */ | |
158 | + if (len >= SIZE_MAX-1) | |
159 | + return NULL; | |
160 | + | |
161 | + ret = malloc(len + 1); | |
162 | + if (ret == NULL) | |
163 | + return NULL; | |
100 | 164 | |
101 | 165 | strncpy16to8 (ret, s, n); |
102 | - | |
103 | - return ret; | |
166 | + | |
167 | + return ret; | |
104 | 168 | } |
@@ -0,0 +1,21 @@ | ||
1 | +LOCAL_PATH:= $(call my-dir) | |
2 | + | |
3 | +include $(CLEAR_VARS) | |
4 | + | |
5 | +LOCAL_SRC_FILES:= \ | |
6 | + src/FrameworkManager.cpp \ | |
7 | + src/SocketListener.cpp \ | |
8 | + src/FrameworkListener.cpp \ | |
9 | + src/NetlinkListener.cpp \ | |
10 | + src/NetlinkEvent.cpp \ | |
11 | + src/FrameworkCommand.cpp \ | |
12 | + | |
13 | +LOCAL_MODULE:= libsysutils | |
14 | + | |
15 | +LOCAL_C_INCLUDES := $(KERNEL_HEADERS) | |
16 | + | |
17 | +LOCAL_CFLAGS := | |
18 | + | |
19 | +LOCAL_SHARED_LIBRARIES := libcutils | |
20 | + | |
21 | +include $(BUILD_SHARED_LIBRARY) |
@@ -0,0 +1,32 @@ | ||
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 <errno.h> | |
17 | + | |
18 | +#define LOG_TAG "FrameworkCommand" | |
19 | + | |
20 | +#include <cutils/log.h> | |
21 | + | |
22 | +#include <sysutils/FrameworkCommand.h> | |
23 | + | |
24 | +FrameworkCommand::FrameworkCommand(const char *cmd) { | |
25 | + mCommand = cmd; | |
26 | +} | |
27 | + | |
28 | +int FrameworkCommand::runCommand(char *data) { | |
29 | + LOGW("Command %s has no run handler!", getCommand()); | |
30 | + errno = ENOSYS; | |
31 | + return -1; | |
32 | +} |
@@ -0,0 +1,77 @@ | ||
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 <errno.h> | |
17 | +#include <string.h> | |
18 | + | |
19 | +#define LOG_TAG "FrameworkListener" | |
20 | + | |
21 | +#include <cutils/log.h> | |
22 | + | |
23 | +#include <sysutils/FrameworkListener.h> | |
24 | +#include <sysutils/FrameworkCommand.h> | |
25 | + | |
26 | +FrameworkListener::FrameworkListener(const char *socketName) : | |
27 | + SocketListener(socketName, true) { | |
28 | + mCommands = new FrameworkCommandCollection(); | |
29 | +} | |
30 | + | |
31 | +bool FrameworkListener::onDataAvailable(int socket) { | |
32 | + char buffer[101]; | |
33 | + int len; | |
34 | + | |
35 | + if ((len = read(socket, buffer, sizeof(buffer) -1)) < 0) { | |
36 | + LOGE("read() failed (%s)", strerror(errno)); | |
37 | + return errno; | |
38 | + } else if (!len) { | |
39 | + LOGW("Lost connection to client"); | |
40 | + return false; | |
41 | + } | |
42 | + | |
43 | + int start = 0; | |
44 | + int i; | |
45 | + | |
46 | + buffer[len] = '\0'; | |
47 | + | |
48 | + for (i = 0; i < len; i++) { | |
49 | + if (buffer[i] == '\0') { | |
50 | + dispatchCommand(buffer + start); | |
51 | + start = i + 1; | |
52 | + } | |
53 | + } | |
54 | + return true; | |
55 | +} | |
56 | + | |
57 | +void FrameworkListener::registerCmd(FrameworkCommand *cmd) { | |
58 | + mCommands->push_back(cmd); | |
59 | +} | |
60 | + | |
61 | +void FrameworkListener::dispatchCommand(char *cmd) { | |
62 | + FrameworkCommandCollection::iterator i; | |
63 | + | |
64 | + for (i = mCommands->begin(); i != mCommands->end(); ++i) { | |
65 | + FrameworkCommand *c = *i; | |
66 | + | |
67 | + if (!strncmp(cmd, c->getCommand(), strlen(c->getCommand()))) { | |
68 | + if (c->runCommand(cmd)) { | |
69 | + LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno)); | |
70 | + } | |
71 | + return; | |
72 | + } | |
73 | + } | |
74 | + | |
75 | + LOGE("No cmd handlers defined for '%s'", cmd); | |
76 | +} | |
77 | + |
@@ -0,0 +1,83 @@ | ||
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 | +} |
@@ -0,0 +1,94 @@ | ||
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 <stdlib.h> | |
17 | +#include <string.h> | |
18 | + | |
19 | +#define LOG_TAG "NetlinkEvent" | |
20 | +#include <cutils/log.h> | |
21 | + | |
22 | +#include <sysutils/NetlinkEvent.h> | |
23 | + | |
24 | +const int NetlinkEvent::NlActionUnknown = 0; | |
25 | +const int NetlinkEvent::NlActionAdd = 1; | |
26 | +const int NetlinkEvent::NlActionRemove = 2; | |
27 | +const int NetlinkEvent::NlActionChange = 3; | |
28 | + | |
29 | +NetlinkEvent::NetlinkEvent() { | |
30 | + mAction = NlActionUnknown; | |
31 | +} | |
32 | + | |
33 | +NetlinkEvent::~NetlinkEvent() { | |
34 | + int i; | |
35 | + if (mPath) | |
36 | + free(mPath); | |
37 | + if (mSubsystem) | |
38 | + free(mSubsystem); | |
39 | + for (i = 0; i < NL_PARAMS_MAX; i++) { | |
40 | + if (!mParams[i]) | |
41 | + break; | |
42 | + free(mParams[i]); | |
43 | + } | |
44 | +} | |
45 | + | |
46 | +bool NetlinkEvent::decode(char *buffer, int size) { | |
47 | + char *s = buffer; | |
48 | + char *end; | |
49 | + int param_idx = 0; | |
50 | + int i; | |
51 | + int first = 1; | |
52 | + | |
53 | + end = s + size; | |
54 | + while (s < end) { | |
55 | + if (first) { | |
56 | + char *p; | |
57 | + for (p = s; *p != '@'; p++); | |
58 | + p++; | |
59 | + mPath = strdup(p); | |
60 | + first = 0; | |
61 | + } else { | |
62 | + if (!strncmp(s, "ACTION=", strlen("ACTION="))) { | |
63 | + char *a = s + strlen("ACTION="); | |
64 | + if (!strcmp(a, "add")) | |
65 | + mAction = NlActionAdd; | |
66 | + else if (!strcmp(a, "remove")) | |
67 | + mAction = NlActionRemove; | |
68 | + else if (!strcmp(a, "change")) | |
69 | + mAction = NlActionChange; | |
70 | + } else if (!strncmp(s, "SEQNUM=", strlen("SEQNUM="))) | |
71 | + mSeq = atoi(s + strlen("SEQNUM=")); | |
72 | + else if (!strncmp(s, "SUBSYSTEM=", strlen("SUBSYSTEM="))) | |
73 | + mSubsystem = strdup(s + strlen("SUBSYSTEM=")); | |
74 | + else | |
75 | + mParams[param_idx++] = strdup(s); | |
76 | + } | |
77 | + s+= strlen(s) + 1; | |
78 | + } | |
79 | + return true; | |
80 | +} | |
81 | + | |
82 | +const char *NetlinkEvent::findParam(const char *paramName) { | |
83 | + int i; | |
84 | + | |
85 | + for (i = 0; i < NL_PARAMS_MAX; i++) { | |
86 | + if (!mParams[i]) | |
87 | + break; | |
88 | + if (!strncmp(mParams[i], paramName, strlen(paramName))) | |
89 | + return &mParams[i][strlen(paramName) + 1]; | |
90 | + } | |
91 | + | |
92 | + LOGE("NetlinkEvent::FindParam(): Parameter '%s' not found", paramName); | |
93 | + return NULL; | |
94 | +} |
@@ -0,0 +1,54 @@ | ||
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 <errno.h> | |
17 | + | |
18 | +#include <sys/types.h> | |
19 | +#include <sys/socket.h> | |
20 | +#include <string.h> | |
21 | + | |
22 | +#define LOG_TAG "NetlinkListener" | |
23 | +#include <cutils/log.h> | |
24 | + | |
25 | +#include <sysutils/NetlinkListener.h> | |
26 | +#include <sysutils/NetlinkEvent.h> | |
27 | + | |
28 | +NetlinkListener::NetlinkListener(int socket) : | |
29 | + SocketListener(socket, false) { | |
30 | +} | |
31 | + | |
32 | +bool NetlinkListener::onDataAvailable(int socket) | |
33 | +{ | |
34 | + LOGD("NetlinkListener::onDataAvailable()"); | |
35 | + | |
36 | + int count; | |
37 | + | |
38 | + if ((count = recv(socket, mBuffer, sizeof(mBuffer), 0)) < 0) { | |
39 | + LOGE("recv failed (%s)", strerror(errno)); | |
40 | + return false; | |
41 | + } | |
42 | + | |
43 | + NetlinkEvent *evt = new NetlinkEvent(); | |
44 | + if (!evt->decode(mBuffer, count)) { | |
45 | + LOGE("Error decoding NetlinkEvent"); | |
46 | + goto out; | |
47 | + } | |
48 | + | |
49 | + LOGD("Ignoring '%s' netlink event", evt->getSubsystem()); | |
50 | + | |
51 | +out: | |
52 | + delete evt; | |
53 | + return true; | |
54 | +} |
@@ -0,0 +1,127 @@ | ||
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 | +#define LOG_TAG "SocketListener" | |
26 | +#include <cutils/log.h> | |
27 | + | |
28 | +#include <cutils/sockets.h> | |
29 | + | |
30 | +#include <sysutils/SocketListener.h> | |
31 | + | |
32 | +SocketListener::SocketListener(const char *socketName, bool acceptClients) { | |
33 | + mAcceptClients = acceptClients; | |
34 | + mCsock = -1; | |
35 | + mSocketName = socketName; | |
36 | + mSock = -1; | |
37 | +} | |
38 | + | |
39 | +SocketListener::SocketListener(int socketFd, bool acceptClients) { | |
40 | + mAcceptClients = acceptClients; | |
41 | + mCsock = -1; | |
42 | + mSocketName = NULL; | |
43 | + mSock = socketFd; | |
44 | +} | |
45 | + | |
46 | +int SocketListener::run() { | |
47 | + | |
48 | + if (!mSocketName && mSock == -1) { | |
49 | + errno = EINVAL; | |
50 | + return -1; | |
51 | + } else if (mSocketName) { | |
52 | + if ((mSock = android_get_control_socket(mSocketName)) < 0) { | |
53 | + LOGE("Obtaining file descriptor socket '%s' failed: %s", | |
54 | + mSocketName, strerror(errno)); | |
55 | + return -1; | |
56 | + } | |
57 | + } | |
58 | + | |
59 | + if (mAcceptClients) { | |
60 | + if (listen(mSock, 4) < 0) { | |
61 | + LOGE("Unable to listen on socket (%s)", strerror(errno)); | |
62 | + return -1; | |
63 | + } | |
64 | + } | |
65 | + | |
66 | + while(1) { | |
67 | + fd_set read_fds; | |
68 | + struct timeval to; | |
69 | + int max = 0; | |
70 | + int rc = 0; | |
71 | + | |
72 | + to.tv_sec = 60 * 60; | |
73 | + to.tv_usec = 0; | |
74 | + | |
75 | + FD_ZERO(&read_fds); | |
76 | + | |
77 | + if ((mAcceptClients == false) || | |
78 | + (mAcceptClients == true && mCsock == -1)) { | |
79 | + FD_SET(mSock, &read_fds); | |
80 | + max = mSock; | |
81 | + } else if (mCsock != -1) { | |
82 | + FD_SET(mCsock, &read_fds); | |
83 | + max = mCsock; | |
84 | + } | |
85 | + | |
86 | + if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) { | |
87 | + LOGE("select failed (%s)", strerror(errno)); | |
88 | + return -errno; | |
89 | + } else if (!rc) | |
90 | + 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; | |
110 | + } | |
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; | |
120 | + } | |
121 | + } | |
122 | + return 0; | |
123 | +} | |
124 | + | |
125 | +bool SocketListener::onDataAvailable(int socket) { | |
126 | + return false; | |
127 | +} |
@@ -0,0 +1,47 @@ | ||
1 | +BUILD_NEXUS := false | |
2 | +ifeq ($(BUILD_NEXUS),true) | |
3 | + | |
4 | +LOCAL_PATH:= $(call my-dir) | |
5 | + | |
6 | +include $(CLEAR_VARS) | |
7 | + | |
8 | +LOCAL_SRC_FILES:= \ | |
9 | + main.cpp \ | |
10 | + NetworkManager.cpp \ | |
11 | + CommandListener.cpp \ | |
12 | + Controller.cpp \ | |
13 | + WifiController.cpp \ | |
14 | + LoopController.cpp \ | |
15 | + NexusCommand.cpp \ | |
16 | + TiwlanWifiController.cpp \ | |
17 | + Supplicant.cpp \ | |
18 | + SupplicantEvent.cpp \ | |
19 | + SupplicantListener.cpp \ | |
20 | + VpnController.cpp \ | |
21 | + ScanResult.cpp \ | |
22 | + | |
23 | +LOCAL_MODULE:= nexus | |
24 | + | |
25 | +LOCAL_C_INCLUDES := $(KERNEL_HEADERS) | |
26 | + | |
27 | +LOCAL_CFLAGS := | |
28 | + | |
29 | +LOCAL_SHARED_LIBRARIES := libsysutils libwpa_client libutils | |
30 | + | |
31 | +include $(BUILD_EXECUTABLE) | |
32 | + | |
33 | +include $(CLEAR_VARS) | |
34 | +LOCAL_SRC_FILES:= \ | |
35 | + nexctl.c \ | |
36 | + | |
37 | +LOCAL_MODULE:= nexctl | |
38 | + | |
39 | +LOCAL_C_INCLUDES := $(KERNEL_HEADERS) | |
40 | + | |
41 | +LOCAL_CFLAGS := | |
42 | + | |
43 | +LOCAL_SHARED_LIBRARIES := libutils | |
44 | + | |
45 | +include $(BUILD_EXECUTABLE) | |
46 | + | |
47 | +endif # ifeq ($(BUILD_NEXUS),true) |
@@ -0,0 +1,124 @@ | ||
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 <stdlib.h> | |
17 | +#include <errno.h> | |
18 | + | |
19 | +#define LOG_TAG "CommandListener" | |
20 | +#include <cutils/log.h> | |
21 | + | |
22 | +#include "CommandListener.h" | |
23 | +#include "Controller.h" | |
24 | +#include "NetworkManager.h" | |
25 | +#include "WifiController.h" | |
26 | + | |
27 | +CommandListener::CommandListener(NetworkManager *netman) : | |
28 | + FrameworkListener("nexus") { | |
29 | + mNetman = netman; | |
30 | + | |
31 | + registerCmd(new WifiEnableCmd(netman)); | |
32 | + registerCmd(new WifiDisableCmd(netman)); | |
33 | + registerCmd(new WifiScanCmd(netman)); | |
34 | + | |
35 | + registerCmd(new VpnEnableCmd(netman)); | |
36 | + registerCmd(new VpnDisableCmd(netman)); | |
37 | +} | |
38 | + | |
39 | +/* ------------- | |
40 | + * Wifi Commands | |
41 | + * ------------ */ | |
42 | + | |
43 | +CommandListener::WifiEnableCmd::WifiEnableCmd(NetworkManager *netman) : | |
44 | + NexusCommand("wifi_enable", netman) { | |
45 | +} | |
46 | + | |
47 | +int CommandListener::WifiEnableCmd::runCommand(char *data) { | |
48 | + Controller *c = mNetman->findController("WIFI"); | |
49 | + char buffer[32]; | |
50 | + | |
51 | + sprintf(buffer, "WIFI_ENABLE:%d", (c->enable() ? errno : 0)); | |
52 | + mNetman->getFrameworkManager()->sendMsg(buffer); | |
53 | + return 0; | |
54 | +} | |
55 | + | |
56 | +CommandListener::WifiDisableCmd::WifiDisableCmd(NetworkManager *netman) : | |
57 | + NexusCommand("wifi_disable", netman) { | |
58 | +} | |
59 | + | |
60 | +int CommandListener::WifiDisableCmd::runCommand(char *data) { | |
61 | + Controller *c = mNetman->findController("WIFI"); | |
62 | + char buffer[32]; | |
63 | + | |
64 | + sprintf(buffer, "WIFI_DISABLE:%d", (c->disable() ? errno : 0)); | |
65 | + mNetman->getFrameworkManager()->sendMsg(buffer); | |
66 | + return 0; | |
67 | +} | |
68 | + | |
69 | +CommandListener::WifiScanCmd::WifiScanCmd(NetworkManager *netman) : | |
70 | + NexusCommand("wifi_scan", netman) { | |
71 | +} | |
72 | + | |
73 | +int CommandListener::WifiScanCmd::runCommand(char *data) { | |
74 | + LOGD("WifiScanCmd(%s)", data); | |
75 | + WifiController *wc = (WifiController *) mNetman->findController("WIFI"); | |
76 | + char buffer[32]; | |
77 | + int mode = 0; | |
78 | + char *bword, *last; | |
79 | + | |
80 | + if (!(bword = strtok_r(data, ":", &last))) { | |
81 | + errno = EINVAL; | |
82 | + return -1; | |
83 | + } | |
84 | + | |
85 | + if (!(bword = strtok_r(NULL, ":", &last))) { | |
86 | + errno = EINVAL; | |
87 | + return -1; | |
88 | + } | |
89 | + | |
90 | + mode = atoi(bword); | |
91 | + | |
92 | + sprintf(buffer, "WIFI_SCAN:%d", (wc->setScanMode(mode) ? errno : 0)); | |
93 | + mNetman->getFrameworkManager()->sendMsg(buffer); | |
94 | + return 0; | |
95 | +} | |
96 | + | |
97 | +/* ------------ | |
98 | + * Vpn Commands | |
99 | + * ------------ */ | |
100 | +CommandListener::VpnEnableCmd::VpnEnableCmd(NetworkManager *netman) : | |
101 | + NexusCommand("vpn_enable", netman) { | |
102 | +} | |
103 | + | |
104 | +int CommandListener::VpnEnableCmd::runCommand(char *data) { | |
105 | + Controller *c = mNetman->findController("VPN"); | |
106 | + char buffer[32]; | |
107 | + | |
108 | + sprintf(buffer, "VPN_ENABLE:%d", (c->enable() ? errno : 0)); | |
109 | + mNetman->getFrameworkManager()->sendMsg(buffer); | |
110 | + return 0; | |
111 | +} | |
112 | + | |
113 | +CommandListener::VpnDisableCmd::VpnDisableCmd(NetworkManager *netman) : | |
114 | + NexusCommand("vpn_disable", netman) { | |
115 | +} | |
116 | + | |
117 | +int CommandListener::VpnDisableCmd::runCommand(char *data) { | |
118 | + Controller *c = mNetman->findController("VPN"); | |
119 | + char buffer[32]; | |
120 | + | |
121 | + sprintf(buffer, "VPN_DISABLE:%d", (c->disable() ? errno : 0)); | |
122 | + mNetman->getFrameworkManager()->sendMsg(buffer); | |
123 | + return 0; | |
124 | +} |
@@ -0,0 +1,70 @@ | ||
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 _COMMANDLISTENER_H__ | |
17 | +#define _COMMANDLISTENER_H__ | |
18 | + | |
19 | +#include <sysutils/FrameworkListener.h> | |
20 | +#include "NexusCommand.h" | |
21 | + | |
22 | +class NetworkManager; | |
23 | + | |
24 | +class CommandListener : public FrameworkListener { | |
25 | +protected: | |
26 | + NetworkManager *mNetman; | |
27 | + | |
28 | +public: | |
29 | + CommandListener(NetworkManager *netman); | |
30 | + virtual ~CommandListener() {} | |
31 | + | |
32 | +private: | |
33 | + class WifiEnableCmd : public NexusCommand { | |
34 | + public: | |
35 | + WifiEnableCmd(NetworkManager *); | |
36 | + virtual ~WifiEnableCmd() {} | |
37 | + int runCommand(char *data); | |
38 | + }; | |
39 | + | |
40 | + class WifiDisableCmd : public NexusCommand { | |
41 | + public: | |
42 | + WifiDisableCmd(NetworkManager *); | |
43 | + virtual ~WifiDisableCmd() {} | |
44 | + int runCommand(char *data); | |
45 | + }; | |
46 | + | |
47 | + class WifiScanCmd : public NexusCommand { | |
48 | + public: | |
49 | + WifiScanCmd(NetworkManager *); | |
50 | + virtual ~WifiScanCmd() {} | |
51 | + int runCommand(char *data); | |
52 | + }; | |
53 | + | |
54 | + class VpnEnableCmd : public NexusCommand { | |
55 | + public: | |
56 | + VpnEnableCmd(NetworkManager *); | |
57 | + virtual ~VpnEnableCmd() {} | |
58 | + int runCommand(char *data); | |
59 | + }; | |
60 | + | |
61 | + class VpnDisableCmd : public NexusCommand { | |
62 | + public: | |
63 | + VpnDisableCmd(NetworkManager *); | |
64 | + virtual ~VpnDisableCmd() {} | |
65 | + int runCommand(char *data); | |
66 | + }; | |
67 | + | |
68 | +}; | |
69 | + | |
70 | +#endif |
@@ -0,0 +1,144 @@ | ||
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 <string.h> | |
18 | +#include <fcntl.h> | |
19 | +#include <unistd.h> | |
20 | +#include <malloc.h> | |
21 | +#include <errno.h> | |
22 | +#include <sys/types.h> | |
23 | +#include <sys/stat.h> | |
24 | +#include <unistd.h> | |
25 | + | |
26 | +#define LOG_TAG "Controller" | |
27 | + | |
28 | +#include <cutils/log.h> | |
29 | + | |
30 | +#include "Controller.h" | |
31 | + | |
32 | +extern "C" int init_module(void *, unsigned int, const char *); | |
33 | +extern "C" int delete_module(const char *, unsigned int); | |
34 | + | |
35 | +Controller::Controller(const char *name) { | |
36 | + mName = name; | |
37 | +} | |
38 | + | |
39 | +int Controller::start() { | |
40 | + return 0; | |
41 | +} | |
42 | + | |
43 | +int Controller::stop() { | |
44 | + return 0; | |
45 | +} | |
46 | + | |
47 | +int Controller::loadKernelModule(char *modpath, const char *args) { | |
48 | + void *module; | |
49 | + unsigned int size; | |
50 | + | |
51 | + LOGD("loadKernelModule(%s, %s)", modpath, args); | |
52 | + | |
53 | + module = loadFile(modpath, &size); | |
54 | + if (!module) { | |
55 | + errno = -EIO; | |
56 | + return -1; | |
57 | + } | |
58 | + | |
59 | + int rc = init_module(module, size, args); | |
60 | + free (module); | |
61 | + return rc; | |
62 | +} | |
63 | + | |
64 | +int Controller::unloadKernelModule(const char *modtag) { | |
65 | + int rc = -1; | |
66 | + int retries = 10; | |
67 | + | |
68 | + LOGD("unloadKernelModule(%s)", modtag); | |
69 | + while (retries--) { | |
70 | + rc = delete_module(modtag, O_NONBLOCK | O_EXCL); | |
71 | + if (rc < 0 && errno == EAGAIN) | |
72 | + usleep(1000*500); | |
73 | + else | |
74 | + break; | |
75 | + } | |
76 | + | |
77 | + if (rc != 0) { | |
78 | + LOGW("Unable to unload kernel driver '%s' (%s)", modtag, | |
79 | + strerror(errno)); | |
80 | + } | |
81 | + return rc; | |
82 | +} | |
83 | + | |
84 | +bool Controller::isKernelModuleLoaded(const char *modtag) { | |
85 | + FILE *fp = fopen("/proc/modules", "r"); | |
86 | + | |
87 | + if (!fp) { | |
88 | + LOGE("Unable to open /proc/modules (%s)", strerror(errno)); | |
89 | + return false; | |
90 | + } | |
91 | + | |
92 | + char line[255]; | |
93 | + while(fgets(line, sizeof(line), fp)) { | |
94 | + char *endTag = strchr(line, ' '); | |
95 | + | |
96 | + if (!endTag) { | |
97 | + LOGW("Unable to find tag for line '%s'", line); | |
98 | + continue; | |
99 | + } | |
100 | + if (!strncmp(line, modtag, (endTag - line))) { | |
101 | + fclose(fp); | |
102 | + return true; | |
103 | + } | |
104 | + } | |
105 | + | |
106 | + fclose(fp); | |
107 | + return false; | |
108 | +} | |
109 | + | |
110 | + | |
111 | +void *Controller::loadFile(char *filename, unsigned int *_size) | |
112 | +{ | |
113 | + int ret, fd; | |
114 | + struct stat sb; | |
115 | + ssize_t size; | |
116 | + void *buffer = NULL; | |
117 | + | |
118 | + /* open the file */ | |
119 | + fd = open(filename, O_RDONLY); | |
120 | + if (fd < 0) | |
121 | + return NULL; | |
122 | + | |
123 | + /* find out how big it is */ | |
124 | + if (fstat(fd, &sb) < 0) | |
125 | + goto bail; | |
126 | + size = sb.st_size; | |
127 | + | |
128 | + /* allocate memory for it to be read into */ | |
129 | + buffer = malloc(size); | |
130 | + if (!buffer) | |
131 | + goto bail; | |
132 | + | |
133 | + /* slurp it into our buffer */ | |
134 | + ret = read(fd, buffer, size); | |
135 | + if (ret != size) | |
136 | + goto bail; | |
137 | + | |
138 | + /* let the caller know how big it is */ | |
139 | + *_size = size; | |
140 | + | |
141 | +bail: | |
142 | + close(fd); | |
143 | + return buffer; | |
144 | +} |
@@ -0,0 +1,47 @@ | ||
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 _CONTROLLER_H | |
17 | +#define _CONTROLLER_H | |
18 | + | |
19 | +#include "../../../frameworks/base/include/utils/List.h" | |
20 | + | |
21 | +class Controller { | |
22 | +private: | |
23 | + const char *mName; | |
24 | + | |
25 | +public: | |
26 | + Controller(const char *name); | |
27 | + virtual ~Controller() {} | |
28 | + | |
29 | + virtual int start(); | |
30 | + virtual int stop(); | |
31 | + | |
32 | + virtual int enable() = 0; | |
33 | + virtual int disable() = 0; | |
34 | + | |
35 | + virtual const char *getName() { return mName; } | |
36 | + | |
37 | +protected: | |
38 | + int loadKernelModule(char *modpath, const char *args); | |
39 | + bool isKernelModuleLoaded(const char *modtag); | |
40 | + int unloadKernelModule(const char *modtag); | |
41 | + | |
42 | +private: | |
43 | + void *loadFile(char *filename, unsigned int *_size); | |
44 | +}; | |
45 | + | |
46 | +typedef android::List<Controller *> ControllerCollection; | |
47 | +#endif |
@@ -0,0 +1,32 @@ | ||
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 <errno.h> | |
17 | + | |
18 | +#include "LoopController.h" | |
19 | + | |
20 | +LoopController::LoopController() : | |
21 | + Controller("LOOP") { | |
22 | +} | |
23 | + | |
24 | +int LoopController::enable() { | |
25 | + errno = ENOSYS; | |
26 | + return -1; | |
27 | +} | |
28 | + | |
29 | +int LoopController::disable() { | |
30 | + errno = ENOSYS; | |
31 | + return -1; | |
32 | +} |
@@ -0,0 +1,30 @@ | ||
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 _LOOP_CONTROLLER_H | |
17 | +#define _LOOP_CONTROLLER_H | |
18 | + | |
19 | +#include "Controller.h" | |
20 | + | |
21 | +class LoopController : public Controller { | |
22 | +public: | |
23 | + LoopController(); | |
24 | + virtual ~LoopController() {} | |
25 | + | |
26 | + int enable(); | |
27 | + int disable(); | |
28 | +}; | |
29 | + | |
30 | +#endif |
@@ -0,0 +1,100 @@ | ||
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 | + | |
19 | +#define LOG_TAG "Nexus" | |
20 | + | |
21 | +#include <cutils/log.h> | |
22 | + | |
23 | +#include "NetworkManager.h" | |
24 | +#include "CommandListener.h" | |
25 | +#include "LoopController.h" | |
26 | +#include "VpnController.h" | |
27 | + | |
28 | +#include "TiwlanWifiController.h" | |
29 | + | |
30 | +NetworkManager::NetworkManager() { | |
31 | + mListener = new CommandListener(this); | |
32 | + mFm = new FrameworkManager(mListener); | |
33 | + mControllers = new ControllerCollection(); | |
34 | +} | |
35 | + | |
36 | +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 | + if (startControllers()) { | |
46 | + LOGW("Unable to start all controllers (%s)", strerror(errno)); | |
47 | + } | |
48 | + mFm->run(); | |
49 | + return 0; | |
50 | +} | |
51 | + | |
52 | +void NetworkManager::addController(Controller *c) { | |
53 | + mControllers->push_back(c); | |
54 | +} | |
55 | + | |
56 | +int NetworkManager::startControllers() { | |
57 | + int rc = 0; | |
58 | + ControllerCollection::iterator i; | |
59 | + | |
60 | + for (i = mControllers->begin(); i != mControllers->end(); ++i) { | |
61 | + int irc = (*i)->start(); | |
62 | + LOGD("Controller '%s' start rc = %d", (*i)->getName(), irc); | |
63 | + if (irc && !rc) | |
64 | + rc = irc; | |
65 | + } | |
66 | + return rc; | |
67 | +} | |
68 | + | |
69 | +int NetworkManager::stopControllers() { | |
70 | + int rc = 0; | |
71 | + ControllerCollection::iterator i; | |
72 | + | |
73 | + for (i = mControllers->begin(); i != mControllers->end(); ++i) { | |
74 | + int irc = (*i)->stop(); | |
75 | + LOGD("Controller '%s' stop rc = %d", (*i)->getName(), irc); | |
76 | + if (irc && !rc) | |
77 | + rc = irc; | |
78 | + } | |
79 | + return rc; | |
80 | +} | |
81 | + | |
82 | +Controller *NetworkManager::findController(const char *name) { | |
83 | + ControllerCollection::iterator i; | |
84 | + for (i = mControllers->begin(); i != mControllers->end(); ++i) { | |
85 | + if (!strcmp((*i)->getName(), name)) | |
86 | + return *i; | |
87 | + } | |
88 | + LOGW("Controller '%s' not found", name); | |
89 | + return NULL; | |
90 | +} | |
91 | + | |
92 | +int NetworkManager::onInterfaceCreated(Controller *c, char *name) { | |
93 | + LOGD("Interface %s created by controller %s", name, c->getName()); | |
94 | + return 0; | |
95 | +} | |
96 | + | |
97 | +int NetworkManager::onInterfaceDestroyed(Controller *c, char *name) { | |
98 | + LOGD("Interface %s destroyed by controller %s", name, c->getName()); | |
99 | + return 0; | |
100 | +} |
@@ -0,0 +1,51 @@ | ||
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 _NETWORKMANAGER_H | |
17 | +#define _NETWORKMANAGER_H | |
18 | + | |
19 | +#include "Controller.h" | |
20 | + | |
21 | +#include <sysutils/FrameworkManager.h> | |
22 | + | |
23 | +class NetworkManager { | |
24 | +private: | |
25 | + FrameworkListener *mListener; | |
26 | + FrameworkManager *mFm; | |
27 | + ControllerCollection *mControllers; | |
28 | + | |
29 | +public: | |
30 | + NetworkManager(); | |
31 | + virtual ~NetworkManager() {} | |
32 | + | |
33 | + int run(); | |
34 | + | |
35 | +private: | |
36 | + void addController(Controller *c); | |
37 | + int startControllers(); | |
38 | + int stopControllers(); | |
39 | + | |
40 | +public: | |
41 | + Controller *findController(const char *name); | |
42 | + ControllerCollection *getControllers() { return mControllers; } | |
43 | + FrameworkManager *getFrameworkManager() { return mFm; } | |
44 | + | |
45 | +public: | |
46 | +// XXX: Extract these into an interface | |
47 | + int onInterfaceCreated(Controller *c, char *name); | |
48 | + int onInterfaceDestroyed(Controller *c, char *name); | |
49 | + | |
50 | +}; | |
51 | +#endif |
@@ -0,0 +1,21 @@ | ||
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 "NexusCommand.h" | |
17 | + | |
18 | +NexusCommand::NexusCommand(const char *cmd, NetworkManager *netman) : | |
19 | + FrameworkCommand(cmd) { | |
20 | + mNetman = netman; | |
21 | +} |
@@ -0,0 +1,32 @@ | ||
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 _NEXUS_COMMAND_H | |
17 | +#define _NEXUS_COMMAND_H | |
18 | + | |
19 | +#include <sysutils/FrameworkCommand.h> | |
20 | + | |
21 | +class NetworkManager; | |
22 | + | |
23 | +class NexusCommand : public FrameworkCommand { | |
24 | +protected: | |
25 | + NetworkManager *mNetman; | |
26 | + | |
27 | +public: | |
28 | + NexusCommand(const char *cmd, NetworkManager *netman); | |
29 | + virtual ~NexusCommand() {} | |
30 | +}; | |
31 | + | |
32 | +#endif |
@@ -0,0 +1,74 @@ | ||
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 <stdlib.h> | |
17 | + | |
18 | +#define LOG_TAG "ScanResult" | |
19 | +#include <cutils/log.h> | |
20 | + | |
21 | +#include "ScanResult.h" | |
22 | + | |
23 | +ScanResult::ScanResult() { | |
24 | +} | |
25 | + | |
26 | +ScanResult::ScanResult(char *rawResult) { | |
27 | + char *tok, *next = NULL; | |
28 | + | |
29 | + if (!(tok = strtok_r(rawResult, "\t", &next))) | |
30 | + goto out_bad; | |
31 | + mBssid = strdup(tok); | |
32 | + | |
33 | + if (!(tok = strtok_r(NULL, "\t", &next))) | |
34 | + goto out_bad; | |
35 | + mFreq = atoi(tok); | |
36 | + | |
37 | + if (!(tok = strtok_r(NULL, "\t", &next))) | |
38 | + goto out_bad; | |
39 | + mLevel = atoi(tok); | |
40 | + | |
41 | + if (!(tok = strtok_r(rawResult, "\t", &next))) | |
42 | + goto out_bad; | |
43 | + mFlags = strdup(tok); | |
44 | + | |
45 | + if (!(tok = strtok_r(rawResult, "\t", &next))) | |
46 | + goto out_bad; | |
47 | + mSsid = strdup(tok); | |
48 | + | |
49 | + return; | |
50 | + | |
51 | + out_bad: | |
52 | + LOGW("Malformatted scan result (%s)", rawResult); | |
53 | +} | |
54 | + | |
55 | +ScanResult::~ScanResult() { | |
56 | + if (mBssid) | |
57 | + free(mBssid); | |
58 | + if (mFlags) | |
59 | + free(mFlags); | |
60 | + if (mSsid) | |
61 | + free(mSsid); | |
62 | +} | |
63 | + | |
64 | +ScanResult *ScanResult::clone() { | |
65 | + ScanResult *r = new ScanResult(); | |
66 | + | |
67 | + r->mBssid = strdup(mBssid); | |
68 | + r->mFreq = mFreq; | |
69 | + r->mLevel = mLevel; | |
70 | + r->mFlags = strdup(mFlags); | |
71 | + r->mSsid = strdup(mSsid); | |
72 | + | |
73 | + return r; | |
74 | +} |
@@ -0,0 +1,47 @@ | ||
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 _SCAN_RESULT_H | |
17 | +#define _SCAN_RESULT_H | |
18 | + | |
19 | +#include <sys/types.h> | |
20 | + | |
21 | +#include "../../../frameworks/base/include/utils/List.h" | |
22 | + | |
23 | +class ScanResult { | |
24 | + char *mBssid; | |
25 | + uint32_t mFreq; | |
26 | + int mLevel; | |
27 | + char *mFlags; | |
28 | + char *mSsid; | |
29 | + | |
30 | +private: | |
31 | + ScanResult(); | |
32 | + | |
33 | +public: | |
34 | + ScanResult(char *rawResult); | |
35 | + virtual ~ScanResult(); | |
36 | + | |
37 | + ScanResult *clone(); | |
38 | + | |
39 | + const char *getBssid() { return mBssid; } | |
40 | + uint32_t getFreq() { return mFreq; } | |
41 | + const char *getFlags() { return mFlags; } | |
42 | + const char *getSsid() { return mSsid; } | |
43 | +}; | |
44 | + | |
45 | +typedef android::List<ScanResult *> ScanResultCollection; | |
46 | + | |
47 | +#endif |
@@ -0,0 +1,377 @@ | ||
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 <errno.h> | |
17 | + | |
18 | +#define LOG_TAG "Supplicant" | |
19 | +#include <cutils/log.h> | |
20 | +#include <cutils/properties.h> | |
21 | + | |
22 | +#undef HAVE_LIBC_SYSTEM_PROPERTIES | |
23 | + | |
24 | +#ifdef HAVE_LIBC_SYSTEM_PROPERTIES | |
25 | +#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ | |
26 | +#include <sys/_system_properties.h> | |
27 | +#endif | |
28 | + | |
29 | +#include "Supplicant.h" | |
30 | +#include "SupplicantListener.h" | |
31 | +#include "SupplicantState.h" | |
32 | +#include "SupplicantEvent.h" | |
33 | +#include "ScanResult.h" | |
34 | + | |
35 | +#include "libwpa_client/wpa_ctrl.h" | |
36 | + | |
37 | +#define IFACE_DIR "/data/system/wpa_supplicant" | |
38 | +#define DRIVER_PROP_NAME "wlan.driver.status" | |
39 | +#define SUPPLICANT_NAME "wpa_supplicant" | |
40 | +#define SUPP_PROP_NAME "init.svc.wpa_supplicant" | |
41 | + | |
42 | +Supplicant::Supplicant() { | |
43 | + mCtrl = NULL; | |
44 | + mMonitor = NULL; | |
45 | + mListener = NULL; | |
46 | + | |
47 | + mState = SupplicantState::UNKNOWN; | |
48 | + | |
49 | + mLatestScanResults = new ScanResultCollection(); | |
50 | + | |
51 | + pthread_mutex_init(&mLatestScanResultsLock, NULL); | |
52 | +} | |
53 | + | |
54 | +int Supplicant::start() { | |
55 | + LOGD("start():"); | |
56 | + // XXX: Validate supplicant config file | |
57 | + | |
58 | + char status[PROPERTY_VALUE_MAX] = {'\0'}; | |
59 | + int count = 200; | |
60 | +#ifdef HAVE_LIBC_SYSTEM_PROPERTIES | |
61 | + const prop_info *pi; | |
62 | + unsigned int serial = 0; | |
63 | +#endif | |
64 | + | |
65 | + if (property_get(SUPP_PROP_NAME, status, NULL) && | |
66 | + strcmp(status, "running") == 0) { | |
67 | + return 0; | |
68 | + } | |
69 | + | |
70 | + wpa_ctrl_cleanup(); | |
71 | +#ifdef HAVE_LIBC_SYSTEM_PROPERTIES | |
72 | + pi = __system_property_find(SUPP_PROP_NAME); | |
73 | + if (pi != NULL) | |
74 | + serial = pi->serial; | |
75 | +#endif | |
76 | + | |
77 | + property_set("ctl.start", SUPPLICANT_NAME); | |
78 | + sched_yield(); | |
79 | + while (count--) { | |
80 | +#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; | |
91 | + } | |
92 | + } | |
93 | +#else | |
94 | + if (property_get(SUPP_PROP_NAME, status, NULL)) { | |
95 | + if (strcmp(status, "running") == 0) | |
96 | + break; | |
97 | + } | |
98 | +#endif | |
99 | + usleep(100000); | |
100 | + } | |
101 | + | |
102 | + if (!count) { | |
103 | + errno = ETIMEDOUT; | |
104 | + return -1; | |
105 | + } | |
106 | + | |
107 | + if (connectToSupplicant()) { | |
108 | + LOGE("Error connecting to supplicant (%s)\n", strerror(errno)); | |
109 | + return -1; | |
110 | + } | |
111 | + return 0; | |
112 | +} | |
113 | + | |
114 | +int Supplicant::stop() { | |
115 | + LOGD("stop()"); | |
116 | + | |
117 | + char supp_status[PROPERTY_VALUE_MAX] = {'\0'}; | |
118 | + int count = 50; | |
119 | + | |
120 | + if (mListener->stopListener()) { | |
121 | + LOGW("Unable to stop supplicant listener (%s)", strerror(errno)); | |
122 | + return -1; | |
123 | + } | |
124 | + | |
125 | + if (property_get(SUPP_PROP_NAME, supp_status, NULL) | |
126 | + && strcmp(supp_status, "stopped") == 0) { | |
127 | + return 0; | |
128 | + } | |
129 | + | |
130 | + property_set("ctl.stop", SUPPLICANT_NAME); | |
131 | + sched_yield(); | |
132 | + | |
133 | + while (count-- > 0) { | |
134 | + if (property_get(SUPP_PROP_NAME, supp_status, NULL)) { | |
135 | + if (strcmp(supp_status, "stopped") == 0) | |
136 | + break; | |
137 | + } | |
138 | + usleep(100000); | |
139 | + } | |
140 | + | |
141 | + if (mCtrl) { | |
142 | + wpa_ctrl_close(mCtrl); | |
143 | + mCtrl = NULL; | |
144 | + } | |
145 | + if (mMonitor) { | |
146 | + wpa_ctrl_close(mMonitor); | |
147 | + mMonitor = NULL; | |
148 | + } | |
149 | + | |
150 | + if (!count) { | |
151 | + LOGD("Timed out waiting for supplicant to stop"); | |
152 | + errno = ETIMEDOUT; | |
153 | + return -1; | |
154 | + } | |
155 | + | |
156 | + LOGD("Stopped OK"); | |
157 | + | |
158 | + return 0; | |
159 | +} | |
160 | + | |
161 | +bool Supplicant::isStarted() { | |
162 | + 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; | |
168 | +} | |
169 | + | |
170 | +int Supplicant::connectToSupplicant() { | |
171 | + char ifname[256]; | |
172 | + char supp_status[PROPERTY_VALUE_MAX] = {'\0'}; | |
173 | + | |
174 | + if (!property_get(SUPP_PROP_NAME, supp_status, NULL) | |
175 | + || strcmp(supp_status, "running") != 0) { | |
176 | + LOGE("Supplicant not running, cannot connect"); | |
177 | + return -1; | |
178 | + } | |
179 | + | |
180 | + mCtrl = wpa_ctrl_open("tiwlan0"); | |
181 | + if (mCtrl == NULL) { | |
182 | + LOGE("Unable to open connection to supplicant on \"%s\": %s", | |
183 | + "tiwlan0", strerror(errno)); | |
184 | + return -1; | |
185 | + } | |
186 | + mMonitor = wpa_ctrl_open("tiwlan0"); | |
187 | + if (mMonitor == NULL) { | |
188 | + wpa_ctrl_close(mCtrl); | |
189 | + mCtrl = NULL; | |
190 | + return -1; | |
191 | + } | |
192 | + if (wpa_ctrl_attach(mMonitor) != 0) { | |
193 | + wpa_ctrl_close(mMonitor); | |
194 | + wpa_ctrl_close(mCtrl); | |
195 | + mCtrl = mMonitor = NULL; | |
196 | + return -1; | |
197 | + } | |
198 | + | |
199 | + mListener = new SupplicantListener(this, mMonitor); | |
200 | + | |
201 | + if (mListener->startListener()) { | |
202 | + LOGE("Error - unable to start supplicant listener"); | |
203 | + stop(); | |
204 | + return -1; | |
205 | + } | |
206 | + return 0; | |
207 | +} | |
208 | + | |
209 | +int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len) | |
210 | +{ | |
211 | + if (!mCtrl) { | |
212 | + errno = ENOTCONN; | |
213 | + return -1; | |
214 | + } | |
215 | + | |
216 | + LOGD("sendCommand(): -> '%s'", cmd); | |
217 | + | |
218 | + int rc; | |
219 | + if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) { | |
220 | + errno = ETIMEDOUT; | |
221 | + return -1; | |
222 | + } else if (rc < 0 || !strncmp(reply, "FAIL", 4)) { | |
223 | + errno = EIO; | |
224 | + return -1; | |
225 | + } | |
226 | + | |
227 | + if (!strncmp(cmd, "PING", 4) || | |
228 | + !strncmp(cmd, "SCAN_RESULTS", 12)) | |
229 | + reply[*reply_len] = '\0'; | |
230 | + | |
231 | + LOGD("sendCommand(): <- '%s'", reply); | |
232 | + return 0; | |
233 | +} | |
234 | + | |
235 | +int Supplicant::triggerScan(bool active) { | |
236 | + char reply[255]; | |
237 | + size_t len = sizeof(reply); | |
238 | + | |
239 | + if (sendCommand((active ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"), | |
240 | + reply, &len)) { | |
241 | + LOGW("triggerScan(%d): Error setting scan mode (%s)", active, | |
242 | + strerror(errno)); | |
243 | + return -1; | |
244 | + } | |
245 | + len = sizeof(reply); | |
246 | + | |
247 | + if (sendCommand("SCAN", reply, &len)) { | |
248 | + LOGW("triggerScan(%d): Error initiating scan", active); | |
249 | + return -1; | |
250 | + } | |
251 | + return 0; | |
252 | +} | |
253 | + | |
254 | +int Supplicant::onConnectedEvent(SupplicantEvent *evt) { | |
255 | + LOGD("onConnectedEvent(%s)", evt->getEvent()); | |
256 | + return 0; | |
257 | +} | |
258 | + | |
259 | +int Supplicant::onDisconnectedEvent(SupplicantEvent *evt) { | |
260 | + LOGD("onDisconnectedEvent(%s)", evt->getEvent()); | |
261 | + return 0; | |
262 | +} | |
263 | + | |
264 | +int Supplicant::onTerminatingEvent(SupplicantEvent *evt) { | |
265 | + LOGD("onTerminatingEvent(%s)", evt->getEvent()); | |
266 | + return 0; | |
267 | +} | |
268 | + | |
269 | +int Supplicant::onPasswordChangedEvent(SupplicantEvent *evt) { | |
270 | + LOGD("onPasswordChangedEvent(%s)", evt->getEvent()); | |
271 | + return 0; | |
272 | +} | |
273 | + | |
274 | +int Supplicant::onEapNotificationEvent(SupplicantEvent *evt) { | |
275 | + LOGD("onEapNotificationEvent(%s)", evt->getEvent()); | |
276 | + return 0; | |
277 | +} | |
278 | + | |
279 | +int Supplicant::onEapStartedEvent(SupplicantEvent *evt) { | |
280 | + LOGD("onEapStartedEvent(%s)", evt->getEvent()); | |
281 | + return 0; | |
282 | +} | |
283 | + | |
284 | +int Supplicant::onEapMethodEvent(SupplicantEvent *evt) { | |
285 | + LOGD("onEapMethodEvent(%s)", evt->getEvent()); | |
286 | + return 0; | |
287 | +} | |
288 | + | |
289 | +int Supplicant::onEapSuccessEvent(SupplicantEvent *evt) { | |
290 | + LOGD("onEapSuccessEvent(%s)", evt->getEvent()); | |
291 | + return 0; | |
292 | +} | |
293 | + | |
294 | +int Supplicant::onEapFailureEvent(SupplicantEvent *evt) { | |
295 | + LOGD("onEapFailureEvent(%s)", evt->getEvent()); | |
296 | + return 0; | |
297 | +} | |
298 | + | |
299 | +int Supplicant::onScanResultsEvent(SupplicantEvent *evt) { | |
300 | + LOGD("onScanResultsEvent(%s)", evt->getEvent()); | |
301 | + | |
302 | + if (!strcmp(evt->getEvent(), "Ready")) { | |
303 | + char *reply; | |
304 | + | |
305 | + if (!(reply = (char *) malloc(4096))) { | |
306 | + errno = -ENOMEM; | |
307 | + return -1; | |
308 | + } | |
309 | + | |
310 | + size_t len = 4096; | |
311 | + | |
312 | + if (sendCommand("SCAN_RESULTS", reply, &len)) { | |
313 | + LOGW("onScanResultsEvent(%s): Error getting scan results (%s)", | |
314 | + evt->getEvent(), strerror(errno)); | |
315 | + free(reply); | |
316 | + return -1; | |
317 | + } | |
318 | + | |
319 | + pthread_mutex_lock(&mLatestScanResultsLock); | |
320 | + if (!mLatestScanResults->empty()) { | |
321 | + ScanResultCollection::iterator i; | |
322 | + | |
323 | + for (i = mLatestScanResults->begin(); | |
324 | + i !=mLatestScanResults->end(); ++i) { | |
325 | + delete *i; | |
326 | + } | |
327 | + mLatestScanResults->clear(); | |
328 | + } | |
329 | + | |
330 | + char *linep; | |
331 | + char *linep_next = NULL; | |
332 | + | |
333 | + if (!strtok_r(reply, "\n", &linep_next)) { | |
334 | + free(reply); | |
335 | + return 0;; | |
336 | + } | |
337 | + | |
338 | + while((linep = strtok_r(NULL, "\n", &linep_next))) | |
339 | + mLatestScanResults->push_back(new ScanResult(linep)); | |
340 | + | |
341 | + pthread_mutex_unlock(&mLatestScanResultsLock); | |
342 | + free(reply); | |
343 | + } else { | |
344 | + LOGW("Unknown SCAN_RESULTS event (%s)", evt->getEvent()); | |
345 | + } | |
346 | + return 0; | |
347 | +} | |
348 | + | |
349 | +int Supplicant::onStateChangeEvent(SupplicantEvent *evt) { | |
350 | + LOGD("onStateChangeEvent(%s)", evt->getEvent()); | |
351 | + // XXX: Update mState | |
352 | + return 0; | |
353 | +} | |
354 | + | |
355 | +int Supplicant::onLinkSpeedEvent(SupplicantEvent *evt) { | |
356 | + LOGD("onLinkSpeedEvent(%s)", evt->getEvent()); | |
357 | + return 0; | |
358 | +} | |
359 | + | |
360 | +int Supplicant::onDriverStateEvent(SupplicantEvent *evt) { | |
361 | + LOGD("onDriverStateEvent(%s)", evt->getEvent()); | |
362 | + return 0; | |
363 | +} | |
364 | + | |
365 | +// XXX: Use a cursor + smartptr instead | |
366 | +const ScanResultCollection *Supplicant::getLatestScanResults() { | |
367 | + ScanResultCollection *d = new ScanResultCollection(); | |
368 | + ScanResultCollection::iterator i; | |
369 | + | |
370 | + pthread_mutex_lock(&mLatestScanResultsLock); | |
371 | + for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i) { | |
372 | + d->push_back((*i)->clone()); | |
373 | + } | |
374 | + | |
375 | + pthread_mutex_unlock(&mLatestScanResultsLock); | |
376 | + return d; | |
377 | +}; |
@@ -0,0 +1,72 @@ | ||
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 _SUPPLICANT_H | |
17 | +#define _SUPPLICANT_H | |
18 | + | |
19 | +struct wpa_ctrl; | |
20 | +class SupplicantListener; | |
21 | +class SupplicantEvent; | |
22 | + | |
23 | +#include <pthread.h> | |
24 | + | |
25 | +#include "ScanResult.h" | |
26 | + | |
27 | +class Supplicant { | |
28 | +private: | |
29 | + struct wpa_ctrl *mCtrl; | |
30 | + struct wpa_ctrl *mMonitor; | |
31 | + SupplicantListener *mListener; | |
32 | + int mState; | |
33 | + | |
34 | + ScanResultCollection *mLatestScanResults; | |
35 | + pthread_mutex_t mLatestScanResultsLock; | |
36 | + | |
37 | +public: | |
38 | + Supplicant(); | |
39 | + virtual ~Supplicant() {} | |
40 | + | |
41 | + virtual int start(); | |
42 | + virtual int stop(); | |
43 | + virtual bool isStarted(); | |
44 | + | |
45 | + virtual int triggerScan(bool active); | |
46 | + | |
47 | + int getState() { return mState; } | |
48 | + | |
49 | + const ScanResultCollection *getLatestScanResults(); | |
50 | + | |
51 | +// XXX: Extract these into an interface | |
52 | +public: | |
53 | + virtual int onConnectedEvent(SupplicantEvent *evt); | |
54 | + virtual int onDisconnectedEvent(SupplicantEvent *evt); | |
55 | + virtual int onTerminatingEvent(SupplicantEvent *evt); | |
56 | + virtual int onPasswordChangedEvent(SupplicantEvent *evt); | |
57 | + virtual int onEapNotificationEvent(SupplicantEvent *evt); | |
58 | + virtual int onEapStartedEvent(SupplicantEvent *evt); | |
59 | + virtual int onEapMethodEvent(SupplicantEvent *evt); | |
60 | + virtual int onEapSuccessEvent(SupplicantEvent *evt); | |
61 | + virtual int onEapFailureEvent(SupplicantEvent *evt); | |
62 | + virtual int onScanResultsEvent(SupplicantEvent *evt); | |
63 | + virtual int onStateChangeEvent(SupplicantEvent *evt); | |
64 | + virtual int onLinkSpeedEvent(SupplicantEvent *evt); | |
65 | + virtual int onDriverStateEvent(SupplicantEvent *evt); | |
66 | + | |
67 | +private: | |
68 | + int connectToSupplicant(); | |
69 | + int sendCommand(const char *cmd, char *reply, size_t *reply_len); | |
70 | +}; | |
71 | + | |
72 | +#endif |
@@ -0,0 +1,95 @@ | ||
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 <stdlib.h> | |
17 | + | |
18 | +#define LOG_TAG "SupplicantEvent" | |
19 | +#include <cutils/log.h> | |
20 | + | |
21 | +#include "SupplicantEvent.h" | |
22 | + | |
23 | +#include "libwpa_client/wpa_ctrl.h" | |
24 | + | |
25 | +SupplicantEvent::SupplicantEvent(char *event, size_t len) { | |
26 | + | |
27 | + if (event[0] == '<') { | |
28 | + char *match = strchr(event, '>'); | |
29 | + if (match) { | |
30 | + char tmp[16]; | |
31 | + | |
32 | + strncpy(tmp, &event[1], (match - event)); | |
33 | + mLevel = atoi(tmp); | |
34 | + event += (match - event) + 1; | |
35 | + } else | |
36 | + LOGW("Unclosed level brace in event"); | |
37 | + } else | |
38 | + LOGW("No level specified in event"); | |
39 | + | |
40 | + /* | |
41 | + * <N>CTRL-EVENT-XXX | |
42 | + * ^ | |
43 | + * +---- event | |
44 | + */ | |
45 | + | |
46 | + if (!strncmp(event, WPA_EVENT_CONNECTED, strlen(WPA_EVENT_CONNECTED))) | |
47 | + mType = SupplicantEvent::EVENT_CONNECTED; | |
48 | + else if (!strncmp(event, WPA_EVENT_DISCONNECTED, strlen(WPA_EVENT_DISCONNECTED))) | |
49 | + mType = SupplicantEvent::EVENT_DISCONNECTED; | |
50 | + else if (!strncmp(event, WPA_EVENT_TERMINATING, strlen(WPA_EVENT_TERMINATING))) | |
51 | + mType = SupplicantEvent::EVENT_TERMINATING; | |
52 | + else if (!strncmp(event, WPA_EVENT_PASSWORD_CHANGED, strlen(WPA_EVENT_PASSWORD_CHANGED))) | |
53 | + mType = SupplicantEvent::EVENT_PASSWORD_CHANGED; | |
54 | + else if (!strncmp(event, WPA_EVENT_EAP_NOTIFICATION, strlen(WPA_EVENT_EAP_NOTIFICATION))) | |
55 | + mType = SupplicantEvent::EVENT_EAP_NOTIFICATION; | |
56 | + else if (!strncmp(event, WPA_EVENT_EAP_STARTED, strlen(WPA_EVENT_EAP_STARTED))) | |
57 | + mType = SupplicantEvent::EVENT_EAP_STARTED; | |
58 | + else if (!strncmp(event, WPA_EVENT_EAP_METHOD, strlen(WPA_EVENT_EAP_METHOD))) | |
59 | + mType = SupplicantEvent::EVENT_EAP_METHOD; | |
60 | + else if (!strncmp(event, WPA_EVENT_EAP_SUCCESS, strlen(WPA_EVENT_EAP_SUCCESS))) | |
61 | + mType = SupplicantEvent::EVENT_EAP_SUCCESS; | |
62 | + else if (!strncmp(event, WPA_EVENT_EAP_FAILURE, strlen(WPA_EVENT_EAP_FAILURE))) | |
63 | + mType = SupplicantEvent::EVENT_EAP_FAILURE; | |
64 | + else if (!strncmp(event, WPA_EVENT_SCAN_RESULTS, strlen(WPA_EVENT_SCAN_RESULTS))) | |
65 | + mType = SupplicantEvent::EVENT_SCAN_RESULTS; | |
66 | + else if (!strncmp(event, WPA_EVENT_STATE_CHANGE, strlen(WPA_EVENT_STATE_CHANGE))) | |
67 | + mType = SupplicantEvent::EVENT_STATE_CHANGE; | |
68 | + else if (!strncmp(event, WPA_EVENT_LINK_SPEED, strlen(WPA_EVENT_LINK_SPEED))) | |
69 | + mType = SupplicantEvent::EVENT_LINK_SPEED; | |
70 | + else if (!strncmp(event, WPA_EVENT_DRIVER_STATE, strlen(WPA_EVENT_DRIVER_STATE))) | |
71 | + mType = SupplicantEvent::EVENT_DRIVER_STATE; | |
72 | + else { | |
73 | + LOGW("Unknown supplicant event '%s'", event); | |
74 | + mType = SupplicantEvent::EVENT_UNKNOWN; | |
75 | + } | |
76 | + | |
77 | + for (event; *event != ' '; event++); | |
78 | + event++; | |
79 | + | |
80 | + /* | |
81 | + * <N>CTRL-EVENT-XXX YYYY | |
82 | + * ^ | |
83 | + * +---- event | |
84 | + */ | |
85 | + | |
86 | + for (event; *event == ' '; event++); | |
87 | + | |
88 | + mEvent = strdup(event); | |
89 | + mLen = len; | |
90 | +} | |
91 | + | |
92 | +SupplicantEvent::~SupplicantEvent() { | |
93 | + if (mEvent) | |
94 | + free(mEvent); | |
95 | +} |
@@ -0,0 +1,54 @@ | ||
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 _SUPPLICANT_EVENT_H | |
17 | +#define _SUPPLICANT_EVENT_H | |
18 | + | |
19 | +#include <sys/types.h> | |
20 | + | |
21 | +class SupplicantEvent { | |
22 | +private: | |
23 | + int mType; | |
24 | + char *mEvent; | |
25 | + size_t mLen; | |
26 | + int mLevel; | |
27 | + | |
28 | +public: | |
29 | + static const int EVENT_UNKNOWN = 0; | |
30 | + static const int EVENT_CONNECTED = 1; | |
31 | + static const int EVENT_DISCONNECTED = 2; | |
32 | + static const int EVENT_TERMINATING = 3; | |
33 | + static const int EVENT_PASSWORD_CHANGED = 4; | |
34 | + static const int EVENT_EAP_NOTIFICATION = 5; | |
35 | + static const int EVENT_EAP_STARTED = 6; | |
36 | + static const int EVENT_EAP_METHOD = 7; | |
37 | + static const int EVENT_EAP_SUCCESS = 8; | |
38 | + static const int EVENT_EAP_FAILURE = 9; | |
39 | + static const int EVENT_SCAN_RESULTS = 10; | |
40 | + static const int EVENT_STATE_CHANGE = 11; | |
41 | + static const int EVENT_LINK_SPEED = 12; | |
42 | + static const int EVENT_DRIVER_STATE = 13; | |
43 | + | |
44 | +public: | |
45 | + SupplicantEvent(char *event, size_t len); | |
46 | + virtual ~SupplicantEvent(); | |
47 | + | |
48 | + int getType() { return mType; } | |
49 | + const char *getEvent() { return mEvent; } | |
50 | + int getLen() { return mLen; } | |
51 | + int getLevel() { return mLevel; } | |
52 | +}; | |
53 | + | |
54 | +#endif |
@@ -0,0 +1,114 @@ | ||
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 <errno.h> | |
17 | +#include <sys/types.h> | |
18 | +#include <pthread.h> | |
19 | + | |
20 | +#define LOG_TAG "SupplicantListener" | |
21 | +#include <cutils/log.h> | |
22 | + | |
23 | +#include "libwpa_client/wpa_ctrl.h" | |
24 | + | |
25 | +#include "Supplicant.h" | |
26 | +#include "SupplicantListener.h" | |
27 | +#include "SupplicantEvent.h" | |
28 | + | |
29 | +SupplicantListener::SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *monitor) : | |
30 | + SocketListener(wpa_ctrl_get_fd(monitor), false) { | |
31 | + mSupplicant = supplicant; | |
32 | + mMonitor = monitor; | |
33 | + mThread = NULL; | |
34 | +} | |
35 | + | |
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) { | |
58 | + char buf[255]; | |
59 | + size_t buflen = sizeof(buf); | |
60 | + int rc; | |
61 | + size_t nread = buflen - 1; | |
62 | + | |
63 | + if ((rc = wpa_ctrl_recv(mMonitor, buf, &nread))) { | |
64 | + LOGE("wpa_ctrl_recv failed (%s)", strerror(errno)); | |
65 | + return -errno; | |
66 | + } | |
67 | + | |
68 | + buf[nread] = '\0'; | |
69 | + if (!rc && !nread) { | |
70 | + LOGD("Received EOF on supplicant socket\n"); | |
71 | + strncpy(buf, WPA_EVENT_TERMINATING " - signal 0 received", buflen-1); | |
72 | + buf[buflen-1] = '\0'; | |
73 | + return false; | |
74 | + } | |
75 | + | |
76 | + SupplicantEvent *evt = new SupplicantEvent(buf, nread); | |
77 | + | |
78 | + // XXX: Make this a factory | |
79 | + // XXX: Instead of calling Supplicant directly | |
80 | + // extract an Interface and use that instead | |
81 | + if (evt->getType() == SupplicantEvent::EVENT_CONNECTED) | |
82 | + rc = mSupplicant->onConnectedEvent(evt); | |
83 | + else if (evt->getType() == SupplicantEvent::EVENT_DISCONNECTED) | |
84 | + rc = mSupplicant->onDisconnectedEvent(evt); | |
85 | + else if (evt->getType() == SupplicantEvent::EVENT_TERMINATING) | |
86 | + rc = mSupplicant->onTerminatingEvent(evt); | |
87 | + else if (evt->getType() == SupplicantEvent::EVENT_PASSWORD_CHANGED) | |
88 | + rc = mSupplicant->onPasswordChangedEvent(evt); | |
89 | + else if (evt->getType() == SupplicantEvent::EVENT_EAP_NOTIFICATION) | |
90 | + rc = mSupplicant->onEapNotificationEvent(evt); | |
91 | + else if (evt->getType() == SupplicantEvent::EVENT_EAP_STARTED) | |
92 | + rc = mSupplicant->onEapStartedEvent(evt); | |
93 | + else if (evt->getType() == SupplicantEvent::EVENT_EAP_SUCCESS) | |
94 | + rc = mSupplicant->onEapSuccessEvent(evt); | |
95 | + else if (evt->getType() == SupplicantEvent::EVENT_EAP_FAILURE) | |
96 | + rc = mSupplicant->onEapFailureEvent(evt); | |
97 | + else if (evt->getType() == SupplicantEvent::EVENT_SCAN_RESULTS) | |
98 | + rc = mSupplicant->onScanResultsEvent(evt); | |
99 | + else if (evt->getType() == SupplicantEvent::EVENT_STATE_CHANGE) | |
100 | + rc = mSupplicant->onStateChangeEvent(evt); | |
101 | + else if (evt->getType() == SupplicantEvent::EVENT_LINK_SPEED) | |
102 | + rc = mSupplicant->onLinkSpeedEvent(evt); | |
103 | + else if (evt->getType() == SupplicantEvent::EVENT_DRIVER_STATE) | |
104 | + rc = mSupplicant->onDriverStateEvent(evt); | |
105 | + else { | |
106 | + LOGW("Ignoring unknown event"); | |
107 | + } | |
108 | + | |
109 | + delete evt; | |
110 | + | |
111 | + if (rc) | |
112 | + return false; | |
113 | + return true; | |
114 | +} |
@@ -0,0 +1,48 @@ | ||
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 _SUPPLICANTLISTENER_H__ | |
17 | +#define _SUPPLICANTLISTENER_H__ | |
18 | + | |
19 | +#include <pthread.h> | |
20 | + | |
21 | +#include <sysutils/SocketListener.h> | |
22 | + | |
23 | +struct wpa_ctrl; | |
24 | +class Supplicant; | |
25 | + | |
26 | +class SupplicantListener: public SocketListener { | |
27 | +private: | |
28 | + struct wpa_ctrl *mMonitor; | |
29 | + Supplicant *mSupplicant; | |
30 | + pthread_t mThread; | |
31 | + | |
32 | +public: | |
33 | + SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *monitor); | |
34 | + virtual ~SupplicantListener() {} | |
35 | + int startListener(); | |
36 | + int stopListener(); | |
37 | + | |
38 | + struct wpa_ctrl *getMonitor() { return mMonitor; } | |
39 | + Supplicant *getSupplicant() { return mSupplicant; } | |
40 | + | |
41 | +protected: | |
42 | + virtual bool onDataAvailable(int socket); | |
43 | + | |
44 | +private: | |
45 | + static void *threadStart(void *obj); | |
46 | +}; | |
47 | + | |
48 | +#endif |
@@ -0,0 +1,33 @@ | ||
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 _SUPPLICANT_STATE_H | |
17 | +#define _SUPPLICANT_STATE_H | |
18 | + | |
19 | +class SupplicantState { | |
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; | |
31 | +}; | |
32 | + | |
33 | +#endif |
@@ -0,0 +1,67 @@ | ||
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 <stdlib.h> | |
17 | +#include <fcntl.h> | |
18 | +#include <errno.h> | |
19 | +#include <string.h> | |
20 | + | |
21 | +#include <cutils/properties.h> | |
22 | +#define LOG_TAG "TiwlanWifiController" | |
23 | +#include <cutils/log.h> | |
24 | + | |
25 | +#include "TiwlanWifiController.h" | |
26 | + | |
27 | +#define DRIVER_PROP_NAME "wlan.driver.status" | |
28 | + | |
29 | +extern "C" int sched_yield(void); | |
30 | + | |
31 | +TiwlanWifiController::TiwlanWifiController(char *modpath, char *modname, char *modargs) : | |
32 | + WifiController(modpath, modname, modargs) { | |
33 | +} | |
34 | + | |
35 | +int TiwlanWifiController::powerUp() { | |
36 | + return 0; // Powerup is currently done when the driver is loaded | |
37 | +} | |
38 | + | |
39 | +int TiwlanWifiController::powerDown() { | |
40 | + return 0; // Powerdown is currently done when the driver is unloaded | |
41 | +} | |
42 | + | |
43 | +bool TiwlanWifiController::isPoweredUp() { | |
44 | + return isKernelModuleLoaded(getModuleName()); | |
45 | +} | |
46 | + | |
47 | +int TiwlanWifiController::loadFirmware() { | |
48 | + char driver_status[PROPERTY_VALUE_MAX]; | |
49 | + int count = 100; | |
50 | + | |
51 | + LOGD("loadFirmware()"); | |
52 | + property_set("ctl.start", "wlan_loader"); | |
53 | + sched_yield(); | |
54 | + | |
55 | + // Wait for driver to be ready | |
56 | + while (count-- > 0) { | |
57 | + if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) { | |
58 | + if (strcmp(driver_status, "ok") == 0) | |
59 | + return 0; | |
60 | + else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) | |
61 | + return -1; | |
62 | + } | |
63 | + usleep(200000); | |
64 | + } | |
65 | + property_set(DRIVER_PROP_NAME, "timeout"); | |
66 | + return -1; | |
67 | +} |
@@ -0,0 +1,31 @@ | ||
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 _TIWLAN_WIFI_CONTROLLER_H | |
17 | +#define _TIWLAN_WIFI_CONTROLLER_H | |
18 | + | |
19 | +#include "WifiController.h" | |
20 | + | |
21 | +class TiwlanWifiController : public WifiController { | |
22 | +public: | |
23 | + TiwlanWifiController(char *modpath, char *modname, char *modargs); | |
24 | + virtual ~TiwlanWifiController() {} | |
25 | + | |
26 | + virtual int powerUp(); | |
27 | + virtual int powerDown(); | |
28 | + virtual bool isPoweredUp(); | |
29 | + virtual int loadFirmware(); | |
30 | +}; | |
31 | +#endif |
@@ -0,0 +1,44 @@ | ||
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 <errno.h> | |
17 | +#include "VpnController.h" | |
18 | + | |
19 | +VpnController::VpnController() : | |
20 | + Controller("VPN") { | |
21 | +} | |
22 | + | |
23 | +int VpnController::start() { | |
24 | + errno = -ENOSYS; | |
25 | + return -1; | |
26 | +} | |
27 | + | |
28 | +int VpnController::stop() { | |
29 | + errno = -ENOSYS; | |
30 | + return -1; | |
31 | +} | |
32 | + | |
33 | +int VpnController::enable() { | |
34 | + | |
35 | + // Load modules | |
36 | + // Start daemons | |
37 | + errno = -ENOSYS; | |
38 | + return -1; | |
39 | +} | |
40 | + | |
41 | +int VpnController::disable() { | |
42 | + errno = -ENOSYS; | |
43 | + return -1; | |
44 | +} |
@@ -0,0 +1,38 @@ | ||
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 _VPN_CONTROLLER_H | |
17 | +#define _VPN_CONTROLLER_H | |
18 | + | |
19 | +#include "Controller.h" | |
20 | + | |
21 | +class VpnController : public Controller { | |
22 | + | |
23 | +public: | |
24 | + VpnController(); | |
25 | + virtual ~VpnController() {} | |
26 | + | |
27 | + virtual int start(); | |
28 | + virtual int stop(); | |
29 | + | |
30 | + virtual int enable(); | |
31 | + virtual int disable(); | |
32 | + | |
33 | +protected: | |
34 | + | |
35 | +private: | |
36 | +}; | |
37 | + | |
38 | +#endif |
@@ -0,0 +1,134 @@ | ||
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 <string.h> | |
17 | +#include <errno.h> | |
18 | + | |
19 | +#define LOG_TAG "WifiController" | |
20 | +#include <cutils/log.h> | |
21 | + | |
22 | +#include "Supplicant.h" | |
23 | +#include "WifiController.h" | |
24 | + | |
25 | +WifiController::WifiController(char *modpath, char *modname, char *modargs) : | |
26 | + Controller("WIFI") { | |
27 | + strncpy(mModulePath, modpath, sizeof(mModulePath)); | |
28 | + strncpy(mModuleName, modname, sizeof(mModuleName)); | |
29 | + strncpy(mModuleArgs, modargs, sizeof(mModuleArgs)); | |
30 | + | |
31 | + mSupplicant = new Supplicant(); | |
32 | + mCurrentScanMode = 0; | |
33 | +} | |
34 | + | |
35 | +int WifiController::start() { | |
36 | + return 0; | |
37 | +} | |
38 | + | |
39 | +int WifiController::stop() { | |
40 | + errno = ENOSYS; | |
41 | + return -1; | |
42 | +} | |
43 | + | |
44 | +int WifiController::enable() { | |
45 | + if (!isPoweredUp() && powerUp()) { | |
46 | + LOGE("Powerup failed (%s)", strerror(errno)); | |
47 | + return -1; | |
48 | + } | |
49 | + | |
50 | + if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) { | |
51 | + if (loadKernelModule(mModulePath, mModuleArgs)) { | |
52 | + LOGE("Kernel module load failed (%s)", strerror(errno)); | |
53 | + goto out_powerdown; | |
54 | + } | |
55 | + } | |
56 | + | |
57 | + if (loadFirmware()) { | |
58 | + LOGE("Firmware load failed (%s)", strerror(errno)); | |
59 | + goto out_powerdown; | |
60 | + } | |
61 | + | |
62 | + if (!mSupplicant->isStarted() && mSupplicant->start()) { | |
63 | + LOGE("Supplicant start failed (%s)", strerror(errno)); | |
64 | + goto out_unloadmodule; | |
65 | + } | |
66 | + | |
67 | + return 0; | |
68 | + | |
69 | +out_unloadmodule: | |
70 | + if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) { | |
71 | + if (unloadKernelModule(mModuleName)) { | |
72 | + LOGE("Unable to unload module after failure!"); | |
73 | + } | |
74 | + } | |
75 | + | |
76 | +out_powerdown: | |
77 | + if (powerDown()) { | |
78 | + LOGE("Unable to powerdown after failure!"); | |
79 | + } | |
80 | + return -1; | |
81 | +} | |
82 | + | |
83 | +int WifiController::disable() { | |
84 | + LOGD("disable()"); | |
85 | + | |
86 | + if (mSupplicant->isStarted() && mSupplicant->stop()) { | |
87 | + LOGE("Supplicant stop failed (%s)", strerror(errno)); | |
88 | + return -1; | |
89 | + } | |
90 | + | |
91 | + if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) { | |
92 | + if (unloadKernelModule(mModuleName)) { | |
93 | + LOGE("Unable to unload module (%s)", strerror(errno)); | |
94 | + return -1; | |
95 | + } | |
96 | + } | |
97 | + | |
98 | + if (isPoweredUp() && powerDown()) { | |
99 | + LOGE("Powerdown failed (%s)", strerror(errno)); | |
100 | + return -1; | |
101 | + } | |
102 | + return 0; | |
103 | +} | |
104 | + | |
105 | +int WifiController::loadFirmware() { | |
106 | + return 0; | |
107 | +} | |
108 | + | |
109 | +int WifiController::setScanMode(int mode) { | |
110 | + int rc = 0; | |
111 | + | |
112 | + if (mCurrentScanMode == mode) | |
113 | + return 0; | |
114 | + | |
115 | + if (!(mode & SCAN_ENABLE_MASK)) { | |
116 | + if (mCurrentScanMode & SCAN_REPEAT_MASK) | |
117 | + stopPeriodicScan(); | |
118 | + } else if (mode & SCAN_REPEAT_MASK) | |
119 | + rc = startPeriodicScan(); | |
120 | + else | |
121 | + rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK); | |
122 | + | |
123 | + return rc; | |
124 | +} | |
125 | + | |
126 | +int WifiController::startPeriodicScan() { | |
127 | + errno = -ENOSYS; | |
128 | + return -1; | |
129 | +} | |
130 | + | |
131 | +int WifiController::stopPeriodicScan() { | |
132 | + errno = -ENOSYS; | |
133 | + return -1; | |
134 | +} |
@@ -0,0 +1,78 @@ | ||
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 _WIFI_CONTROLLER_H | |
17 | +#define _WIFI_CONTROLLER_H | |
18 | + | |
19 | +#include <sys/types.h> | |
20 | + | |
21 | +#include "Controller.h" | |
22 | + | |
23 | +class NetInterface; | |
24 | +class Supplicant; | |
25 | + | |
26 | +class WifiController : public Controller { | |
27 | +public: | |
28 | + static const uint32_t SCAN_ENABLE_MASK = 0x01; | |
29 | + static const uint32_t SCAN_ACTIVE_MASK = 0x02; | |
30 | + static const uint32_t SCAN_REPEAT_MASK = 0x04; | |
31 | + | |
32 | + static const uint32_t SCANMODE_NONE = 0; | |
33 | + static const uint32_t SCANMODE_PASSIVE_ONESHOT = SCAN_ENABLE_MASK; | |
34 | + static const uint32_t SCANMODE_PASSIVE_CONTINUOUS = SCAN_ENABLE_MASK | SCAN_REPEAT_MASK; | |
35 | + static const uint32_t SCANMODE_ACTIVE_ONESHOT = SCAN_ENABLE_MASK | SCAN_ACTIVE_MASK; | |
36 | + static const uint32_t SCANMODE_ACTIVE_CONTINUOUS = SCAN_ENABLE_MASK | SCAN_ACTIVE_MASK | SCAN_REPEAT_MASK; | |
37 | + | |
38 | +private: | |
39 | + Supplicant *mSupplicant; | |
40 | + char mModulePath[255]; | |
41 | + char mModuleName[64]; | |
42 | + char mModuleArgs[255]; | |
43 | + int mCurrentScanMode; | |
44 | + | |
45 | + | |
46 | +public: | |
47 | + WifiController(char *modpath, char *modname, char *modargs); | |
48 | + virtual ~WifiController() {} | |
49 | + | |
50 | + int start(); | |
51 | + int stop(); | |
52 | + | |
53 | + int enable(); | |
54 | + int disable(); | |
55 | + | |
56 | + int getType(); | |
57 | + | |
58 | + char *getModulePath() { return mModulePath; } | |
59 | + char *getModuleName() { return mModuleName; } | |
60 | + char *getModuleArgs() { return mModuleArgs; } | |
61 | + | |
62 | + Supplicant *getSupplicant() { return mSupplicant; } | |
63 | + | |
64 | + int getScanMode() { return mCurrentScanMode; } | |
65 | + int setScanMode(int mode); | |
66 | + | |
67 | +protected: | |
68 | + virtual int powerUp() = 0; | |
69 | + virtual int powerDown() = 0; | |
70 | + virtual int loadFirmware(); | |
71 | + virtual bool isPoweredUp() = 0; | |
72 | + | |
73 | +private: | |
74 | + int startPeriodicScan(); | |
75 | + int stopPeriodicScan(); | |
76 | +}; | |
77 | + | |
78 | +#endif |
@@ -0,0 +1,41 @@ | ||
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 <stdlib.h> | |
17 | +#include <errno.h> | |
18 | + | |
19 | +#define LOG_TAG "Nexus" | |
20 | + | |
21 | +#include "cutils/log.h" | |
22 | +#include "NetworkManager.h" | |
23 | + | |
24 | +int main() { | |
25 | + NetworkManager *nm; | |
26 | + | |
27 | + LOGI("Nexus version 0.1 firing up"); | |
28 | + | |
29 | + if (!(nm = new NetworkManager())) { | |
30 | + LOGE("Unable to create NetworkManager"); | |
31 | + exit (-1); | |
32 | + }; | |
33 | + | |
34 | + if (nm->run()) { | |
35 | + LOGE("Unable to Run NetworkManager (%s)", strerror(errno)); | |
36 | + exit (1); | |
37 | + } | |
38 | + | |
39 | + LOGI("Nexus exiting"); | |
40 | + exit(0); | |
41 | +} |
@@ -0,0 +1,104 @@ | ||
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 <stdlib.h> | |
18 | +#include <unistd.h> | |
19 | +#include <string.h> | |
20 | +#include <signal.h> | |
21 | +#include <errno.h> | |
22 | +#include <fcntl.h> | |
23 | + | |
24 | +#include <sys/socket.h> | |
25 | +#include <sys/select.h> | |
26 | +#include <sys/time.h> | |
27 | +#include <sys/types.h> | |
28 | +#include <sys/un.h> | |
29 | + | |
30 | +#include <cutils/sockets.h> | |
31 | + | |
32 | +#include <private/android_filesystem_config.h> | |
33 | + | |
34 | +static void signal_handler(int sig) { | |
35 | + fprintf(stdout, "{ interrupt! }\n"); | |
36 | +} | |
37 | + | |
38 | +int main(int argc, char **argv) { | |
39 | + int sock; | |
40 | + | |
41 | + if ((sock = socket_local_client("nexus", | |
42 | + ANDROID_SOCKET_NAMESPACE_RESERVED, | |
43 | + SOCK_STREAM)) < 0) { | |
44 | + fprintf(stderr, "Error connecting (%s)\n", strerror(errno)); | |
45 | + exit(1); | |
46 | + } | |
47 | + | |
48 | + printf("Connected to nexus\n"); | |
49 | + | |
50 | + while(1) { | |
51 | + fd_set read_fds; | |
52 | + struct timeval to; | |
53 | + int rc = 0; | |
54 | + | |
55 | + signal(SIGINT, SIG_DFL); | |
56 | + | |
57 | + printf("-> "); | |
58 | + fflush(stdout); | |
59 | + | |
60 | + char buffer[255]; | |
61 | + if (!fgets(buffer, sizeof(buffer) -1, stdin)) { | |
62 | + printf("Exiting...\n"); | |
63 | + exit(0); | |
64 | + } | |
65 | + | |
66 | + buffer[strlen(buffer) -1] = 0; | |
67 | + | |
68 | + printf("sending '%s'\n", buffer); | |
69 | + if (write(sock, buffer, strlen(buffer) +1) < 0) { | |
70 | + fprintf(stderr, "Error writing data (%s)\n", strerror(errno)); | |
71 | + exit(2); | |
72 | + } | |
73 | + | |
74 | +wait: | |
75 | + to.tv_sec = 5; | |
76 | + to.tv_usec = 0; | |
77 | + FD_ZERO(&read_fds); | |
78 | + FD_SET(sock, &read_fds); | |
79 | + | |
80 | + signal(SIGINT, signal_handler); | |
81 | + | |
82 | + if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) { | |
83 | + if (errno == EINTR) | |
84 | + continue; | |
85 | + fprintf(stderr, "Error in select (%s)\n", strerror(errno)); | |
86 | + exit(2); | |
87 | + } else if (!rc) { | |
88 | + printf("{response timeout}\n"); | |
89 | + continue; | |
90 | + } else if (FD_ISSET(sock, &read_fds)) { | |
91 | +printf("got data!\n"); | |
92 | + if ((rc = read(sock, buffer, sizeof(buffer)-1)) < 0) { | |
93 | + fprintf(stderr, "Error reading response (%s)\n", strerror(errno)); | |
94 | + exit(2); | |
95 | + } | |
96 | + printf(" |%s|\n", buffer); | |
97 | + goto wait; | |
98 | + } | |
99 | + } | |
100 | + | |
101 | + | |
102 | + exit(0); | |
103 | + | |
104 | +} |
@@ -217,6 +217,10 @@ service servicemanager /system/bin/servicemanager | ||
217 | 217 | service vold /system/bin/vold |
218 | 218 | socket vold stream 0660 root mount |
219 | 219 | |
220 | +service nexus /system/bin/nexus | |
221 | + socket nexus stream 0660 root system | |
222 | + disabled | |
223 | + | |
220 | 224 | #service mountd /system/bin/mountd |
221 | 225 | # socket mountd stream 0660 root mount |
222 | 226 |