Merge commit 'goog/master' into merge_master

This commit is contained in:
Mathias Agopian 2009-05-07 17:46:47 -07:00
commit ab15ac0881
49 changed files with 2956 additions and 24 deletions

View file

@ -21,6 +21,7 @@ else
include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
adb \
libcutils \
libsysutils \
liblog \
libnetutils \
libpixelflinger \

View file

@ -7,7 +7,6 @@ LOCAL_PATH:= $(call my-dir)
# adb host tool
# =========================================================
ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean (also unused with the sim)
include $(CLEAR_VARS)
# Default to a virtual (sockets) usb interface
@ -77,7 +76,6 @@ ifeq ($(HOST_OS),windows)
$(LOCAL_INSTALLED_MODULE): $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll
endif
endif
# adbd device daemon
# =========================================================

View file

@ -222,6 +222,7 @@ void usage(void)
" -p <product> specify product name\n"
" -c <cmdline> override kernel commandline\n"
" -i <vendor id> specify a custom USB vendor id\n"
" -b <base_addr> specify a custom kernel base address\n"
);
exit(1);
}

View file

@ -0,0 +1,37 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __FRAMEWORK_CMD_HANDLER_H
#define __FRAMEWORK_CMD_HANDLER_H
#include "../../../frameworks/base/include/utils/List.h"
class FrameworkCommand {
private:
const char *mCommand;
public:
FrameworkCommand(const char *cmd);
virtual ~FrameworkCommand() { }
virtual int runCommand(char *data);
const char *getCommand() { return mCommand; }
};
typedef android::List<FrameworkCommand *> FrameworkCommandCollection;
#endif

View file

@ -0,0 +1,37 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _FRAMEWORKSOCKETLISTENER_H
#define _FRAMEWORKSOCKETLISTENER_H
#include "SocketListener.h"
#include "FrameworkCommand.h"
class FrameworkListener : public SocketListener {
private:
FrameworkCommandCollection *mCommands;
public:
FrameworkListener(const char *socketName);
virtual ~FrameworkListener() {}
protected:
void registerCmd(FrameworkCommand *cmd);
virtual bool onDataAvailable(int socket);
private:
void dispatchCommand(char *cmd);
};
#endif

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _FRAMEWORKMANAGER_H
#define _FRAMEWORKMANAGER_H
#include <pthread.h>
class FrameworkListener;
class FrameworkManager {
int mDoorbell; // Socket used to accept connections from framework
int mFwSock; // Socket used to communicate with framework
const char *mSocketName;
FrameworkListener *mListener;
pthread_mutex_t mWriteMutex;
public:
FrameworkManager(FrameworkListener *Listener);
virtual ~FrameworkManager() {}
int run();
int sendMsg(char *msg);
int sendMsg(char *msg, char *data);
};
#endif

View file

@ -0,0 +1,44 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _NETLINKEVENT_H
#define _NETLINKEVENT_H
#define NL_PARAMS_MAX 32
class NetlinkEvent {
int mSeq;
char *mPath;
int mAction;
char *mSubsystem;
char *mParams[NL_PARAMS_MAX];
public:
const static int NlActionUnknown;
const static int NlActionAdd;
const static int NlActionRemove;
const static int NlActionChange;
NetlinkEvent();
virtual ~NetlinkEvent();
bool decode(char *buffer, int size);
const char *findParam(const char *paramName);
const char *getSubsystem() { return mSubsystem; }
int getAction() { return mAction; }
};
#endif

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _NETLINKLISTENER_H
#define _NETLINKLISTENER_H
#include "SocketListener.h"
class NetlinkEvent;
class NetlinkListener : public SocketListener {
char mBuffer[64 * 1024];
public:
NetlinkListener(int socket);
virtual ~NetlinkListener() {}
protected:
virtual bool onDataAvailable(int socket);
};
#endif

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SOCKETLISTENER_H
#define _SOCKETLISTENER_H
class SocketListener {
int mSock;
int mCsock;
int mAcceptClients;
const char *mSocketName;
public:
SocketListener(const char *socketName, bool acceptClients);
SocketListener(int socketFd, bool acceptClients);
virtual ~SocketListener() {}
virtual int run();
protected:
virtual bool onDataAvailable(int socket);
};
#endif

View file

@ -126,6 +126,7 @@ static struct perms_ devperms[] = {
{ "/dev/msm_audpre", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/htc-acoustic", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qemu_trace", 0666, AID_SYSTEM, AID_SYSTEM, 0 },
{ "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 },

View file

@ -423,7 +423,7 @@ static void msg_stop(const char *name)
if (svc) {
service_stop(svc);
} else {
ERROR("no such service '%s'\n");
ERROR("no such service '%s'\n", name);
}
}

View file

@ -29,7 +29,8 @@ void *read_file(const char *fn, unsigned *_sz);
void log_init(void);
void log_set_level(int level);
void log_close(void);
void log_write(int level, const char *fmt, ...);
void log_write(int level, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
#define ERROR(x...) log_write(3, "<3>init: " x)
#define NOTICE(x...) log_write(5, "<5>init: " x)

View file

@ -15,6 +15,8 @@
** limitations under the License.
*/
#include <limits.h> /* for SIZE_MAX */
#include <cutils/jstring.h>
#include <assert.h>
#include <stdlib.h>
@ -26,19 +28,67 @@
*/
extern size_t strnlen16to8(const char16_t* utf16Str, size_t len)
{
size_t utf8Len = 0;
size_t utf8Len = 0;
while (len--) {
unsigned int uic = *utf16Str++;
/* A small note on integer overflow. The result can
* potentially be as big as 3*len, which will overflow
* for len > SIZE_MAX/3.
*
* Moreover, the result of a strnlen16to8 is typically used
* to allocate a destination buffer to strncpy16to8 which
* requires one more byte to terminate the UTF-8 copy, and
* this is generally done by careless users by incrementing
* the result without checking for integer overflows, e.g.:
*
* dst = malloc(strnlen16to8(utf16,len)+1)
*
* Due to this, the following code will try to detect
* overflows, and never return more than (SIZE_MAX-1)
* when it detects one. A careless user will try to malloc
* SIZE_MAX bytes, which will return NULL which can at least
* be detected appropriately.
*
* As far as I know, this function is only used by strndup16(),
* but better be safe than sorry.
*/
if (uic > 0x07ff)
utf8Len += 3;
else if (uic > 0x7f || uic == 0)
utf8Len += 2;
else
utf8Len++;
}
return utf8Len;
/* Fast path for the usual case where 3*len is < SIZE_MAX-1.
*/
if (len < (SIZE_MAX-1)/3) {
while (len--) {
unsigned int uic = *utf16Str++;
if (uic > 0x07ff)
utf8Len += 3;
else if (uic > 0x7f || uic == 0)
utf8Len += 2;
else
utf8Len++;
}
return utf8Len;
}
/* The slower but paranoid version */
while (len--) {
unsigned int uic = *utf16Str++;
size_t utf8Cur = utf8Len;
if (uic > 0x07ff)
utf8Len += 3;
else if (uic > 0x7f || uic == 0)
utf8Len += 2;
else
utf8Len++;
if (utf8Len < utf8Cur) /* overflow detected */
return SIZE_MAX-1;
}
/* don't return SIZE_MAX to avoid common user bug */
if (utf8Len == SIZE_MAX)
utf8Len = SIZE_MAX-1;
return utf8Len;
}
@ -50,7 +100,7 @@ extern size_t strnlen16to8(const char16_t* utf16Str, size_t len)
*
* Make sure you allocate "utf8Str" with the result of strlen16to8() + 1,
* not just "len".
*
*
* Please note, a terminated \0 is always added, so your result will always
* be "strlen16to8() + 1" bytes long.
*/
@ -58,6 +108,10 @@ extern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len)
{
char* utf8cur = utf8Str;
/* Note on overflows: We assume the user did check the result of
* strnlen16to8() properly or at a minimum checked the result of
* its malloc(SIZE_MAX) in case of overflow.
*/
while (len--) {
unsigned int uic = *utf16Str++;
@ -73,8 +127,8 @@ extern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len)
if (uic == 0) {
break;
}
}
}
}
}
*utf8cur = '\0';
@ -85,20 +139,30 @@ extern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len)
/**
* Convert a UTF-16 string to UTF-8.
*
* Make sure you allocate "dest" with the result of strblen16to8(),
* not just "strlen16()".
*/
char * strndup16to8 (const char16_t* s, size_t n)
{
char *ret;
char* ret;
size_t len;
if (s == NULL) {
return NULL;
}
ret = malloc(strnlen16to8(s, n) + 1);
len = strnlen16to8(s, n);
/* We are paranoid, and we check for SIZE_MAX-1
* too since it is an overflow value for our
* strnlen16to8 implementation.
*/
if (len >= SIZE_MAX-1)
return NULL;
ret = malloc(len + 1);
if (ret == NULL)
return NULL;
strncpy16to8 (ret, s, n);
return ret;
return ret;
}

21
libsysutils/Android.mk Normal file
View file

@ -0,0 +1,21 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
src/FrameworkManager.cpp \
src/SocketListener.cpp \
src/FrameworkListener.cpp \
src/NetlinkListener.cpp \
src/NetlinkEvent.cpp \
src/FrameworkCommand.cpp \
LOCAL_MODULE:= libsysutils
LOCAL_C_INCLUDES := $(KERNEL_HEADERS)
LOCAL_CFLAGS :=
LOCAL_SHARED_LIBRARIES := libcutils
include $(BUILD_SHARED_LIBRARY)

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#define LOG_TAG "FrameworkCommand"
#include <cutils/log.h>
#include <sysutils/FrameworkCommand.h>
FrameworkCommand::FrameworkCommand(const char *cmd) {
mCommand = cmd;
}
int FrameworkCommand::runCommand(char *data) {
LOGW("Command %s has no run handler!", getCommand());
errno = ENOSYS;
return -1;
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <string.h>
#define LOG_TAG "FrameworkListener"
#include <cutils/log.h>
#include <sysutils/FrameworkListener.h>
#include <sysutils/FrameworkCommand.h>
FrameworkListener::FrameworkListener(const char *socketName) :
SocketListener(socketName, true) {
mCommands = new FrameworkCommandCollection();
}
bool FrameworkListener::onDataAvailable(int socket) {
char buffer[101];
int len;
if ((len = read(socket, buffer, sizeof(buffer) -1)) < 0) {
LOGE("read() failed (%s)", strerror(errno));
return errno;
} else if (!len) {
LOGW("Lost connection to client");
return false;
}
int start = 0;
int i;
buffer[len] = '\0';
for (i = 0; i < len; i++) {
if (buffer[i] == '\0') {
dispatchCommand(buffer + start);
start = i + 1;
}
}
return true;
}
void FrameworkListener::registerCmd(FrameworkCommand *cmd) {
mCommands->push_back(cmd);
}
void FrameworkListener::dispatchCommand(char *cmd) {
FrameworkCommandCollection::iterator i;
for (i = mCommands->begin(); i != mCommands->end(); ++i) {
FrameworkCommand *c = *i;
if (!strncmp(cmd, c->getCommand(), strlen(c->getCommand()))) {
if (c->runCommand(cmd)) {
LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno));
}
return;
}
}
LOGE("No cmd handlers defined for '%s'", cmd);
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
#include <cutils/config_utils.h>
#include <cutils/cpu_info.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
#define LOG_TAG "FrameworkManager"
#include <cutils/log.h>
#include <sysutils/FrameworkManager.h>
#include <sysutils/FrameworkListener.h>
FrameworkManager::FrameworkManager(FrameworkListener *Listener) {
mDoorbell = -1;
mFwSock = -1;
mListener = Listener;
pthread_mutex_init(&mWriteMutex, NULL);
}
int FrameworkManager::run() {
if (mListener->run()) {
LOGE("Error running listener (%s)", strerror(errno));
return -1;
}
return 0;
}
/* ========
* Privates
* ========
*/
int FrameworkManager::sendMsg(char *msg) {
LOGD("FrameworkManager::sendMsg(%s)", msg);
if (mFwSock < 0) {
errno = EHOSTUNREACH;
return -1;
}
pthread_mutex_lock(&mWriteMutex);
if (write(mFwSock, msg, strlen(msg) +1) < 0) {
LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno));
}
pthread_mutex_unlock(&mWriteMutex);
return 0;
}
int FrameworkManager::sendMsg(char *msg, char *data) {
char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1);
if (!buffer) {
errno = -ENOMEM;
return -1;
}
strcpy(buffer, msg);
strcat(buffer, data);
return sendMsg(buffer);
}

View file

@ -0,0 +1,94 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#define LOG_TAG "NetlinkEvent"
#include <cutils/log.h>
#include <sysutils/NetlinkEvent.h>
const int NetlinkEvent::NlActionUnknown = 0;
const int NetlinkEvent::NlActionAdd = 1;
const int NetlinkEvent::NlActionRemove = 2;
const int NetlinkEvent::NlActionChange = 3;
NetlinkEvent::NetlinkEvent() {
mAction = NlActionUnknown;
}
NetlinkEvent::~NetlinkEvent() {
int i;
if (mPath)
free(mPath);
if (mSubsystem)
free(mSubsystem);
for (i = 0; i < NL_PARAMS_MAX; i++) {
if (!mParams[i])
break;
free(mParams[i]);
}
}
bool NetlinkEvent::decode(char *buffer, int size) {
char *s = buffer;
char *end;
int param_idx = 0;
int i;
int first = 1;
end = s + size;
while (s < end) {
if (first) {
char *p;
for (p = s; *p != '@'; p++);
p++;
mPath = strdup(p);
first = 0;
} else {
if (!strncmp(s, "ACTION=", strlen("ACTION="))) {
char *a = s + strlen("ACTION=");
if (!strcmp(a, "add"))
mAction = NlActionAdd;
else if (!strcmp(a, "remove"))
mAction = NlActionRemove;
else if (!strcmp(a, "change"))
mAction = NlActionChange;
} else if (!strncmp(s, "SEQNUM=", strlen("SEQNUM=")))
mSeq = atoi(s + strlen("SEQNUM="));
else if (!strncmp(s, "SUBSYSTEM=", strlen("SUBSYSTEM=")))
mSubsystem = strdup(s + strlen("SUBSYSTEM="));
else
mParams[param_idx++] = strdup(s);
}
s+= strlen(s) + 1;
}
return true;
}
const char *NetlinkEvent::findParam(const char *paramName) {
int i;
for (i = 0; i < NL_PARAMS_MAX; i++) {
if (!mParams[i])
break;
if (!strncmp(mParams[i], paramName, strlen(paramName)))
return &mParams[i][strlen(paramName) + 1];
}
LOGE("NetlinkEvent::FindParam(): Parameter '%s' not found", paramName);
return NULL;
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#define LOG_TAG "NetlinkListener"
#include <cutils/log.h>
#include <sysutils/NetlinkListener.h>
#include <sysutils/NetlinkEvent.h>
NetlinkListener::NetlinkListener(int socket) :
SocketListener(socket, false) {
}
bool NetlinkListener::onDataAvailable(int socket)
{
LOGD("NetlinkListener::onDataAvailable()");
int count;
if ((count = recv(socket, mBuffer, sizeof(mBuffer), 0)) < 0) {
LOGE("recv failed (%s)", strerror(errno));
return false;
}
NetlinkEvent *evt = new NetlinkEvent();
if (!evt->decode(mBuffer, count)) {
LOGE("Error decoding NetlinkEvent");
goto out;
}
LOGD("Ignoring '%s' netlink event", evt->getSubsystem());
out:
delete evt;
return true;
}

View file

@ -0,0 +1,127 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
#define LOG_TAG "SocketListener"
#include <cutils/log.h>
#include <cutils/sockets.h>
#include <sysutils/SocketListener.h>
SocketListener::SocketListener(const char *socketName, bool acceptClients) {
mAcceptClients = acceptClients;
mCsock = -1;
mSocketName = socketName;
mSock = -1;
}
SocketListener::SocketListener(int socketFd, bool acceptClients) {
mAcceptClients = acceptClients;
mCsock = -1;
mSocketName = NULL;
mSock = socketFd;
}
int SocketListener::run() {
if (!mSocketName && mSock == -1) {
errno = EINVAL;
return -1;
} else if (mSocketName) {
if ((mSock = android_get_control_socket(mSocketName)) < 0) {
LOGE("Obtaining file descriptor socket '%s' failed: %s",
mSocketName, strerror(errno));
return -1;
}
}
if (mAcceptClients) {
if (listen(mSock, 4) < 0) {
LOGE("Unable to listen on socket (%s)", strerror(errno));
return -1;
}
}
while(1) {
fd_set read_fds;
struct timeval to;
int max = 0;
int rc = 0;
to.tv_sec = 60 * 60;
to.tv_usec = 0;
FD_ZERO(&read_fds);
if ((mAcceptClients == false) ||
(mAcceptClients == true && mCsock == -1)) {
FD_SET(mSock, &read_fds);
max = mSock;
} else if (mCsock != -1) {
FD_SET(mCsock, &read_fds);
max = mCsock;
}
if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) {
LOGE("select failed (%s)", strerror(errno));
return -errno;
} else if (!rc)
continue;
else if (FD_ISSET(mSock, &read_fds)) {
/*
* If we're accepting client connections then
* accept and gobble the event. Otherwise
* pass it on to the handlers.
*/
if (mAcceptClients) {
struct sockaddr addr;
socklen_t alen = sizeof(addr);
if ((mCsock = accept(mSock, &addr, &alen)) < 0) {
LOGE("accept failed (%s)", strerror(errno));
return -errno;
}
LOGD("SocketListener client connection accepted");
} else if (!onDataAvailable(mSock)) {
LOGW("SocketListener closing listening socket (Will shut down)");
close(mSock);
return -ESHUTDOWN;
}
} else if ((FD_ISSET(mCsock, &read_fds)) &&
!onDataAvailable(mCsock)) {
/*
* Once mCsock == -1, we'll start
* accepting connections on mSock again.
*/
LOGD("SocketListener closing client socket");
close(mCsock);
mCsock = -1;
}
}
return 0;
}
bool SocketListener::onDataAvailable(int socket) {
return false;
}

47
nexus/Android.mk Normal file
View file

@ -0,0 +1,47 @@
BUILD_NEXUS := false
ifeq ($(BUILD_NEXUS),true)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
main.cpp \
NetworkManager.cpp \
CommandListener.cpp \
Controller.cpp \
WifiController.cpp \
LoopController.cpp \
NexusCommand.cpp \
TiwlanWifiController.cpp \
Supplicant.cpp \
SupplicantEvent.cpp \
SupplicantListener.cpp \
VpnController.cpp \
ScanResult.cpp \
LOCAL_MODULE:= nexus
LOCAL_C_INCLUDES := $(KERNEL_HEADERS)
LOCAL_CFLAGS :=
LOCAL_SHARED_LIBRARIES := libsysutils libwpa_client libutils
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
nexctl.c \
LOCAL_MODULE:= nexctl
LOCAL_C_INCLUDES := $(KERNEL_HEADERS)
LOCAL_CFLAGS :=
LOCAL_SHARED_LIBRARIES := libutils
include $(BUILD_EXECUTABLE)
endif # ifeq ($(BUILD_NEXUS),true)

124
nexus/CommandListener.cpp Normal file
View file

@ -0,0 +1,124 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <errno.h>
#define LOG_TAG "CommandListener"
#include <cutils/log.h>
#include "CommandListener.h"
#include "Controller.h"
#include "NetworkManager.h"
#include "WifiController.h"
CommandListener::CommandListener(NetworkManager *netman) :
FrameworkListener("nexus") {
mNetman = netman;
registerCmd(new WifiEnableCmd(netman));
registerCmd(new WifiDisableCmd(netman));
registerCmd(new WifiScanCmd(netman));
registerCmd(new VpnEnableCmd(netman));
registerCmd(new VpnDisableCmd(netman));
}
/* -------------
* Wifi Commands
* ------------ */
CommandListener::WifiEnableCmd::WifiEnableCmd(NetworkManager *netman) :
NexusCommand("wifi_enable", netman) {
}
int CommandListener::WifiEnableCmd::runCommand(char *data) {
Controller *c = mNetman->findController("WIFI");
char buffer[32];
sprintf(buffer, "WIFI_ENABLE:%d", (c->enable() ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
return 0;
}
CommandListener::WifiDisableCmd::WifiDisableCmd(NetworkManager *netman) :
NexusCommand("wifi_disable", netman) {
}
int CommandListener::WifiDisableCmd::runCommand(char *data) {
Controller *c = mNetman->findController("WIFI");
char buffer[32];
sprintf(buffer, "WIFI_DISABLE:%d", (c->disable() ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
return 0;
}
CommandListener::WifiScanCmd::WifiScanCmd(NetworkManager *netman) :
NexusCommand("wifi_scan", netman) {
}
int CommandListener::WifiScanCmd::runCommand(char *data) {
LOGD("WifiScanCmd(%s)", data);
WifiController *wc = (WifiController *) mNetman->findController("WIFI");
char buffer[32];
int mode = 0;
char *bword, *last;
if (!(bword = strtok_r(data, ":", &last))) {
errno = EINVAL;
return -1;
}
if (!(bword = strtok_r(NULL, ":", &last))) {
errno = EINVAL;
return -1;
}
mode = atoi(bword);
sprintf(buffer, "WIFI_SCAN:%d", (wc->setScanMode(mode) ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
return 0;
}
/* ------------
* Vpn Commands
* ------------ */
CommandListener::VpnEnableCmd::VpnEnableCmd(NetworkManager *netman) :
NexusCommand("vpn_enable", netman) {
}
int CommandListener::VpnEnableCmd::runCommand(char *data) {
Controller *c = mNetman->findController("VPN");
char buffer[32];
sprintf(buffer, "VPN_ENABLE:%d", (c->enable() ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
return 0;
}
CommandListener::VpnDisableCmd::VpnDisableCmd(NetworkManager *netman) :
NexusCommand("vpn_disable", netman) {
}
int CommandListener::VpnDisableCmd::runCommand(char *data) {
Controller *c = mNetman->findController("VPN");
char buffer[32];
sprintf(buffer, "VPN_DISABLE:%d", (c->disable() ? errno : 0));
mNetman->getFrameworkManager()->sendMsg(buffer);
return 0;
}

70
nexus/CommandListener.h Normal file
View file

@ -0,0 +1,70 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _COMMANDLISTENER_H__
#define _COMMANDLISTENER_H__
#include <sysutils/FrameworkListener.h>
#include "NexusCommand.h"
class NetworkManager;
class CommandListener : public FrameworkListener {
protected:
NetworkManager *mNetman;
public:
CommandListener(NetworkManager *netman);
virtual ~CommandListener() {}
private:
class WifiEnableCmd : public NexusCommand {
public:
WifiEnableCmd(NetworkManager *);
virtual ~WifiEnableCmd() {}
int runCommand(char *data);
};
class WifiDisableCmd : public NexusCommand {
public:
WifiDisableCmd(NetworkManager *);
virtual ~WifiDisableCmd() {}
int runCommand(char *data);
};
class WifiScanCmd : public NexusCommand {
public:
WifiScanCmd(NetworkManager *);
virtual ~WifiScanCmd() {}
int runCommand(char *data);
};
class VpnEnableCmd : public NexusCommand {
public:
VpnEnableCmd(NetworkManager *);
virtual ~VpnEnableCmd() {}
int runCommand(char *data);
};
class VpnDisableCmd : public NexusCommand {
public:
VpnDisableCmd(NetworkManager *);
virtual ~VpnDisableCmd() {}
int runCommand(char *data);
};
};
#endif

144
nexus/Controller.cpp Normal file
View file

@ -0,0 +1,144 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <malloc.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define LOG_TAG "Controller"
#include <cutils/log.h>
#include "Controller.h"
extern "C" int init_module(void *, unsigned int, const char *);
extern "C" int delete_module(const char *, unsigned int);
Controller::Controller(const char *name) {
mName = name;
}
int Controller::start() {
return 0;
}
int Controller::stop() {
return 0;
}
int Controller::loadKernelModule(char *modpath, const char *args) {
void *module;
unsigned int size;
LOGD("loadKernelModule(%s, %s)", modpath, args);
module = loadFile(modpath, &size);
if (!module) {
errno = -EIO;
return -1;
}
int rc = init_module(module, size, args);
free (module);
return rc;
}
int Controller::unloadKernelModule(const char *modtag) {
int rc = -1;
int retries = 10;
LOGD("unloadKernelModule(%s)", modtag);
while (retries--) {
rc = delete_module(modtag, O_NONBLOCK | O_EXCL);
if (rc < 0 && errno == EAGAIN)
usleep(1000*500);
else
break;
}
if (rc != 0) {
LOGW("Unable to unload kernel driver '%s' (%s)", modtag,
strerror(errno));
}
return rc;
}
bool Controller::isKernelModuleLoaded(const char *modtag) {
FILE *fp = fopen("/proc/modules", "r");
if (!fp) {
LOGE("Unable to open /proc/modules (%s)", strerror(errno));
return false;
}
char line[255];
while(fgets(line, sizeof(line), fp)) {
char *endTag = strchr(line, ' ');
if (!endTag) {
LOGW("Unable to find tag for line '%s'", line);
continue;
}
if (!strncmp(line, modtag, (endTag - line))) {
fclose(fp);
return true;
}
}
fclose(fp);
return false;
}
void *Controller::loadFile(char *filename, unsigned int *_size)
{
int ret, fd;
struct stat sb;
ssize_t size;
void *buffer = NULL;
/* open the file */
fd = open(filename, O_RDONLY);
if (fd < 0)
return NULL;
/* find out how big it is */
if (fstat(fd, &sb) < 0)
goto bail;
size = sb.st_size;
/* allocate memory for it to be read into */
buffer = malloc(size);
if (!buffer)
goto bail;
/* slurp it into our buffer */
ret = read(fd, buffer, size);
if (ret != size)
goto bail;
/* let the caller know how big it is */
*_size = size;
bail:
close(fd);
return buffer;
}

47
nexus/Controller.h Normal file
View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _CONTROLLER_H
#define _CONTROLLER_H
#include "../../../frameworks/base/include/utils/List.h"
class Controller {
private:
const char *mName;
public:
Controller(const char *name);
virtual ~Controller() {}
virtual int start();
virtual int stop();
virtual int enable() = 0;
virtual int disable() = 0;
virtual const char *getName() { return mName; }
protected:
int loadKernelModule(char *modpath, const char *args);
bool isKernelModuleLoaded(const char *modtag);
int unloadKernelModule(const char *modtag);
private:
void *loadFile(char *filename, unsigned int *_size);
};
typedef android::List<Controller *> ControllerCollection;
#endif

32
nexus/LoopController.cpp Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include "LoopController.h"
LoopController::LoopController() :
Controller("LOOP") {
}
int LoopController::enable() {
errno = ENOSYS;
return -1;
}
int LoopController::disable() {
errno = ENOSYS;
return -1;
}

30
nexus/LoopController.h Normal file
View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _LOOP_CONTROLLER_H
#define _LOOP_CONTROLLER_H
#include "Controller.h"
class LoopController : public Controller {
public:
LoopController();
virtual ~LoopController() {}
int enable();
int disable();
};
#endif

100
nexus/NetworkManager.cpp Normal file
View file

@ -0,0 +1,100 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <errno.h>
#define LOG_TAG "Nexus"
#include <cutils/log.h>
#include "NetworkManager.h"
#include "CommandListener.h"
#include "LoopController.h"
#include "VpnController.h"
#include "TiwlanWifiController.h"
NetworkManager::NetworkManager() {
mListener = new CommandListener(this);
mFm = new FrameworkManager(mListener);
mControllers = new ControllerCollection();
}
int NetworkManager::run() {
LOGD("NetworkManager::start()");
// XXX: Factory needed
addController(new LoopController());
addController(new TiwlanWifiController("/system/lib/modules/wlan.ko", "wlan", ""));
addController(new VpnController());
//addController(new GenericController("rmnet0"));
if (startControllers()) {
LOGW("Unable to start all controllers (%s)", strerror(errno));
}
mFm->run();
return 0;
}
void NetworkManager::addController(Controller *c) {
mControllers->push_back(c);
}
int NetworkManager::startControllers() {
int rc = 0;
ControllerCollection::iterator i;
for (i = mControllers->begin(); i != mControllers->end(); ++i) {
int irc = (*i)->start();
LOGD("Controller '%s' start rc = %d", (*i)->getName(), irc);
if (irc && !rc)
rc = irc;
}
return rc;
}
int NetworkManager::stopControllers() {
int rc = 0;
ControllerCollection::iterator i;
for (i = mControllers->begin(); i != mControllers->end(); ++i) {
int irc = (*i)->stop();
LOGD("Controller '%s' stop rc = %d", (*i)->getName(), irc);
if (irc && !rc)
rc = irc;
}
return rc;
}
Controller *NetworkManager::findController(const char *name) {
ControllerCollection::iterator i;
for (i = mControllers->begin(); i != mControllers->end(); ++i) {
if (!strcmp((*i)->getName(), name))
return *i;
}
LOGW("Controller '%s' not found", name);
return NULL;
}
int NetworkManager::onInterfaceCreated(Controller *c, char *name) {
LOGD("Interface %s created by controller %s", name, c->getName());
return 0;
}
int NetworkManager::onInterfaceDestroyed(Controller *c, char *name) {
LOGD("Interface %s destroyed by controller %s", name, c->getName());
return 0;
}

51
nexus/NetworkManager.h Normal file
View file

@ -0,0 +1,51 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _NETWORKMANAGER_H
#define _NETWORKMANAGER_H
#include "Controller.h"
#include <sysutils/FrameworkManager.h>
class NetworkManager {
private:
FrameworkListener *mListener;
FrameworkManager *mFm;
ControllerCollection *mControllers;
public:
NetworkManager();
virtual ~NetworkManager() {}
int run();
private:
void addController(Controller *c);
int startControllers();
int stopControllers();
public:
Controller *findController(const char *name);
ControllerCollection *getControllers() { return mControllers; }
FrameworkManager *getFrameworkManager() { return mFm; }
public:
// XXX: Extract these into an interface
int onInterfaceCreated(Controller *c, char *name);
int onInterfaceDestroyed(Controller *c, char *name);
};
#endif

21
nexus/NexusCommand.cpp Normal file
View file

@ -0,0 +1,21 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "NexusCommand.h"
NexusCommand::NexusCommand(const char *cmd, NetworkManager *netman) :
FrameworkCommand(cmd) {
mNetman = netman;
}

32
nexus/NexusCommand.h Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _NEXUS_COMMAND_H
#define _NEXUS_COMMAND_H
#include <sysutils/FrameworkCommand.h>
class NetworkManager;
class NexusCommand : public FrameworkCommand {
protected:
NetworkManager *mNetman;
public:
NexusCommand(const char *cmd, NetworkManager *netman);
virtual ~NexusCommand() {}
};
#endif

74
nexus/ScanResult.cpp Normal file
View file

@ -0,0 +1,74 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#define LOG_TAG "ScanResult"
#include <cutils/log.h>
#include "ScanResult.h"
ScanResult::ScanResult() {
}
ScanResult::ScanResult(char *rawResult) {
char *tok, *next = NULL;
if (!(tok = strtok_r(rawResult, "\t", &next)))
goto out_bad;
mBssid = strdup(tok);
if (!(tok = strtok_r(NULL, "\t", &next)))
goto out_bad;
mFreq = atoi(tok);
if (!(tok = strtok_r(NULL, "\t", &next)))
goto out_bad;
mLevel = atoi(tok);
if (!(tok = strtok_r(rawResult, "\t", &next)))
goto out_bad;
mFlags = strdup(tok);
if (!(tok = strtok_r(rawResult, "\t", &next)))
goto out_bad;
mSsid = strdup(tok);
return;
out_bad:
LOGW("Malformatted scan result (%s)", rawResult);
}
ScanResult::~ScanResult() {
if (mBssid)
free(mBssid);
if (mFlags)
free(mFlags);
if (mSsid)
free(mSsid);
}
ScanResult *ScanResult::clone() {
ScanResult *r = new ScanResult();
r->mBssid = strdup(mBssid);
r->mFreq = mFreq;
r->mLevel = mLevel;
r->mFlags = strdup(mFlags);
r->mSsid = strdup(mSsid);
return r;
}

47
nexus/ScanResult.h Normal file
View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SCAN_RESULT_H
#define _SCAN_RESULT_H
#include <sys/types.h>
#include "../../../frameworks/base/include/utils/List.h"
class ScanResult {
char *mBssid;
uint32_t mFreq;
int mLevel;
char *mFlags;
char *mSsid;
private:
ScanResult();
public:
ScanResult(char *rawResult);
virtual ~ScanResult();
ScanResult *clone();
const char *getBssid() { return mBssid; }
uint32_t getFreq() { return mFreq; }
const char *getFlags() { return mFlags; }
const char *getSsid() { return mSsid; }
};
typedef android::List<ScanResult *> ScanResultCollection;
#endif

377
nexus/Supplicant.cpp Normal file
View file

@ -0,0 +1,377 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#define LOG_TAG "Supplicant"
#include <cutils/log.h>
#include <cutils/properties.h>
#undef HAVE_LIBC_SYSTEM_PROPERTIES
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
#endif
#include "Supplicant.h"
#include "SupplicantListener.h"
#include "SupplicantState.h"
#include "SupplicantEvent.h"
#include "ScanResult.h"
#include "libwpa_client/wpa_ctrl.h"
#define IFACE_DIR "/data/system/wpa_supplicant"
#define DRIVER_PROP_NAME "wlan.driver.status"
#define SUPPLICANT_NAME "wpa_supplicant"
#define SUPP_PROP_NAME "init.svc.wpa_supplicant"
Supplicant::Supplicant() {
mCtrl = NULL;
mMonitor = NULL;
mListener = NULL;
mState = SupplicantState::UNKNOWN;
mLatestScanResults = new ScanResultCollection();
pthread_mutex_init(&mLatestScanResultsLock, NULL);
}
int Supplicant::start() {
LOGD("start():");
// XXX: Validate supplicant config file
char status[PROPERTY_VALUE_MAX] = {'\0'};
int count = 200;
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
const prop_info *pi;
unsigned int serial = 0;
#endif
if (property_get(SUPP_PROP_NAME, status, NULL) &&
strcmp(status, "running") == 0) {
return 0;
}
wpa_ctrl_cleanup();
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
pi = __system_property_find(SUPP_PROP_NAME);
if (pi != NULL)
serial = pi->serial;
#endif
property_set("ctl.start", SUPPLICANT_NAME);
sched_yield();
while (count--) {
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
if (!pi)
pi = __system_property_find(SUPP_PROP_NAME);
if (pi) {
__system_property_read(pi, NULL, status);
if (strcmp(status, "running") == 0)
return 0;
else if (pi->serial != serial &&
strcmp(status, "stopped") == 0) {
errno = EIO;
return -1;
}
}
#else
if (property_get(SUPP_PROP_NAME, status, NULL)) {
if (strcmp(status, "running") == 0)
break;
}
#endif
usleep(100000);
}
if (!count) {
errno = ETIMEDOUT;
return -1;
}
if (connectToSupplicant()) {
LOGE("Error connecting to supplicant (%s)\n", strerror(errno));
return -1;
}
return 0;
}
int Supplicant::stop() {
LOGD("stop()");
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
int count = 50;
if (mListener->stopListener()) {
LOGW("Unable to stop supplicant listener (%s)", strerror(errno));
return -1;
}
if (property_get(SUPP_PROP_NAME, supp_status, NULL)
&& strcmp(supp_status, "stopped") == 0) {
return 0;
}
property_set("ctl.stop", SUPPLICANT_NAME);
sched_yield();
while (count-- > 0) {
if (property_get(SUPP_PROP_NAME, supp_status, NULL)) {
if (strcmp(supp_status, "stopped") == 0)
break;
}
usleep(100000);
}
if (mCtrl) {
wpa_ctrl_close(mCtrl);
mCtrl = NULL;
}
if (mMonitor) {
wpa_ctrl_close(mMonitor);
mMonitor = NULL;
}
if (!count) {
LOGD("Timed out waiting for supplicant to stop");
errno = ETIMEDOUT;
return -1;
}
LOGD("Stopped OK");
return 0;
}
bool Supplicant::isStarted() {
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
if (!property_get(SUPP_PROP_NAME, supp_status, NULL) ||
!strcmp(supp_status, "running")) {
return false;
}
return true;
}
int Supplicant::connectToSupplicant() {
char ifname[256];
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
if (!property_get(SUPP_PROP_NAME, supp_status, NULL)
|| strcmp(supp_status, "running") != 0) {
LOGE("Supplicant not running, cannot connect");
return -1;
}
mCtrl = wpa_ctrl_open("tiwlan0");
if (mCtrl == NULL) {
LOGE("Unable to open connection to supplicant on \"%s\": %s",
"tiwlan0", strerror(errno));
return -1;
}
mMonitor = wpa_ctrl_open("tiwlan0");
if (mMonitor == NULL) {
wpa_ctrl_close(mCtrl);
mCtrl = NULL;
return -1;
}
if (wpa_ctrl_attach(mMonitor) != 0) {
wpa_ctrl_close(mMonitor);
wpa_ctrl_close(mCtrl);
mCtrl = mMonitor = NULL;
return -1;
}
mListener = new SupplicantListener(this, mMonitor);
if (mListener->startListener()) {
LOGE("Error - unable to start supplicant listener");
stop();
return -1;
}
return 0;
}
int Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len)
{
if (!mCtrl) {
errno = ENOTCONN;
return -1;
}
LOGD("sendCommand(): -> '%s'", cmd);
int rc;
if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) {
errno = ETIMEDOUT;
return -1;
} else if (rc < 0 || !strncmp(reply, "FAIL", 4)) {
errno = EIO;
return -1;
}
if (!strncmp(cmd, "PING", 4) ||
!strncmp(cmd, "SCAN_RESULTS", 12))
reply[*reply_len] = '\0';
LOGD("sendCommand(): <- '%s'", reply);
return 0;
}
int Supplicant::triggerScan(bool active) {
char reply[255];
size_t len = sizeof(reply);
if (sendCommand((active ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"),
reply, &len)) {
LOGW("triggerScan(%d): Error setting scan mode (%s)", active,
strerror(errno));
return -1;
}
len = sizeof(reply);
if (sendCommand("SCAN", reply, &len)) {
LOGW("triggerScan(%d): Error initiating scan", active);
return -1;
}
return 0;
}
int Supplicant::onConnectedEvent(SupplicantEvent *evt) {
LOGD("onConnectedEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onDisconnectedEvent(SupplicantEvent *evt) {
LOGD("onDisconnectedEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onTerminatingEvent(SupplicantEvent *evt) {
LOGD("onTerminatingEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onPasswordChangedEvent(SupplicantEvent *evt) {
LOGD("onPasswordChangedEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onEapNotificationEvent(SupplicantEvent *evt) {
LOGD("onEapNotificationEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onEapStartedEvent(SupplicantEvent *evt) {
LOGD("onEapStartedEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onEapMethodEvent(SupplicantEvent *evt) {
LOGD("onEapMethodEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onEapSuccessEvent(SupplicantEvent *evt) {
LOGD("onEapSuccessEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onEapFailureEvent(SupplicantEvent *evt) {
LOGD("onEapFailureEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onScanResultsEvent(SupplicantEvent *evt) {
LOGD("onScanResultsEvent(%s)", evt->getEvent());
if (!strcmp(evt->getEvent(), "Ready")) {
char *reply;
if (!(reply = (char *) malloc(4096))) {
errno = -ENOMEM;
return -1;
}
size_t len = 4096;
if (sendCommand("SCAN_RESULTS", reply, &len)) {
LOGW("onScanResultsEvent(%s): Error getting scan results (%s)",
evt->getEvent(), strerror(errno));
free(reply);
return -1;
}
pthread_mutex_lock(&mLatestScanResultsLock);
if (!mLatestScanResults->empty()) {
ScanResultCollection::iterator i;
for (i = mLatestScanResults->begin();
i !=mLatestScanResults->end(); ++i) {
delete *i;
}
mLatestScanResults->clear();
}
char *linep;
char *linep_next = NULL;
if (!strtok_r(reply, "\n", &linep_next)) {
free(reply);
return 0;;
}
while((linep = strtok_r(NULL, "\n", &linep_next)))
mLatestScanResults->push_back(new ScanResult(linep));
pthread_mutex_unlock(&mLatestScanResultsLock);
free(reply);
} else {
LOGW("Unknown SCAN_RESULTS event (%s)", evt->getEvent());
}
return 0;
}
int Supplicant::onStateChangeEvent(SupplicantEvent *evt) {
LOGD("onStateChangeEvent(%s)", evt->getEvent());
// XXX: Update mState
return 0;
}
int Supplicant::onLinkSpeedEvent(SupplicantEvent *evt) {
LOGD("onLinkSpeedEvent(%s)", evt->getEvent());
return 0;
}
int Supplicant::onDriverStateEvent(SupplicantEvent *evt) {
LOGD("onDriverStateEvent(%s)", evt->getEvent());
return 0;
}
// XXX: Use a cursor + smartptr instead
const ScanResultCollection *Supplicant::getLatestScanResults() {
ScanResultCollection *d = new ScanResultCollection();
ScanResultCollection::iterator i;
pthread_mutex_lock(&mLatestScanResultsLock);
for (i = mLatestScanResults->begin(); i != mLatestScanResults->end(); ++i) {
d->push_back((*i)->clone());
}
pthread_mutex_unlock(&mLatestScanResultsLock);
return d;
};

72
nexus/Supplicant.h Normal file
View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SUPPLICANT_H
#define _SUPPLICANT_H
struct wpa_ctrl;
class SupplicantListener;
class SupplicantEvent;
#include <pthread.h>
#include "ScanResult.h"
class Supplicant {
private:
struct wpa_ctrl *mCtrl;
struct wpa_ctrl *mMonitor;
SupplicantListener *mListener;
int mState;
ScanResultCollection *mLatestScanResults;
pthread_mutex_t mLatestScanResultsLock;
public:
Supplicant();
virtual ~Supplicant() {}
virtual int start();
virtual int stop();
virtual bool isStarted();
virtual int triggerScan(bool active);
int getState() { return mState; }
const ScanResultCollection *getLatestScanResults();
// XXX: Extract these into an interface
public:
virtual int onConnectedEvent(SupplicantEvent *evt);
virtual int onDisconnectedEvent(SupplicantEvent *evt);
virtual int onTerminatingEvent(SupplicantEvent *evt);
virtual int onPasswordChangedEvent(SupplicantEvent *evt);
virtual int onEapNotificationEvent(SupplicantEvent *evt);
virtual int onEapStartedEvent(SupplicantEvent *evt);
virtual int onEapMethodEvent(SupplicantEvent *evt);
virtual int onEapSuccessEvent(SupplicantEvent *evt);
virtual int onEapFailureEvent(SupplicantEvent *evt);
virtual int onScanResultsEvent(SupplicantEvent *evt);
virtual int onStateChangeEvent(SupplicantEvent *evt);
virtual int onLinkSpeedEvent(SupplicantEvent *evt);
virtual int onDriverStateEvent(SupplicantEvent *evt);
private:
int connectToSupplicant();
int sendCommand(const char *cmd, char *reply, size_t *reply_len);
};
#endif

95
nexus/SupplicantEvent.cpp Normal file
View file

@ -0,0 +1,95 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#define LOG_TAG "SupplicantEvent"
#include <cutils/log.h>
#include "SupplicantEvent.h"
#include "libwpa_client/wpa_ctrl.h"
SupplicantEvent::SupplicantEvent(char *event, size_t len) {
if (event[0] == '<') {
char *match = strchr(event, '>');
if (match) {
char tmp[16];
strncpy(tmp, &event[1], (match - event));
mLevel = atoi(tmp);
event += (match - event) + 1;
} else
LOGW("Unclosed level brace in event");
} else
LOGW("No level specified in event");
/*
* <N>CTRL-EVENT-XXX
* ^
* +---- event
*/
if (!strncmp(event, WPA_EVENT_CONNECTED, strlen(WPA_EVENT_CONNECTED)))
mType = SupplicantEvent::EVENT_CONNECTED;
else if (!strncmp(event, WPA_EVENT_DISCONNECTED, strlen(WPA_EVENT_DISCONNECTED)))
mType = SupplicantEvent::EVENT_DISCONNECTED;
else if (!strncmp(event, WPA_EVENT_TERMINATING, strlen(WPA_EVENT_TERMINATING)))
mType = SupplicantEvent::EVENT_TERMINATING;
else if (!strncmp(event, WPA_EVENT_PASSWORD_CHANGED, strlen(WPA_EVENT_PASSWORD_CHANGED)))
mType = SupplicantEvent::EVENT_PASSWORD_CHANGED;
else if (!strncmp(event, WPA_EVENT_EAP_NOTIFICATION, strlen(WPA_EVENT_EAP_NOTIFICATION)))
mType = SupplicantEvent::EVENT_EAP_NOTIFICATION;
else if (!strncmp(event, WPA_EVENT_EAP_STARTED, strlen(WPA_EVENT_EAP_STARTED)))
mType = SupplicantEvent::EVENT_EAP_STARTED;
else if (!strncmp(event, WPA_EVENT_EAP_METHOD, strlen(WPA_EVENT_EAP_METHOD)))
mType = SupplicantEvent::EVENT_EAP_METHOD;
else if (!strncmp(event, WPA_EVENT_EAP_SUCCESS, strlen(WPA_EVENT_EAP_SUCCESS)))
mType = SupplicantEvent::EVENT_EAP_SUCCESS;
else if (!strncmp(event, WPA_EVENT_EAP_FAILURE, strlen(WPA_EVENT_EAP_FAILURE)))
mType = SupplicantEvent::EVENT_EAP_FAILURE;
else if (!strncmp(event, WPA_EVENT_SCAN_RESULTS, strlen(WPA_EVENT_SCAN_RESULTS)))
mType = SupplicantEvent::EVENT_SCAN_RESULTS;
else if (!strncmp(event, WPA_EVENT_STATE_CHANGE, strlen(WPA_EVENT_STATE_CHANGE)))
mType = SupplicantEvent::EVENT_STATE_CHANGE;
else if (!strncmp(event, WPA_EVENT_LINK_SPEED, strlen(WPA_EVENT_LINK_SPEED)))
mType = SupplicantEvent::EVENT_LINK_SPEED;
else if (!strncmp(event, WPA_EVENT_DRIVER_STATE, strlen(WPA_EVENT_DRIVER_STATE)))
mType = SupplicantEvent::EVENT_DRIVER_STATE;
else {
LOGW("Unknown supplicant event '%s'", event);
mType = SupplicantEvent::EVENT_UNKNOWN;
}
for (event; *event != ' '; event++);
event++;
/*
* <N>CTRL-EVENT-XXX YYYY
* ^
* +---- event
*/
for (event; *event == ' '; event++);
mEvent = strdup(event);
mLen = len;
}
SupplicantEvent::~SupplicantEvent() {
if (mEvent)
free(mEvent);
}

54
nexus/SupplicantEvent.h Normal file
View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SUPPLICANT_EVENT_H
#define _SUPPLICANT_EVENT_H
#include <sys/types.h>
class SupplicantEvent {
private:
int mType;
char *mEvent;
size_t mLen;
int mLevel;
public:
static const int EVENT_UNKNOWN = 0;
static const int EVENT_CONNECTED = 1;
static const int EVENT_DISCONNECTED = 2;
static const int EVENT_TERMINATING = 3;
static const int EVENT_PASSWORD_CHANGED = 4;
static const int EVENT_EAP_NOTIFICATION = 5;
static const int EVENT_EAP_STARTED = 6;
static const int EVENT_EAP_METHOD = 7;
static const int EVENT_EAP_SUCCESS = 8;
static const int EVENT_EAP_FAILURE = 9;
static const int EVENT_SCAN_RESULTS = 10;
static const int EVENT_STATE_CHANGE = 11;
static const int EVENT_LINK_SPEED = 12;
static const int EVENT_DRIVER_STATE = 13;
public:
SupplicantEvent(char *event, size_t len);
virtual ~SupplicantEvent();
int getType() { return mType; }
const char *getEvent() { return mEvent; }
int getLen() { return mLen; }
int getLevel() { return mLevel; }
};
#endif

View file

@ -0,0 +1,114 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <sys/types.h>
#include <pthread.h>
#define LOG_TAG "SupplicantListener"
#include <cutils/log.h>
#include "libwpa_client/wpa_ctrl.h"
#include "Supplicant.h"
#include "SupplicantListener.h"
#include "SupplicantEvent.h"
SupplicantListener::SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *monitor) :
SocketListener(wpa_ctrl_get_fd(monitor), false) {
mSupplicant = supplicant;
mMonitor = monitor;
mThread = NULL;
}
int SupplicantListener::startListener() {
LOGD("startListener()");
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
return pthread_create(&mThread, &attr, &SupplicantListener::threadStart, this);
}
int SupplicantListener::stopListener() {
errno = -ENOSYS;
return -1;
}
void *SupplicantListener::threadStart(void *obj) {
LOGD("threadStart(): Worker thread started");
reinterpret_cast<SupplicantListener *>(obj)->run();
LOGD("threadStart(): Worker thread exited");
return NULL;
}
bool SupplicantListener::onDataAvailable(int socket) {
char buf[255];
size_t buflen = sizeof(buf);
int rc;
size_t nread = buflen - 1;
if ((rc = wpa_ctrl_recv(mMonitor, buf, &nread))) {
LOGE("wpa_ctrl_recv failed (%s)", strerror(errno));
return -errno;
}
buf[nread] = '\0';
if (!rc && !nread) {
LOGD("Received EOF on supplicant socket\n");
strncpy(buf, WPA_EVENT_TERMINATING " - signal 0 received", buflen-1);
buf[buflen-1] = '\0';
return false;
}
SupplicantEvent *evt = new SupplicantEvent(buf, nread);
// XXX: Make this a factory
// XXX: Instead of calling Supplicant directly
// extract an Interface and use that instead
if (evt->getType() == SupplicantEvent::EVENT_CONNECTED)
rc = mSupplicant->onConnectedEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_DISCONNECTED)
rc = mSupplicant->onDisconnectedEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_TERMINATING)
rc = mSupplicant->onTerminatingEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_PASSWORD_CHANGED)
rc = mSupplicant->onPasswordChangedEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_EAP_NOTIFICATION)
rc = mSupplicant->onEapNotificationEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_EAP_STARTED)
rc = mSupplicant->onEapStartedEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_EAP_SUCCESS)
rc = mSupplicant->onEapSuccessEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_EAP_FAILURE)
rc = mSupplicant->onEapFailureEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_SCAN_RESULTS)
rc = mSupplicant->onScanResultsEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_STATE_CHANGE)
rc = mSupplicant->onStateChangeEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_LINK_SPEED)
rc = mSupplicant->onLinkSpeedEvent(evt);
else if (evt->getType() == SupplicantEvent::EVENT_DRIVER_STATE)
rc = mSupplicant->onDriverStateEvent(evt);
else {
LOGW("Ignoring unknown event");
}
delete evt;
if (rc)
return false;
return true;
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SUPPLICANTLISTENER_H__
#define _SUPPLICANTLISTENER_H__
#include <pthread.h>
#include <sysutils/SocketListener.h>
struct wpa_ctrl;
class Supplicant;
class SupplicantListener: public SocketListener {
private:
struct wpa_ctrl *mMonitor;
Supplicant *mSupplicant;
pthread_t mThread;
public:
SupplicantListener(Supplicant *supplicant, struct wpa_ctrl *monitor);
virtual ~SupplicantListener() {}
int startListener();
int stopListener();
struct wpa_ctrl *getMonitor() { return mMonitor; }
Supplicant *getSupplicant() { return mSupplicant; }
protected:
virtual bool onDataAvailable(int socket);
private:
static void *threadStart(void *obj);
};
#endif

33
nexus/SupplicantState.h Normal file
View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SUPPLICANT_STATE_H
#define _SUPPLICANT_STATE_H
class SupplicantState {
public:
static const int UNKNOWN = 0;
static const int DISCONNECTED = 1;
static const int INACTIVE = 2;
static const int SCANNING = 3;
static const int ASSOCIATING = 4;
static const int ASSOCIATED = 5;
static const int FOURWAY_HANDSHAKE = 6;
static const int GROUP_HANDSHAKE = 7;
static const int COMPLETED = 8;
static const int IDLE = 9;
};
#endif

View file

@ -0,0 +1,67 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <cutils/properties.h>
#define LOG_TAG "TiwlanWifiController"
#include <cutils/log.h>
#include "TiwlanWifiController.h"
#define DRIVER_PROP_NAME "wlan.driver.status"
extern "C" int sched_yield(void);
TiwlanWifiController::TiwlanWifiController(char *modpath, char *modname, char *modargs) :
WifiController(modpath, modname, modargs) {
}
int TiwlanWifiController::powerUp() {
return 0; // Powerup is currently done when the driver is loaded
}
int TiwlanWifiController::powerDown() {
return 0; // Powerdown is currently done when the driver is unloaded
}
bool TiwlanWifiController::isPoweredUp() {
return isKernelModuleLoaded(getModuleName());
}
int TiwlanWifiController::loadFirmware() {
char driver_status[PROPERTY_VALUE_MAX];
int count = 100;
LOGD("loadFirmware()");
property_set("ctl.start", "wlan_loader");
sched_yield();
// Wait for driver to be ready
while (count-- > 0) {
if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
if (strcmp(driver_status, "ok") == 0)
return 0;
else if (strcmp(DRIVER_PROP_NAME, "failed") == 0)
return -1;
}
usleep(200000);
}
property_set(DRIVER_PROP_NAME, "timeout");
return -1;
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _TIWLAN_WIFI_CONTROLLER_H
#define _TIWLAN_WIFI_CONTROLLER_H
#include "WifiController.h"
class TiwlanWifiController : public WifiController {
public:
TiwlanWifiController(char *modpath, char *modname, char *modargs);
virtual ~TiwlanWifiController() {}
virtual int powerUp();
virtual int powerDown();
virtual bool isPoweredUp();
virtual int loadFirmware();
};
#endif

44
nexus/VpnController.cpp Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include "VpnController.h"
VpnController::VpnController() :
Controller("VPN") {
}
int VpnController::start() {
errno = -ENOSYS;
return -1;
}
int VpnController::stop() {
errno = -ENOSYS;
return -1;
}
int VpnController::enable() {
// Load modules
// Start daemons
errno = -ENOSYS;
return -1;
}
int VpnController::disable() {
errno = -ENOSYS;
return -1;
}

38
nexus/VpnController.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _VPN_CONTROLLER_H
#define _VPN_CONTROLLER_H
#include "Controller.h"
class VpnController : public Controller {
public:
VpnController();
virtual ~VpnController() {}
virtual int start();
virtual int stop();
virtual int enable();
virtual int disable();
protected:
private:
};
#endif

134
nexus/WifiController.cpp Normal file
View file

@ -0,0 +1,134 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include <errno.h>
#define LOG_TAG "WifiController"
#include <cutils/log.h>
#include "Supplicant.h"
#include "WifiController.h"
WifiController::WifiController(char *modpath, char *modname, char *modargs) :
Controller("WIFI") {
strncpy(mModulePath, modpath, sizeof(mModulePath));
strncpy(mModuleName, modname, sizeof(mModuleName));
strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
mSupplicant = new Supplicant();
mCurrentScanMode = 0;
}
int WifiController::start() {
return 0;
}
int WifiController::stop() {
errno = ENOSYS;
return -1;
}
int WifiController::enable() {
if (!isPoweredUp() && powerUp()) {
LOGE("Powerup failed (%s)", strerror(errno));
return -1;
}
if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
if (loadKernelModule(mModulePath, mModuleArgs)) {
LOGE("Kernel module load failed (%s)", strerror(errno));
goto out_powerdown;
}
}
if (loadFirmware()) {
LOGE("Firmware load failed (%s)", strerror(errno));
goto out_powerdown;
}
if (!mSupplicant->isStarted() && mSupplicant->start()) {
LOGE("Supplicant start failed (%s)", strerror(errno));
goto out_unloadmodule;
}
return 0;
out_unloadmodule:
if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
if (unloadKernelModule(mModuleName)) {
LOGE("Unable to unload module after failure!");
}
}
out_powerdown:
if (powerDown()) {
LOGE("Unable to powerdown after failure!");
}
return -1;
}
int WifiController::disable() {
LOGD("disable()");
if (mSupplicant->isStarted() && mSupplicant->stop()) {
LOGE("Supplicant stop failed (%s)", strerror(errno));
return -1;
}
if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
if (unloadKernelModule(mModuleName)) {
LOGE("Unable to unload module (%s)", strerror(errno));
return -1;
}
}
if (isPoweredUp() && powerDown()) {
LOGE("Powerdown failed (%s)", strerror(errno));
return -1;
}
return 0;
}
int WifiController::loadFirmware() {
return 0;
}
int WifiController::setScanMode(int mode) {
int rc = 0;
if (mCurrentScanMode == mode)
return 0;
if (!(mode & SCAN_ENABLE_MASK)) {
if (mCurrentScanMode & SCAN_REPEAT_MASK)
stopPeriodicScan();
} else if (mode & SCAN_REPEAT_MASK)
rc = startPeriodicScan();
else
rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
return rc;
}
int WifiController::startPeriodicScan() {
errno = -ENOSYS;
return -1;
}
int WifiController::stopPeriodicScan() {
errno = -ENOSYS;
return -1;
}

78
nexus/WifiController.h Normal file
View file

@ -0,0 +1,78 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WIFI_CONTROLLER_H
#define _WIFI_CONTROLLER_H
#include <sys/types.h>
#include "Controller.h"
class NetInterface;
class Supplicant;
class WifiController : public Controller {
public:
static const uint32_t SCAN_ENABLE_MASK = 0x01;
static const uint32_t SCAN_ACTIVE_MASK = 0x02;
static const uint32_t SCAN_REPEAT_MASK = 0x04;
static const uint32_t SCANMODE_NONE = 0;
static const uint32_t SCANMODE_PASSIVE_ONESHOT = SCAN_ENABLE_MASK;
static const uint32_t SCANMODE_PASSIVE_CONTINUOUS = SCAN_ENABLE_MASK | SCAN_REPEAT_MASK;
static const uint32_t SCANMODE_ACTIVE_ONESHOT = SCAN_ENABLE_MASK | SCAN_ACTIVE_MASK;
static const uint32_t SCANMODE_ACTIVE_CONTINUOUS = SCAN_ENABLE_MASK | SCAN_ACTIVE_MASK | SCAN_REPEAT_MASK;
private:
Supplicant *mSupplicant;
char mModulePath[255];
char mModuleName[64];
char mModuleArgs[255];
int mCurrentScanMode;
public:
WifiController(char *modpath, char *modname, char *modargs);
virtual ~WifiController() {}
int start();
int stop();
int enable();
int disable();
int getType();
char *getModulePath() { return mModulePath; }
char *getModuleName() { return mModuleName; }
char *getModuleArgs() { return mModuleArgs; }
Supplicant *getSupplicant() { return mSupplicant; }
int getScanMode() { return mCurrentScanMode; }
int setScanMode(int mode);
protected:
virtual int powerUp() = 0;
virtual int powerDown() = 0;
virtual int loadFirmware();
virtual bool isPoweredUp() = 0;
private:
int startPeriodicScan();
int stopPeriodicScan();
};
#endif

41
nexus/main.cpp Normal file
View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <errno.h>
#define LOG_TAG "Nexus"
#include "cutils/log.h"
#include "NetworkManager.h"
int main() {
NetworkManager *nm;
LOGI("Nexus version 0.1 firing up");
if (!(nm = new NetworkManager())) {
LOGE("Unable to create NetworkManager");
exit (-1);
};
if (nm->run()) {
LOGE("Unable to Run NetworkManager (%s)", strerror(errno));
exit (1);
}
LOGI("Nexus exiting");
exit(0);
}

104
nexus/nexctl.c Normal file
View file

@ -0,0 +1,104 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>
static void signal_handler(int sig) {
fprintf(stdout, "{ interrupt! }\n");
}
int main(int argc, char **argv) {
int sock;
if ((sock = socket_local_client("nexus",
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM)) < 0) {
fprintf(stderr, "Error connecting (%s)\n", strerror(errno));
exit(1);
}
printf("Connected to nexus\n");
while(1) {
fd_set read_fds;
struct timeval to;
int rc = 0;
signal(SIGINT, SIG_DFL);
printf("-> ");
fflush(stdout);
char buffer[255];
if (!fgets(buffer, sizeof(buffer) -1, stdin)) {
printf("Exiting...\n");
exit(0);
}
buffer[strlen(buffer) -1] = 0;
printf("sending '%s'\n", buffer);
if (write(sock, buffer, strlen(buffer) +1) < 0) {
fprintf(stderr, "Error writing data (%s)\n", strerror(errno));
exit(2);
}
wait:
to.tv_sec = 5;
to.tv_usec = 0;
FD_ZERO(&read_fds);
FD_SET(sock, &read_fds);
signal(SIGINT, signal_handler);
if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "Error in select (%s)\n", strerror(errno));
exit(2);
} else if (!rc) {
printf("{response timeout}\n");
continue;
} else if (FD_ISSET(sock, &read_fds)) {
printf("got data!\n");
if ((rc = read(sock, buffer, sizeof(buffer)-1)) < 0) {
fprintf(stderr, "Error reading response (%s)\n", strerror(errno));
exit(2);
}
printf(" |%s|\n", buffer);
goto wait;
}
}
exit(0);
}

View file

@ -217,6 +217,10 @@ service servicemanager /system/bin/servicemanager
service vold /system/bin/vold
socket vold stream 0660 root mount
service nexus /system/bin/nexus
socket nexus stream 0660 root system
disabled
#service mountd /system/bin/mountd
# socket mountd stream 0660 root mount