Merge change 1365
* changes:
Remove all gcc warnings.
diff --git a/adb/adb.h b/adb/adb.h
index a17c8dd..aebb81a 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -359,17 +359,10 @@
// Google's USB Vendor ID
#define VENDOR_ID_GOOGLE 0x18d1
+
// HTC's USB Vendor ID
#define VENDOR_ID_HTC 0x0bb4
-// products for VENDOR_ID_GOOGLE
-#define PRODUCT_ID_SOONER 0xd00d // Sooner bootloader
-#define PRODUCT_ID_SOONER_COMP 0xdeed // Sooner composite device
-
-// products for VENDOR_ID_HTC
-#define PRODUCT_ID_DREAM 0x0c01 // Dream bootloader
-#define PRODUCT_ID_DREAM_COMP 0x0c02 // Dream composite device
-
void local_init();
int local_connect(int port);
diff --git a/adb/usb_osx.c b/adb/usb_osx.c
index 49e1eef..2d4c1a9 100644
--- a/adb/usb_osx.c
+++ b/adb/usb_osx.c
@@ -31,21 +31,17 @@
#define DBG D
-typedef struct {
- int vid;
- int pid;
-} VendorProduct;
+#define ADB_SUBCLASS 0x42
+#define ADB_PROTOCOL 0x1
-#define kSupportedDeviceCount 4
-VendorProduct kSupportedDevices[kSupportedDeviceCount] = {
- { VENDOR_ID_GOOGLE, PRODUCT_ID_SOONER },
- { VENDOR_ID_GOOGLE, PRODUCT_ID_SOONER_COMP },
- { VENDOR_ID_HTC, PRODUCT_ID_DREAM },
- { VENDOR_ID_HTC, PRODUCT_ID_DREAM_COMP },
+int vendorIds[] = {
+ VENDOR_ID_GOOGLE,
+ VENDOR_ID_HTC,
};
+#define NUM_VENDORS (sizeof(vendorIds)/sizeof(vendorIds[0]))
static IONotificationPortRef notificationPort = 0;
-static io_iterator_t notificationIterators[kSupportedDeviceCount];
+static io_iterator_t notificationIterators[NUM_VENDORS];
struct usb_handle
{
@@ -61,17 +57,20 @@
static pthread_cond_t start_cond;
-static void AndroidDeviceAdded(void *refCon, io_iterator_t iterator);
-static void AndroidDeviceNotify(void *refCon, io_iterator_t iterator, natural_t messageType, void *messageArgument);
-static usb_handle* FindDeviceInterface(IOUSBDeviceInterface **dev, UInt16 vendor, UInt16 product);
+static void AndroidInterfaceAdded(void *refCon, io_iterator_t iterator);
+static void AndroidInterfaceNotify(void *refCon, io_iterator_t iterator,
+ natural_t messageType,
+ void *messageArgument);
+static usb_handle* CheckInterface(IOUSBInterfaceInterface **iface,
+ UInt16 vendor, UInt16 product);
static int
InitUSB()
{
CFMutableDictionaryRef matchingDict;
CFRunLoopSourceRef runLoopSource;
- SInt32 vendor, product;
- int i;
+ SInt32 vendor, if_subclass, if_protocol;
+ unsigned i;
//* To set up asynchronous notifications, create a notification port and
//* add its run loop event source to the program's run loop
@@ -81,51 +80,57 @@
memset(notificationIterators, 0, sizeof(notificationIterators));
- //* loop through all supported vendor/product pairs
- for (i = 0; i < kSupportedDeviceCount; i++) {
- //* Create our matching dictionary to find the Android device
- //* IOServiceAddMatchingNotification consumes the reference, so we do not need to release this
- matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
+ //* loop through all supported vendors
+ for (i = 0; i < NUM_VENDORS; i++) {
+ //* Create our matching dictionary to find the Android device's
+ //* adb interface
+ //* IOServiceAddMatchingNotification consumes the reference, so we do
+ //* not need to release this
+ matchingDict = IOServiceMatching(kIOUSBInterfaceClassName);
if (!matchingDict) {
DBG("ERR: Couldn't create USB matching dictionary.\n");
return -1;
}
- //* Set up two matching dictionaries, one for each product ID we support.
- //* This will cause the kernel to notify us only if the vendor and product IDs match.
- vendor = kSupportedDevices[i].vid;
- product = kSupportedDevices[i].pid;
- CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendor));
- CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &product));
-
- //* Now set up two notifications: one to be called when a raw device
- //* is first matched by the I/O Kit and another to be called when the
- //* device is terminated.
- //* we need to do this with each matching dictionary.
+ //* Match based on vendor id, interface subclass and protocol
+ vendor = vendorIds[i];
+ if_subclass = ADB_SUBCLASS;
+ if_protocol = ADB_PROTOCOL;
+ CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID),
+ CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberSInt32Type, &vendor));
+ CFDictionarySetValue(matchingDict, CFSTR(kUSBInterfaceSubClass),
+ CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberSInt32Type, &if_subclass));
+ CFDictionarySetValue(matchingDict, CFSTR(kUSBInterfaceProtocol),
+ CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberSInt32Type, &if_protocol));
IOServiceAddMatchingNotification(
notificationPort,
kIOFirstMatchNotification,
matchingDict,
- AndroidDeviceAdded,
+ AndroidInterfaceAdded,
NULL,
¬ificationIterators[i]);
- //* Iterate over set of matching devices to access already-present devices
- //* and to arm the notification
- AndroidDeviceAdded(NULL, notificationIterators[i]);
+ //* Iterate over set of matching interfaces to access already-present
+ //* devices and to arm the notification
+ AndroidInterfaceAdded(NULL, notificationIterators[i]);
}
return 0;
}
static void
-AndroidDeviceAdded(void *refCon, io_iterator_t iterator)
+AndroidInterfaceAdded(void *refCon, io_iterator_t iterator)
{
kern_return_t kr;
io_service_t usbDevice;
+ io_service_t usbInterface;
IOCFPlugInInterface **plugInInterface = NULL;
- IOUSBDeviceInterface182 **dev = NULL;
+ IOUSBInterfaceInterface220 **iface = NULL;
+ IOUSBDeviceInterface197 **dev = NULL;
HRESULT result;
SInt32 score;
UInt16 vendor;
@@ -133,28 +138,66 @@
UInt8 serialIndex;
char serial[256];
- while ((usbDevice = IOIteratorNext(iterator))) {
- //* Create an intermediate plugin
+ while ((usbInterface = IOIteratorNext(iterator))) {
+ //* Create an intermediate interface plugin
+ kr = IOCreatePlugInInterfaceForService(usbInterface,
+ kIOUSBInterfaceUserClientTypeID,
+ kIOCFPlugInInterfaceID,
+ &plugInInterface, &score);
+ IOObjectRelease(usbInterface);
+ if ((kIOReturnSuccess != kr) || (!plugInInterface)) {
+ DBG("ERR: Unable to create an interface plug-in (%08x)\n", kr);
+ continue;
+ }
+
+ //* This gets us the interface object
+ result = (*plugInInterface)->QueryInterface(plugInInterface,
+ CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID)
+ &iface);
+ //* We only needed the plugin to get the interface, so discard it
+ (*plugInInterface)->Release(plugInInterface);
+ if (result || !iface) {
+ DBG("ERR: Couldn't query the interface (%08x)\n", (int) result);
+ continue;
+ }
+
+ //* this gets us an ioservice, with which we will find the actual
+ //* device; after getting a plugin, and querying the interface, of
+ //* course.
+ //* Gotta love OS X
+ kr = (*iface)->GetDevice(iface, &usbDevice);
+ if (kIOReturnSuccess != kr || !usbDevice) {
+ DBG("ERR: Couldn't grab device from interface (%08x)\n", kr);
+ continue;
+ }
+
+ plugInInterface = NULL;
+ score = 0;
+ //* create an intermediate device plugin
kr = IOCreatePlugInInterfaceForService(usbDevice,
kIOUSBDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&plugInInterface, &score);
-
+ //* only needed this to find the plugin
+ (void)IOObjectRelease(usbDevice);
if ((kIOReturnSuccess != kr) || (!plugInInterface)) {
- DBG("ERR: Unable to create a plug-in (%08x)\n", kr);
- goto continue1;
+ DBG("ERR: Unable to create a device plug-in (%08x)\n", kr);
+ continue;
}
- //* Now create the device interface
result = (*plugInInterface)->QueryInterface(plugInInterface,
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID) &dev);
-
+ //* only needed this to query the plugin
+ (*plugInInterface)->Release(plugInInterface);
if (result || !dev) {
- DBG("ERR: Couldn't create a device interface (%08x)\n", (int) result);
- goto continue2;
+ DBG("ERR: Couldn't create a device interface (%08x)\n",
+ (int) result);
+ continue;
}
- //* Check the device to see if it's ours
+ //* Now after all that, we actually have a ref to the device and
+ //* the interface that matched our criteria
+
kr = (*dev)->GetDeviceVendor(dev, &vendor);
kr = (*dev)->GetDeviceProduct(dev, &product);
kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
@@ -163,7 +206,8 @@
IOUSBDevRequest req;
UInt16 buffer[256];
- req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
+ req.bmRequestType =
+ USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
req.bRequest = kUSBRqGetDescriptor;
req.wValue = (kUSBStringDesc << 8) | serialIndex;
req.wIndex = 0;
@@ -174,219 +218,149 @@
if (kr == kIOReturnSuccess && req.wLenDone > 0) {
int i, count;
- // skip first word, and copy the rest to the serial string, changing shorts to bytes.
+ // skip first word, and copy the rest to the serial string,
+ // changing shorts to bytes.
count = (req.wLenDone - 1) / 2;
for (i = 0; i < count; i++)
serial[i] = buffer[i + 1];
serial[i] = 0;
}
}
+ (*dev)->Release(dev);
- usb_handle* handle = NULL;
+ DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product,
+ serial);
- //* Open the device
- kr = (*dev)->USBDeviceOpen(dev);
-
- if (kr != kIOReturnSuccess) {
- DBG("ERR: Could not open device: %08x\n", kr);
- goto continue3;
- } else {
- //* Find an interface for the device
- handle = FindDeviceInterface((IOUSBDeviceInterface**)dev, vendor, product);
- }
-
+ usb_handle* handle = CheckInterface((IOUSBInterfaceInterface**)iface,
+ vendor, product);
if (handle == NULL) {
DBG("ERR: Could not find device interface: %08x\n", kr);
- (*dev)->USBDeviceClose(dev);
- goto continue3;
+ (*iface)->Release(iface);
+ continue;
}
DBG("AndroidDeviceAdded calling register_usb_transport\n");
register_usb_transport(handle, (serial[0] ? serial : NULL));
- // Register for an interest notification of this device being removed. Pass the reference to our
- // private data as the refCon for the notification.
+ // Register for an interest notification of this device being removed.
+ // Pass the reference to our private data as the refCon for the
+ // notification.
kr = IOServiceAddInterestNotification(notificationPort,
- usbDevice,
+ usbInterface,
kIOGeneralInterest,
- AndroidDeviceNotify,
+ AndroidInterfaceNotify,
handle,
&handle->usbNotification);
+
if (kIOReturnSuccess != kr) {
DBG("ERR: Unable to create interest notification (%08x)\n", kr);
}
-
-continue3:
- (void)(*dev)->Release(dev);
-continue2:
- IODestroyPlugInInterface(plugInInterface);
-continue1:
- IOObjectRelease(usbDevice);
}
}
static void
-AndroidDeviceNotify(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
+AndroidInterfaceNotify(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
{
usb_handle *handle = (usb_handle *)refCon;
if (messageType == kIOMessageServiceIsTerminated) {
- DBG("AndroidDeviceNotify\n");
+ if (!handle) {
+ DBG("ERR: NULL handle\n");
+ return;
+ }
+ DBG("AndroidInterfaceNotify\n");
IOObjectRelease(handle->usbNotification);
usb_kick(handle);
}
}
+//* TODO: simplify this further since we only register to get ADB interface
+//* subclass+protocol events
static usb_handle*
-FindDeviceInterface(IOUSBDeviceInterface **dev, UInt16 vendor, UInt16 product)
+CheckInterface(IOUSBInterfaceInterface **interface, UInt16 vendor, UInt16 product)
{
usb_handle* handle = NULL;
IOReturn kr;
- IOUSBFindInterfaceRequest request;
- io_iterator_t iterator;
- io_service_t usbInterface;
- IOCFPlugInInterface **plugInInterface;
- IOUSBInterfaceInterface **interface = NULL;
- HRESULT result;
- SInt32 score;
UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol;
- UInt8 endpoint, configuration;
+ UInt8 endpoint;
- //* Placing the constant KIOUSBFindInterfaceDontCare into the following
- //* fields of the IOUSBFindInterfaceRequest structure will allow us to
- //* find all of the interfaces
- request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
- request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
- request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
- request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
- //* SetConfiguration will kill an existing UMS connection, so let's not do this if not necessary.
- configuration = 0;
- (*dev)->GetConfiguration(dev, &configuration);
- if (configuration != 1)
- (*dev)->SetConfiguration(dev, 1);
-
- //* Get an iterator for the interfaces on the device
- kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator);
-
+ //* Now open the interface. This will cause the pipes associated with
+ //* the endpoints in the interface descriptor to be instantiated
+ kr = (*interface)->USBInterfaceOpen(interface);
if (kr != kIOReturnSuccess) {
- DBG("ERR: Couldn't create a device interface iterator: (%08x)\n", kr);
+ DBG("ERR: Could not open interface: (%08x)\n", kr);
return NULL;
}
- while ((usbInterface = IOIteratorNext(iterator))) {
- //* Create an intermediate plugin
- kr = IOCreatePlugInInterfaceForService(
- usbInterface,
- kIOUSBInterfaceUserClientTypeID,
- kIOCFPlugInInterfaceID,
- &plugInInterface,
- &score);
-
- //* No longer need the usbInterface object now that we have the plugin
- (void) IOObjectRelease(usbInterface);
-
- if ((kr != kIOReturnSuccess) || (!plugInInterface)) {
- DBG("ERR: Unable to create plugin (%08x)\n", kr);
- break;
- }
-
- //* Now create the interface interface for the interface
- result = (*plugInInterface)->QueryInterface(
- plugInInterface,
- CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
- (LPVOID) &interface);
-
- //* No longer need the intermediate plugin
- (*plugInInterface)->Release(plugInInterface);
-
- if (result || !interface) {
- DBG("ERR: Couldn't create interface interface: (%08x)\n",
- (unsigned int) result);
- break;
- }
-
- //* Now open the interface. This will cause the pipes associated with
- //* the endpoints in the interface descriptor to be instantiated
- kr = (*interface)->USBInterfaceOpen(interface);
-
- if (kr != kIOReturnSuccess)
- {
- DBG("ERR: Could not open interface: (%08x)\n", kr);
- (void) (*interface)->Release(interface);
- //* continue so we can try the next interface
- continue;
- }
-
- //* Get the number of endpoints associated with this interface
- kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints);
-
- if (kr != kIOReturnSuccess) {
- DBG("ERR: Unable to get number of endpoints: (%08x)\n", kr);
- goto next_interface;
- }
-
- //* Get interface class, subclass and protocol
- if ((*interface)->GetInterfaceClass(interface, &interfaceClass) != kIOReturnSuccess ||
- (*interface)->GetInterfaceSubClass(interface, &interfaceSubClass) != kIOReturnSuccess ||
- (*interface)->GetInterfaceProtocol(interface, &interfaceProtocol) != kIOReturnSuccess)
- {
- DBG("ERR: Unable to get interface class, subclass and protocol\n");
- goto next_interface;
- }
-
- //* check to make sure interface class, subclass and protocol match ADB
- //* avoid opening mass storage endpoints
- if (is_adb_interface(vendor, product, interfaceClass, interfaceSubClass, interfaceProtocol)) {
- handle = calloc(1, sizeof(usb_handle));
-
- //* Iterate over the endpoints for this interface and find the first
- //* bulk in/out pipes available. These will be our read/write pipes.
- for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) {
- UInt8 transferType;
- UInt16 maxPacketSize;
- UInt8 interval;
- UInt8 number;
- UInt8 direction;
-
- kr = (*interface)->GetPipeProperties(interface, endpoint, &direction,
- &number, &transferType, &maxPacketSize, &interval);
-
- if (kIOReturnSuccess == kr) {
- if (kUSBBulk != transferType)
- continue;
-
- if (kUSBIn == direction)
- handle->bulkIn = endpoint;
-
- if (kUSBOut == direction)
- handle->bulkOut = endpoint;
-
- if (interfaceProtocol == 0x01) {
- handle->zero_mask = maxPacketSize - 1;
- }
-
- } else {
- DBG("ERR: FindDeviceInterface - could not get pipe properties\n");
- }
- }
-
- handle->interface = interface;
- break;
- }
-
-next_interface:
- (*interface)->USBInterfaceClose(interface);
- (*interface)->Release(interface);
+ //* Get the number of endpoints associated with this interface
+ kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints);
+ if (kr != kIOReturnSuccess) {
+ DBG("ERR: Unable to get number of endpoints: (%08x)\n", kr);
+ goto err_get_num_ep;
}
+ //* Get interface class, subclass and protocol
+ if ((*interface)->GetInterfaceClass(interface, &interfaceClass) != kIOReturnSuccess ||
+ (*interface)->GetInterfaceSubClass(interface, &interfaceSubClass) != kIOReturnSuccess ||
+ (*interface)->GetInterfaceProtocol(interface, &interfaceProtocol) != kIOReturnSuccess) {
+ DBG("ERR: Unable to get interface class, subclass and protocol\n");
+ goto err_get_interface_class;
+ }
+
+ //* check to make sure interface class, subclass and protocol match ADB
+ //* avoid opening mass storage endpoints
+ if (!is_adb_interface(vendor, product, interfaceClass,
+ interfaceSubClass, interfaceProtocol))
+ goto err_bad_adb_interface;
+
+ handle = calloc(1, sizeof(usb_handle));
+
+ //* Iterate over the endpoints for this interface and find the first
+ //* bulk in/out pipes available. These will be our read/write pipes.
+ for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) {
+ UInt8 transferType;
+ UInt16 maxPacketSize;
+ UInt8 interval;
+ UInt8 number;
+ UInt8 direction;
+
+ kr = (*interface)->GetPipeProperties(interface, endpoint, &direction,
+ &number, &transferType, &maxPacketSize, &interval);
+
+ if (kIOReturnSuccess == kr) {
+ if (kUSBBulk != transferType)
+ continue;
+
+ if (kUSBIn == direction)
+ handle->bulkIn = endpoint;
+
+ if (kUSBOut == direction)
+ handle->bulkOut = endpoint;
+
+ handle->zero_mask = maxPacketSize - 1;
+ } else {
+ DBG("ERR: FindDeviceInterface - could not get pipe properties\n");
+ goto err_get_pipe_props;
+ }
+ }
+
+ handle->interface = interface;
return handle;
+
+err_get_pipe_props:
+ free(handle);
+err_bad_adb_interface:
+err_get_interface_class:
+err_get_num_ep:
+ (*interface)->USBInterfaceClose(interface);
+ return NULL;
}
void* RunLoopThread(void* unused)
{
- int i;
+ unsigned i;
InitUSB();
@@ -400,7 +374,7 @@
CFRunLoopRun();
currentRunLoop = 0;
- for (i = 0; i < kSupportedDeviceCount; i++) {
+ for (i = 0; i < NUM_VENDORS; i++) {
IOObjectRelease(notificationIterators[i]);
}
IONotificationPortDestroy(notificationPort);
@@ -527,6 +501,9 @@
void usb_kick(usb_handle *handle)
{
/* release the interface */
+ if (!handle)
+ return;
+
if (handle->interface)
{
(*handle->interface)->USBInterfaceClose(handle->interface);
diff --git a/include/sysutils/FrameworkClient.h b/include/sysutils/FrameworkClient.h
new file mode 100644
index 0000000..1eb112a
--- /dev/null
+++ b/include/sysutils/FrameworkClient.h
@@ -0,0 +1,21 @@
+#ifndef _FRAMEWORK_CLIENT_H
+#define _FRAMEWORK_CLIENT_H
+
+#include "../../../frameworks/base/include/utils/List.h"
+
+#include <pthread.h>
+
+class FrameworkClient {
+ int mSocket;
+ pthread_mutex_t mWriteMutex;
+
+public:
+ FrameworkClient(int sock);
+ virtual ~FrameworkClient() {}
+
+ int sendMsg(char *msg);
+ int sendMsg(char *msg, char *data);
+};
+
+typedef android::List<FrameworkClient *> FrameworkClientCollection;
+#endif
diff --git a/include/sysutils/FrameworkCommand.h b/include/sysutils/FrameworkCommand.h
index 952e99a..5b50247 100644
--- a/include/sysutils/FrameworkCommand.h
+++ b/include/sysutils/FrameworkCommand.h
@@ -18,6 +18,7 @@
#include "../../../frameworks/base/include/utils/List.h"
+class SocketClient;
class FrameworkCommand {
private:
@@ -28,7 +29,7 @@
FrameworkCommand(const char *cmd);
virtual ~FrameworkCommand() { }
- virtual int runCommand(char *data);
+ virtual int runCommand(SocketClient *c, char *data) = 0;
const char *getCommand() { return mCommand; }
};
diff --git a/include/sysutils/FrameworkListener.h b/include/sysutils/FrameworkListener.h
index 1454a6f..8a83c33 100644
--- a/include/sysutils/FrameworkListener.h
+++ b/include/sysutils/FrameworkListener.h
@@ -19,6 +19,8 @@
#include "SocketListener.h"
#include "FrameworkCommand.h"
+class SocketClient;
+
class FrameworkListener : public SocketListener {
private:
FrameworkCommandCollection *mCommands;
@@ -29,9 +31,9 @@
protected:
void registerCmd(FrameworkCommand *cmd);
- virtual bool onDataAvailable(int socket);
+ virtual bool onDataAvailable(SocketClient *c);
private:
- void dispatchCommand(char *cmd);
+ void dispatchCommand(SocketClient *c, char *cmd);
};
#endif
diff --git a/include/sysutils/FrameworkManager.h b/include/sysutils/FrameworkManager.h
deleted file mode 100644
index 8a24d33..0000000
--- a/include/sysutils/FrameworkManager.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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
diff --git a/include/sysutils/NetlinkListener.h b/include/sysutils/NetlinkListener.h
index 8ac811c..6dcc005 100644
--- a/include/sysutils/NetlinkListener.h
+++ b/include/sysutils/NetlinkListener.h
@@ -27,6 +27,6 @@
NetlinkListener(int socket);
virtual ~NetlinkListener() {}
protected:
- virtual bool onDataAvailable(int socket);
+ virtual bool onDataAvailable(SocketClient *cli);
};
#endif
diff --git a/include/sysutils/SocketClient.h b/include/sysutils/SocketClient.h
new file mode 100644
index 0000000..39ec7ae
--- /dev/null
+++ b/include/sysutils/SocketClient.h
@@ -0,0 +1,23 @@
+#ifndef _SOCKET_CLIENT_H
+#define _SOCKET_CLIENT_H
+
+#include "../../../frameworks/base/include/utils/List.h"
+
+#include <pthread.h>
+
+class SocketClient {
+ int mSocket;
+ pthread_mutex_t mWriteMutex;
+
+public:
+ SocketClient(int sock);
+ virtual ~SocketClient() {}
+
+ int getSocket() { return mSocket; }
+
+ int sendMsg(char *msg);
+ int sendMsg(char *msg, char *data);
+};
+
+typedef android::List<SocketClient *> SocketClientCollection;
+#endif
diff --git a/include/sysutils/SocketListener.h b/include/sysutils/SocketListener.h
index f079dba..be97421 100644
--- a/include/sysutils/SocketListener.h
+++ b/include/sysutils/SocketListener.h
@@ -16,20 +16,35 @@
#ifndef _SOCKETLISTENER_H
#define _SOCKETLISTENER_H
+#include <pthread.h>
+
+#include <sysutils/SocketClient.h>
+
class SocketListener {
- int mSock;
- int mCsock;
- int mAcceptClients;
- const char *mSocketName;
+ int mSock;
+ const char *mSocketName;
+ SocketClientCollection *mClients;
+ pthread_mutex_t mClientsLock;
+ bool mListen;
+ int mCtrlPipe[2];
+ pthread_t mThread;
public:
- SocketListener(const char *socketName, bool acceptClients);
- SocketListener(int socketFd, bool acceptClients);
+ SocketListener(const char *socketNames, bool listen);
+ SocketListener(int socketFd, bool listen);
virtual ~SocketListener() {}
- virtual int run();
+ int startListener();
+ int stopListener();
+
+ void sendBroadcast(char *msg);
+ void sendBroadcast(char *msg, char *data);
protected:
- virtual bool onDataAvailable(int socket);
+ virtual bool onDataAvailable(SocketClient *c) = 0;
+
+private:
+ static void *threadStart(void *obj);
+ void runListener();
};
#endif
diff --git a/libsysutils/Android.mk b/libsysutils/Android.mk
index 0b15c12..cbb1edf 100644
--- a/libsysutils/Android.mk
+++ b/libsysutils/Android.mk
@@ -3,12 +3,12 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- src/FrameworkManager.cpp \
src/SocketListener.cpp \
src/FrameworkListener.cpp \
src/NetlinkListener.cpp \
src/NetlinkEvent.cpp \
src/FrameworkCommand.cpp \
+ src/SocketClient.cpp \
LOCAL_MODULE:= libsysutils
diff --git a/libsysutils/src/FrameworkClient.cpp b/libsysutils/src/FrameworkClient.cpp
new file mode 100644
index 0000000..237bb60
--- /dev/null
+++ b/libsysutils/src/FrameworkClient.cpp
@@ -0,0 +1,41 @@
+#include <alloca.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <pthread.h>
+
+#define LOG_TAG "FrameworkClient"
+#include <cutils/log.h>
+
+#include <sysutils/FrameworkClient.h>
+
+FrameworkClient::FrameworkClient(int socket) {
+ mSocket = socket;
+ pthread_mutex_init(&mWriteMutex, NULL);
+}
+
+int FrameworkClient::sendMsg(char *msg) {
+ LOGD("FrameworkClient::sendMsg(%s)", msg);
+ if (mSocket < 0) {
+ errno = EHOSTUNREACH;
+ return -1;
+ }
+
+ pthread_mutex_lock(&mWriteMutex);
+ if (write(mSocket, msg, strlen(msg) +1) < 0) {
+ LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno));
+ }
+ pthread_mutex_unlock(&mWriteMutex);
+ return 0;
+}
+
+int FrameworkClient::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);
+}
+
diff --git a/libsysutils/src/FrameworkCommand.cpp b/libsysutils/src/FrameworkCommand.cpp
index 0444de5..94e7426 100644
--- a/libsysutils/src/FrameworkCommand.cpp
+++ b/libsysutils/src/FrameworkCommand.cpp
@@ -25,7 +25,7 @@
mCommand = cmd;
}
-int FrameworkCommand::runCommand(char *data) {
+int FrameworkCommand::runCommand(SocketClient *c, char *data) {
LOGW("Command %s has no run handler!", getCommand());
errno = ENOSYS;
return -1;
diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp
index b920215..9210ca5 100644
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -22,17 +22,18 @@
#include <sysutils/FrameworkListener.h>
#include <sysutils/FrameworkCommand.h>
+#include <sysutils/SocketClient.h>
FrameworkListener::FrameworkListener(const char *socketName) :
SocketListener(socketName, true) {
mCommands = new FrameworkCommandCollection();
}
-bool FrameworkListener::onDataAvailable(int socket) {
+bool FrameworkListener::onDataAvailable(SocketClient *c) {
char buffer[101];
int len;
- if ((len = read(socket, buffer, sizeof(buffer) -1)) < 0) {
+ if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) {
LOGE("read() failed (%s)", strerror(errno));
return errno;
} else if (!len) {
@@ -47,7 +48,7 @@
for (i = 0; i < len; i++) {
if (buffer[i] == '\0') {
- dispatchCommand(buffer + start);
+ dispatchCommand(c, buffer + start);
start = i + 1;
}
}
@@ -58,14 +59,22 @@
mCommands->push_back(cmd);
}
-void FrameworkListener::dispatchCommand(char *cmd) {
+void FrameworkListener::dispatchCommand(SocketClient *cli, char *cmd) {
+
+ char *cm, *last;
+
+ if (!(cm = strtok_r(cmd, ":", &last))) {
+ cli->sendMsg("BAD_MSG");
+ return;
+ }
+
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)) {
+ if (!strcmp(cm, c->getCommand())) {
+ if (c->runCommand(cli, cmd)) {
LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno));
}
return;
@@ -73,5 +82,6 @@
}
LOGE("No cmd handlers defined for '%s'", cmd);
+ cli->sendMsg("UNKNOWN_CMD");
+ return;
}
-
diff --git a/libsysutils/src/FrameworkManager.cpp b/libsysutils/src/FrameworkManager.cpp
deleted file mode 100644
index 5dceb9f..0000000
--- a/libsysutils/src/FrameworkManager.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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);
-}
diff --git a/libsysutils/src/NetlinkListener.cpp b/libsysutils/src/NetlinkListener.cpp
index 96a616d..3ec9d9d 100644
--- a/libsysutils/src/NetlinkListener.cpp
+++ b/libsysutils/src/NetlinkListener.cpp
@@ -29,8 +29,9 @@
SocketListener(socket, false) {
}
-bool NetlinkListener::onDataAvailable(int socket)
+bool NetlinkListener::onDataAvailable(SocketClient *cli)
{
+ int socket = cli->getSocket();
LOGD("NetlinkListener::onDataAvailable()");
int count;
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
new file mode 100644
index 0000000..6db62b3
--- /dev/null
+++ b/libsysutils/src/SocketClient.cpp
@@ -0,0 +1,41 @@
+#include <alloca.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <pthread.h>
+
+#define LOG_TAG "SocketClient"
+#include <cutils/log.h>
+
+#include <sysutils/SocketClient.h>
+
+SocketClient::SocketClient(int socket) {
+ mSocket = socket;
+ pthread_mutex_init(&mWriteMutex, NULL);
+}
+
+int SocketClient::sendMsg(char *msg) {
+ LOGD("SocketClient::sendMsg(%s)", msg);
+ if (mSocket < 0) {
+ errno = EHOSTUNREACH;
+ return -1;
+ }
+
+ pthread_mutex_lock(&mWriteMutex);
+ if (write(mSocket, msg, strlen(msg) +1) < 0) {
+ LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno));
+ }
+ pthread_mutex_unlock(&mWriteMutex);
+ return 0;
+}
+
+int SocketClient::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);
+}
+
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index f92e30d..cb69bfd 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -24,26 +24,28 @@
#define LOG_TAG "SocketListener"
#include <cutils/log.h>
-
#include <cutils/sockets.h>
#include <sysutils/SocketListener.h>
+#include <sysutils/SocketClient.h>
-SocketListener::SocketListener(const char *socketName, bool acceptClients) {
- mAcceptClients = acceptClients;
- mCsock = -1;
+SocketListener::SocketListener(const char *socketName, bool listen) {
+ mListen = listen;
mSocketName = socketName;
mSock = -1;
+ pthread_mutex_init(&mClientsLock, NULL);
+ mClients = new SocketClientCollection();
}
-SocketListener::SocketListener(int socketFd, bool acceptClients) {
- mAcceptClients = acceptClients;
- mCsock = -1;
+SocketListener::SocketListener(int socketFd, bool listen) {
+ mListen = listen;
mSocketName = NULL;
mSock = socketFd;
+ pthread_mutex_init(&mClientsLock, NULL);
+ mClients = new SocketClientCollection();
}
-int SocketListener::run() {
+int SocketListener::startListener() {
if (!mSocketName && mSock == -1) {
errno = EINVAL;
@@ -56,72 +58,155 @@
}
}
- if (mAcceptClients) {
- if (listen(mSock, 4) < 0) {
- LOGE("Unable to listen on socket (%s)", strerror(errno));
- return -1;
- }
+ if (mListen && listen(mSock, 4) < 0) {
+ LOGE("Unable to listen on socket (%s)", strerror(errno));
+ return -1;
+ } else if (!mListen) {
+ mClients->push_back(new SocketClient(mSock));
+ LOGD("Created phantom client");
}
+ if (pipe(mCtrlPipe))
+ return -1;
+
+ if (pthread_create(&mThread, NULL, SocketListener::threadStart, this))
+ return -1;
+
+ return 0;
+}
+
+int SocketListener::stopListener() {
+ char c = 0;
+
+ if (write(mCtrlPipe[1], &c, 1) != 1) {
+ LOGE("Error writing to control pipe (%s)", strerror(errno));
+ return -1;
+ }
+
+ LOGD("Signaled listener thread - waiting for it to die");
+ void *ret;
+ if (pthread_join(mThread, &ret)) {
+ LOGE("Error joining to listener thread (%s)", strerror(errno));
+ return -1;
+ }
+ LOGD("Listener stopped");
+ return 0;
+}
+
+void *SocketListener::threadStart(void *obj) {
+ SocketListener *me = reinterpret_cast<SocketListener *>(obj);
+
+ me->runListener();
+ LOGD("Listener thread shutting down");
+ pthread_exit(NULL);
+ return NULL;
+}
+
+void SocketListener::runListener() {
+
while(1) {
+ SocketClientCollection::iterator it;
fd_set read_fds;
struct timeval to;
- int max = 0;
int rc = 0;
to.tv_sec = 60 * 60;
to.tv_usec = 0;
+ int max = 0;
+
FD_ZERO(&read_fds);
- if ((mAcceptClients == false) ||
- (mAcceptClients == true && mCsock == -1)) {
- FD_SET(mSock, &read_fds);
+ if (mListen) {
max = mSock;
- } else if (mCsock != -1) {
- FD_SET(mCsock, &read_fds);
- max = mCsock;
+ FD_SET(mSock, &read_fds);
}
+ FD_SET(mCtrlPipe[0], &read_fds);
+ if (mCtrlPipe[0] > max)
+ max = mCtrlPipe[0];
+
+ pthread_mutex_lock(&mClientsLock);
+ for (it = mClients->begin(); it != mClients->end(); ++it) {
+ FD_SET((*it)->getSocket(), &read_fds);
+ if ((*it)->getSocket() > max)
+ max = (*it)->getSocket();
+ }
+ pthread_mutex_unlock(&mClientsLock);
+
if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) {
LOGE("select failed (%s)", strerror(errno));
- return -errno;
- } else if (!rc)
+ sleep(1);
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);
+ } else if (!rc) {
+ LOGD("select timeout");
+ continue;
+ }
- if ((mCsock = accept(mSock, &addr, &alen)) < 0) {
- LOGE("accept failed (%s)", strerror(errno));
- return -errno;
+ if (FD_ISSET(mCtrlPipe[0], &read_fds)) {
+ LOGD("Control message received");
+ break;
+ }
+ if (mListen && FD_ISSET(mSock, &read_fds)) {
+ struct sockaddr addr;
+ socklen_t alen = sizeof(addr);
+ int c;
+
+ if ((c = accept(mSock, &addr, &alen)) < 0) {
+ LOGE("accept failed (%s)", strerror(errno));
+ sleep(1);
+ continue;
+ }
+ LOGD("SocketListener client connection accepted");
+ pthread_mutex_lock(&mClientsLock);
+ mClients->push_back(new SocketClient(c));
+ pthread_mutex_unlock(&mClientsLock);
+ }
+
+ do {
+ pthread_mutex_lock(&mClientsLock);
+ for (it = mClients->begin(); it != mClients->end(); ++it) {
+ int fd = (*it)->getSocket();
+ if (FD_ISSET(fd, &read_fds)) {
+ pthread_mutex_unlock(&mClientsLock);
+ if (!onDataAvailable(*it)) {
+ LOGD("SocketListener closing client socket");
+ close(fd);
+ pthread_mutex_lock(&mClientsLock);
+ delete *it;
+ it = mClients->erase(it);
+ pthread_mutex_unlock(&mClientsLock);
+ }
+ FD_CLR(fd, &read_fds);
+ continue;
}
- 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;
- }
+ pthread_mutex_unlock(&mClientsLock);
+ } while (0);
}
- return 0;
}
-bool SocketListener::onDataAvailable(int socket) {
- return false;
+void SocketListener::sendBroadcast(char *msg) {
+ pthread_mutex_lock(&mClientsLock);
+ SocketClientCollection::iterator i;
+
+ for (i = mClients->begin(); i != mClients->end(); ++i) {
+ if ((*i)->sendMsg(msg)) {
+ LOGW("Error sending broadcast (%s)", strerror(errno));
+ }
+ }
+ pthread_mutex_unlock(&mClientsLock);
}
+
+void SocketListener::sendBroadcast(char *msg, char *data) {
+ pthread_mutex_lock(&mClientsLock);
+ SocketClientCollection::iterator i;
+
+ for (i = mClients->begin(); i != mClients->end(); ++i) {
+ if ((*i)->sendMsg(msg, data)) {
+ LOGW("Error sending broadcast (%s)", strerror(errno));
+ }
+ }
+ pthread_mutex_unlock(&mClientsLock);
+}
+
diff --git a/nexus/Android.mk b/nexus/Android.mk
index e76cb27..7cf4a1f 100644
--- a/nexus/Android.mk
+++ b/nexus/Android.mk
@@ -19,6 +19,7 @@
SupplicantListener.cpp \
VpnController.cpp \
ScanResult.cpp \
+ WifiScanner.cpp \
LOCAL_MODULE:= nexus
diff --git a/nexus/CommandListener.cpp b/nexus/CommandListener.cpp
index cdb1db5..02ede15 100644
--- a/nexus/CommandListener.cpp
+++ b/nexus/CommandListener.cpp
@@ -19,60 +19,64 @@
#define LOG_TAG "CommandListener"
#include <cutils/log.h>
+#include <sysutils/SocketClient.h>
+
#include "CommandListener.h"
#include "Controller.h"
#include "NetworkManager.h"
#include "WifiController.h"
-CommandListener::CommandListener(NetworkManager *netman) :
+CommandListener::CommandListener() :
FrameworkListener("nexus") {
- mNetman = netman;
+ registerCmd(new WifiEnableCmd());
+ registerCmd(new WifiDisableCmd());
+ registerCmd(new WifiScanCmd());
+ registerCmd(new WifiScanResultsCmd());
- registerCmd(new WifiEnableCmd(netman));
- registerCmd(new WifiDisableCmd(netman));
- registerCmd(new WifiScanCmd(netman));
-
- registerCmd(new VpnEnableCmd(netman));
- registerCmd(new VpnDisableCmd(netman));
+ registerCmd(new VpnEnableCmd());
+ registerCmd(new VpnDisableCmd());
}
/* -------------
* Wifi Commands
* ------------ */
-CommandListener::WifiEnableCmd::WifiEnableCmd(NetworkManager *netman) :
- NexusCommand("wifi_enable", netman) {
+CommandListener::WifiEnableCmd::WifiEnableCmd() :
+ NexusCommand("wifi_enable") {
}
-int CommandListener::WifiEnableCmd::runCommand(char *data) {
- Controller *c = mNetman->findController("WIFI");
+int CommandListener::WifiEnableCmd::runCommand(SocketClient *cli, char *data) {
+ Controller *c = NetworkManager::Instance()->findController("WIFI");
char buffer[32];
sprintf(buffer, "WIFI_ENABLE:%d", (c->enable() ? errno : 0));
- mNetman->getFrameworkManager()->sendMsg(buffer);
+
+ cli->sendMsg(buffer);
return 0;
}
-CommandListener::WifiDisableCmd::WifiDisableCmd(NetworkManager *netman) :
- NexusCommand("wifi_disable", netman) {
+CommandListener::WifiDisableCmd::WifiDisableCmd() :
+ NexusCommand("wifi_disable") {
}
-int CommandListener::WifiDisableCmd::runCommand(char *data) {
- Controller *c = mNetman->findController("WIFI");
+int CommandListener::WifiDisableCmd::runCommand(SocketClient *cli, char *data) {
+ Controller *c = NetworkManager::Instance()->findController("WIFI");
char buffer[32];
sprintf(buffer, "WIFI_DISABLE:%d", (c->disable() ? errno : 0));
- mNetman->getFrameworkManager()->sendMsg(buffer);
+ cli->sendMsg(buffer);
return 0;
}
-CommandListener::WifiScanCmd::WifiScanCmd(NetworkManager *netman) :
- NexusCommand("wifi_scan", netman) {
+CommandListener::WifiScanCmd::WifiScanCmd() :
+ NexusCommand("wifi_scan") {
}
-int CommandListener::WifiScanCmd::runCommand(char *data) {
+int CommandListener::WifiScanCmd::runCommand(SocketClient *cli, char *data) {
LOGD("WifiScanCmd(%s)", data);
- WifiController *wc = (WifiController *) mNetman->findController("WIFI");
+
+ WifiController *wc = (WifiController *) NetworkManager::Instance()->findController("WIFI");
+
char buffer[32];
int mode = 0;
char *bword, *last;
@@ -90,35 +94,62 @@
mode = atoi(bword);
sprintf(buffer, "WIFI_SCAN:%d", (wc->setScanMode(mode) ? errno : 0));
- mNetman->getFrameworkManager()->sendMsg(buffer);
+ cli->sendMsg(buffer);
+ return 0;
+}
+
+CommandListener::WifiScanResultsCmd::WifiScanResultsCmd() :
+ NexusCommand("wifi_scan_results") {
+}
+
+int CommandListener::WifiScanResultsCmd::runCommand(SocketClient *cli, char *data) {
+ NetworkManager *nm = NetworkManager::Instance();
+
+ WifiController *wc = (WifiController *) nm->findController("WIFI");
+
+ ScanResultCollection *src = wc->createScanResults();
+ ScanResultCollection::iterator it;
+ char buffer[256];
+
+ for(it = src->begin(); it != src->end(); ++it) {
+ sprintf(buffer, "WIFI_SCAN_RESULT:%s:%u:%d:%s:%s",
+ (*it)->getBssid(), (*it)->getFreq(), (*it)->getLevel(),
+ (*it)->getFlags(), (*it)->getSsid());
+ cli->sendMsg(buffer);
+ delete (*it);
+ it = src->erase(it);
+ }
+
+ delete src;
+ cli->sendMsg("WIFI_SCAN_RESULT:0");
return 0;
}
/* ------------
* Vpn Commands
* ------------ */
-CommandListener::VpnEnableCmd::VpnEnableCmd(NetworkManager *netman) :
- NexusCommand("vpn_enable", netman) {
+CommandListener::VpnEnableCmd::VpnEnableCmd() :
+ NexusCommand("vpn_enable") {
}
-int CommandListener::VpnEnableCmd::runCommand(char *data) {
- Controller *c = mNetman->findController("VPN");
+int CommandListener::VpnEnableCmd::runCommand(SocketClient *cli, char *data) {
+ Controller *c = NetworkManager::Instance()->findController("VPN");
char buffer[32];
sprintf(buffer, "VPN_ENABLE:%d", (c->enable() ? errno : 0));
- mNetman->getFrameworkManager()->sendMsg(buffer);
+ cli->sendMsg(buffer);
return 0;
}
-CommandListener::VpnDisableCmd::VpnDisableCmd(NetworkManager *netman) :
- NexusCommand("vpn_disable", netman) {
+CommandListener::VpnDisableCmd::VpnDisableCmd() :
+ NexusCommand("vpn_disable") {
}
-int CommandListener::VpnDisableCmd::runCommand(char *data) {
- Controller *c = mNetman->findController("VPN");
+int CommandListener::VpnDisableCmd::runCommand(SocketClient *cli, char *data) {
+ Controller *c = NetworkManager::Instance()->findController("VPN");
char buffer[32];
sprintf(buffer, "VPN_DISABLE:%d", (c->disable() ? errno : 0));
- mNetman->getFrameworkManager()->sendMsg(buffer);
+ cli->sendMsg(buffer);
return 0;
}
diff --git a/nexus/CommandListener.h b/nexus/CommandListener.h
index 261c093..064eab8 100644
--- a/nexus/CommandListener.h
+++ b/nexus/CommandListener.h
@@ -19,50 +19,52 @@
#include <sysutils/FrameworkListener.h>
#include "NexusCommand.h"
-class NetworkManager;
-
class CommandListener : public FrameworkListener {
-protected:
- NetworkManager *mNetman;
-
public:
- CommandListener(NetworkManager *netman);
+ CommandListener();
virtual ~CommandListener() {}
private:
class WifiEnableCmd : public NexusCommand {
public:
- WifiEnableCmd(NetworkManager *);
+ WifiEnableCmd();
virtual ~WifiEnableCmd() {}
- int runCommand(char *data);
+ int runCommand(SocketClient *c, char *data);
};
class WifiDisableCmd : public NexusCommand {
public:
- WifiDisableCmd(NetworkManager *);
+ WifiDisableCmd();
virtual ~WifiDisableCmd() {}
- int runCommand(char *data);
+ int runCommand(SocketClient *c, char *data);
};
class WifiScanCmd : public NexusCommand {
public:
- WifiScanCmd(NetworkManager *);
+ WifiScanCmd();
virtual ~WifiScanCmd() {}
- int runCommand(char *data);
+ int runCommand(SocketClient *c, char *data);
+ };
+
+ class WifiScanResultsCmd : public NexusCommand {
+ public:
+ WifiScanResultsCmd();
+ virtual ~WifiScanResultsCmd() {}
+ int runCommand(SocketClient *c, char *data);
};
class VpnEnableCmd : public NexusCommand {
public:
- VpnEnableCmd(NetworkManager *);
+ VpnEnableCmd();
virtual ~VpnEnableCmd() {}
- int runCommand(char *data);
+ int runCommand(SocketClient *c, char *data);
};
class VpnDisableCmd : public NexusCommand {
public:
- VpnDisableCmd(NetworkManager *);
+ VpnDisableCmd();
virtual ~VpnDisableCmd() {}
- int runCommand(char *data);
+ int runCommand(SocketClient *c, char *data);
};
};
diff --git a/nexus/NetworkManager.cpp b/nexus/NetworkManager.cpp
index 9c64945..3b823d1 100644
--- a/nexus/NetworkManager.cpp
+++ b/nexus/NetworkManager.cpp
@@ -21,36 +21,30 @@
#include <cutils/log.h>
#include "NetworkManager.h"
-#include "CommandListener.h"
-#include "LoopController.h"
-#include "VpnController.h"
-#include "TiwlanWifiController.h"
+NetworkManager *NetworkManager::sInstance = NULL;
+
+NetworkManager *NetworkManager::Instance() {
+ if (!sInstance)
+ sInstance = new NetworkManager();
+ return sInstance;
+}
NetworkManager::NetworkManager() {
- mListener = new CommandListener(this);
- mFm = new FrameworkManager(mListener);
+ mBroadcaster = NULL;
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) {
+int NetworkManager::attachController(Controller *c) {
mControllers->push_back(c);
+ return 0;
}
int NetworkManager::startControllers() {
diff --git a/nexus/NetworkManager.h b/nexus/NetworkManager.h
index 8f362a9..0ac4a4d 100644
--- a/nexus/NetworkManager.h
+++ b/nexus/NetworkManager.h
@@ -16,31 +16,36 @@
#ifndef _NETWORKMANAGER_H
#define _NETWORKMANAGER_H
-#include "Controller.h"
+#include <sysutils/SocketListener.h>
-#include <sysutils/FrameworkManager.h>
+#include "Controller.h"
class NetworkManager {
private:
- FrameworkListener *mListener;
- FrameworkManager *mFm;
+ static NetworkManager *sInstance;
+
+private:
ControllerCollection *mControllers;
+ SocketListener *mBroadcaster;
public:
- NetworkManager();
virtual ~NetworkManager() {}
int run();
+ int attachController(Controller *controller);
+
+ Controller *findController(const char *name);
+
+ void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
+ SocketListener *getBroadcaster() { return mBroadcaster; }
+
+ static NetworkManager *Instance();
+
private:
- void addController(Controller *c);
int startControllers();
int stopControllers();
-
-public:
- Controller *findController(const char *name);
- ControllerCollection *getControllers() { return mControllers; }
- FrameworkManager *getFrameworkManager() { return mFm; }
+ NetworkManager();
public:
// XXX: Extract these into an interface
diff --git a/nexus/NexusCommand.cpp b/nexus/NexusCommand.cpp
index 090113c..92bb1c3 100644
--- a/nexus/NexusCommand.cpp
+++ b/nexus/NexusCommand.cpp
@@ -15,7 +15,6 @@
*/
#include "NexusCommand.h"
-NexusCommand::NexusCommand(const char *cmd, NetworkManager *netman) :
+NexusCommand::NexusCommand(const char *cmd) :
FrameworkCommand(cmd) {
- mNetman = netman;
}
diff --git a/nexus/NexusCommand.h b/nexus/NexusCommand.h
index 204541c..1482998 100644
--- a/nexus/NexusCommand.h
+++ b/nexus/NexusCommand.h
@@ -18,14 +18,9 @@
#include <sysutils/FrameworkCommand.h>
-class NetworkManager;
-
class NexusCommand : public FrameworkCommand {
-protected:
- NetworkManager *mNetman;
-
public:
- NexusCommand(const char *cmd, NetworkManager *netman);
+ NexusCommand(const char *cmd);
virtual ~NexusCommand() {}
};
diff --git a/nexus/ScanResult.h b/nexus/ScanResult.h
index 79b2b65..f70a1a9 100644
--- a/nexus/ScanResult.h
+++ b/nexus/ScanResult.h
@@ -38,6 +38,7 @@
const char *getBssid() { return mBssid; }
uint32_t getFreq() { return mFreq; }
+ int getLevel() { return mLevel; }
const char *getFlags() { return mFlags; }
const char *getSsid() { return mSsid; }
};
diff --git a/nexus/Supplicant.cpp b/nexus/Supplicant.cpp
index 215a8b3..d809e6e 100644
--- a/nexus/Supplicant.cpp
+++ b/nexus/Supplicant.cpp
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#include <stdlib.h>
#include <errno.h>
#define LOG_TAG "Supplicant"
@@ -31,6 +33,7 @@
#include "SupplicantState.h"
#include "SupplicantEvent.h"
#include "ScanResult.h"
+#include "NetworkManager.h"
#include "libwpa_client/wpa_ctrl.h"
@@ -52,7 +55,6 @@
}
int Supplicant::start() {
- LOGD("start():");
// XXX: Validate supplicant config file
char status[PROPERTY_VALUE_MAX] = {'\0'};
@@ -63,47 +65,47 @@
#endif
if (property_get(SUPP_PROP_NAME, status, NULL) &&
- strcmp(status, "running") == 0) {
- return 0;
+ !strcmp(status, "running")) {
+ LOGD("Supplicant already started");
+ } else {
+#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
+ pi = __system_property_find(SUPP_PROP_NAME);
+ if (pi != NULL)
+ serial = pi->serial;
+#endif
+
+ LOGD("Starting Supplicant");
+ 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)
+ break;
+ 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;
+ }
}
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;
@@ -112,7 +114,6 @@
}
int Supplicant::stop() {
- LOGD("stop()");
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
int count = 50;
@@ -124,9 +125,11 @@
if (property_get(SUPP_PROP_NAME, supp_status, NULL)
&& strcmp(supp_status, "stopped") == 0) {
+ LOGD("Supplicant already stopped");
return 0;
}
+ LOGD("Stopping Supplicant");
property_set("ctl.stop", SUPPLICANT_NAME);
sched_yield();
@@ -153,24 +156,29 @@
return -1;
}
- LOGD("Stopped OK");
+ LOGD("Supplicant shutdown");
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 rc = property_get(SUPP_PROP_NAME, supp_status, NULL);
+
+ LOGD("rc = %d, property = '%s'", rc, supp_status);
+
+ if (!strcmp(supp_status, "running"))
+ return true;
+
+ return false;
}
int Supplicant::connectToSupplicant() {
char ifname[256];
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
+ LOGD("connectToSupplicant()");
if (!property_get(SUPP_PROP_NAME, supp_status, NULL)
|| strcmp(supp_status, "running") != 0) {
LOGE("Supplicant not running, cannot connect");
@@ -213,13 +221,14 @@
return -1;
}
- LOGD("sendCommand(): -> '%s'", cmd);
+// 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)) {
+ LOGW("sendCommand(): <- '%s'", reply);
errno = EIO;
return -1;
}
@@ -228,7 +237,7 @@
!strncmp(cmd, "SCAN_RESULTS", 12))
reply[*reply_len] = '\0';
- LOGD("sendCommand(): <- '%s'", reply);
+// LOGD("sendCommand(): <- '%s'", reply);
return 0;
}
@@ -332,12 +341,16 @@
if (!strtok_r(reply, "\n", &linep_next)) {
free(reply);
- return 0;;
+ pthread_mutex_unlock(&mLatestScanResultsLock);
+ return 0;
}
while((linep = strtok_r(NULL, "\n", &linep_next)))
mLatestScanResults->push_back(new ScanResult(linep));
-
+
+ char tmp[32];
+ sprintf(tmp, "WIFI_SCAN_RESULTS_READY:%d", mLatestScanResults->size());
+ NetworkManager::Instance()->getBroadcaster()->sendBroadcast(tmp);
pthread_mutex_unlock(&mLatestScanResultsLock);
free(reply);
} else {
@@ -347,8 +360,24 @@
}
int Supplicant::onStateChangeEvent(SupplicantEvent *evt) {
- LOGD("onStateChangeEvent(%s)", evt->getEvent());
- // XXX: Update mState
+ char *bword, *last;
+ char *tmp = strdup(evt->getEvent());
+
+ if (!(bword = strtok_r(tmp, " ", &last))) {
+ LOGE("Malformatted state update (%s)", evt->getEvent());
+ free(tmp);
+ return 0;
+ }
+
+ if (!(bword = strtok_r(NULL, " ", &last))) {
+ LOGE("Malformatted state update (%s)", evt->getEvent());
+ free(tmp);
+ return 0;
+ }
+
+ mState = atoi(&bword[strlen("state=")]);
+ LOGD("State changed to %d", mState);
+ free(tmp);
return 0;
}
@@ -363,7 +392,7 @@
}
// XXX: Use a cursor + smartptr instead
-const ScanResultCollection *Supplicant::getLatestScanResults() {
+ScanResultCollection *Supplicant::createLatestScanResults() {
ScanResultCollection *d = new ScanResultCollection();
ScanResultCollection::iterator i;
diff --git a/nexus/Supplicant.h b/nexus/Supplicant.h
index 46a9e86..2a25ea2 100644
--- a/nexus/Supplicant.h
+++ b/nexus/Supplicant.h
@@ -46,7 +46,7 @@
int getState() { return mState; }
- const ScanResultCollection *getLatestScanResults();
+ ScanResultCollection *createLatestScanResults();
// XXX: Extract these into an interface
public:
diff --git a/nexus/SupplicantListener.cpp b/nexus/SupplicantListener.cpp
index 16306b5..76e9945 100644
--- a/nexus/SupplicantListener.cpp
+++ b/nexus/SupplicantListener.cpp
@@ -30,31 +30,9 @@
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) {
+bool SupplicantListener::onDataAvailable(SocketClient *cli) {
char buf[255];
size_t buflen = sizeof(buf);
int rc;
@@ -62,7 +40,7 @@
if ((rc = wpa_ctrl_recv(mMonitor, buf, &nread))) {
LOGE("wpa_ctrl_recv failed (%s)", strerror(errno));
- return -errno;
+ return false;
}
buf[nread] = '\0';
@@ -108,7 +86,9 @@
delete evt;
- if (rc)
+ if (rc) {
+ LOGW("Handler %d (%s) error: %s", evt->getType(), evt->getEvent(), strerror(errno));
return false;
+ }
return true;
}
diff --git a/nexus/SupplicantListener.h b/nexus/SupplicantListener.h
index 3d27a68..95bad9a 100644
--- a/nexus/SupplicantListener.h
+++ b/nexus/SupplicantListener.h
@@ -16,33 +16,27 @@
#ifndef _SUPPLICANTLISTENER_H__
#define _SUPPLICANTLISTENER_H__
-#include <pthread.h>
-
#include <sysutils/SocketListener.h>
struct wpa_ctrl;
class Supplicant;
+class SocketClient;
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);
+ virtual bool onDataAvailable(SocketClient *c);
-private:
- static void *threadStart(void *obj);
};
#endif
diff --git a/nexus/SupplicantState.h b/nexus/SupplicantState.h
index f2cf603..e85dcb5 100644
--- a/nexus/SupplicantState.h
+++ b/nexus/SupplicantState.h
@@ -18,16 +18,16 @@
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;
+ static const int UNKNOWN = -1;
+ static const int DISCONNECTED = 0;
+ static const int INACTIVE = 1;
+ static const int SCANNING = 2;
+ static const int ASSOCIATING = 3;
+ static const int ASSOCIATED = 4;
+ static const int FOURWAY_HANDSHAKE = 5;
+ static const int GROUP_HANDSHAKE = 6;
+ static const int COMPLETED = 7;
+ static const int IDLE = 8;
};
#endif
diff --git a/nexus/TiwlanWifiController.cpp b/nexus/TiwlanWifiController.cpp
index ec83825..10606a1 100644
--- a/nexus/TiwlanWifiController.cpp
+++ b/nexus/TiwlanWifiController.cpp
@@ -65,3 +65,17 @@
property_set(DRIVER_PROP_NAME, "timeout");
return -1;
}
+
+bool TiwlanWifiController::isFirmwareLoaded() {
+ char driver_status[PROPERTY_VALUE_MAX];
+ if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
+ if (!strcmp(driver_status, "ok"))
+ return true;
+ else {
+ LOGD("Driver status '%s'", driver_status);
+ return false;
+ }
+ }
+ LOGW("Unable to get property '%s'", DRIVER_PROP_NAME);
+ return false;
+}
diff --git a/nexus/TiwlanWifiController.h b/nexus/TiwlanWifiController.h
index a93d610..f17ef51 100644
--- a/nexus/TiwlanWifiController.h
+++ b/nexus/TiwlanWifiController.h
@@ -27,5 +27,6 @@
virtual int powerDown();
virtual bool isPoweredUp();
virtual int loadFirmware();
+ virtual bool isFirmwareLoaded();
};
#endif
diff --git a/nexus/WifiController.cpp b/nexus/WifiController.cpp
index 8a7e33f..806141c 100644
--- a/nexus/WifiController.cpp
+++ b/nexus/WifiController.cpp
@@ -21,6 +21,8 @@
#include "Supplicant.h"
#include "WifiController.h"
+#include "WifiScanner.h"
+#include "NetworkManager.h"
WifiController::WifiController(char *modpath, char *modname, char *modargs) :
Controller("WIFI") {
@@ -29,6 +31,7 @@
strncpy(mModuleArgs, modargs, sizeof(mModuleArgs));
mSupplicant = new Supplicant();
+ mScanner = new WifiScanner(mSupplicant, 10);
mCurrentScanMode = 0;
}
@@ -42,26 +45,36 @@
}
int WifiController::enable() {
- if (!isPoweredUp() && powerUp()) {
- LOGE("Powerup failed (%s)", strerror(errno));
- return -1;
+ if (!isPoweredUp()) {
+ sendStatusBroadcast("POWERING_UP");
+ if (powerUp()) {
+ LOGE("Powerup failed (%s)", strerror(errno));
+ return -1;
+ }
}
-
+
if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
+ sendStatusBroadcast("LOADING_DRIVER");
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 (!isFirmwareLoaded()) {
+ sendStatusBroadcast("LOADING_FIRMWARE");
+ 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;
+ if (!mSupplicant->isStarted()) {
+ sendStatusBroadcast("STARTING_SUPPLICANT");
+ if (mSupplicant->start()) {
+ LOGE("Supplicant start failed (%s)", strerror(errno));
+ goto out_unloadmodule;
+ }
}
return 0;
@@ -80,24 +93,38 @@
return -1;
}
-int WifiController::disable() {
- LOGD("disable()");
+void WifiController::sendStatusBroadcast(const char *msg) {
+ char tmp[255];
- if (mSupplicant->isStarted() && mSupplicant->stop()) {
- LOGE("Supplicant stop failed (%s)", strerror(errno));
- return -1;
- }
+ sprintf(tmp, "WIFI_STATUS:%s", msg);
+ NetworkManager::Instance()->getBroadcaster()->sendBroadcast(tmp);
+}
+
+int WifiController::disable() {
+
+ if (mSupplicant->isStarted()) {
+ sendStatusBroadcast("STOPPING_SUPPLICANT");
+ if (mSupplicant->stop()) {
+ LOGE("Supplicant stop failed (%s)", strerror(errno));
+ return -1;
+ }
+ } else
+ LOGW("disable(): Supplicant not running?");
if (mModuleName[0] != '\0' && isKernelModuleLoaded(mModuleName)) {
+ sendStatusBroadcast("UNLOADING_DRIVER");
if (unloadKernelModule(mModuleName)) {
LOGE("Unable to unload module (%s)", strerror(errno));
return -1;
}
}
- if (isPoweredUp() && powerDown()) {
- LOGE("Powerdown failed (%s)", strerror(errno));
- return -1;
+ if (isPoweredUp()) {
+ sendStatusBroadcast("POWERING_DOWN");
+ if (powerDown()) {
+ LOGE("Powerdown failed (%s)", strerror(errno));
+ return -1;
+ }
}
return 0;
}
@@ -106,7 +133,7 @@
return 0;
}
-int WifiController::setScanMode(int mode) {
+int WifiController::setScanMode(uint32_t mode) {
int rc = 0;
if (mCurrentScanMode == mode)
@@ -114,21 +141,15 @@
if (!(mode & SCAN_ENABLE_MASK)) {
if (mCurrentScanMode & SCAN_REPEAT_MASK)
- stopPeriodicScan();
+ mScanner->stopPeriodicScan();
} else if (mode & SCAN_REPEAT_MASK)
- rc = startPeriodicScan();
+ rc = mScanner->startPeriodicScan(mode & SCAN_ACTIVE_MASK);
else
rc = mSupplicant->triggerScan(mode & SCAN_ACTIVE_MASK);
return rc;
}
-int WifiController::startPeriodicScan() {
- errno = -ENOSYS;
- return -1;
-}
-
-int WifiController::stopPeriodicScan() {
- errno = -ENOSYS;
- return -1;
+ScanResultCollection *WifiController::createScanResults() {
+ return mSupplicant->createLatestScanResults();
}
diff --git a/nexus/WifiController.h b/nexus/WifiController.h
index 6d00513..38aea81 100644
--- a/nexus/WifiController.h
+++ b/nexus/WifiController.h
@@ -22,6 +22,9 @@
class NetInterface;
class Supplicant;
+class WifiScanner;
+
+#include "ScanResult.h"
class WifiController : public Controller {
public:
@@ -40,8 +43,8 @@
char mModulePath[255];
char mModuleName[64];
char mModuleArgs[255];
- int mCurrentScanMode;
-
+ uint32_t mCurrentScanMode;
+ WifiScanner *mScanner;
public:
WifiController(char *modpath, char *modname, char *modargs);
@@ -53,6 +56,8 @@
int enable();
int disable();
+ ScanResultCollection *createScanResults();
+
int getType();
char *getModulePath() { return mModulePath; }
@@ -62,17 +67,17 @@
Supplicant *getSupplicant() { return mSupplicant; }
int getScanMode() { return mCurrentScanMode; }
- int setScanMode(int mode);
+ int setScanMode(uint32_t mode);
protected:
virtual int powerUp() = 0;
virtual int powerDown() = 0;
virtual int loadFirmware();
+
+ virtual bool isFirmwareLoaded() = 0;
virtual bool isPoweredUp() = 0;
-private:
- int startPeriodicScan();
- int stopPeriodicScan();
+ void sendStatusBroadcast(const char *msg);
};
#endif
diff --git a/nexus/WifiScanner.cpp b/nexus/WifiScanner.cpp
new file mode 100644
index 0000000..590d895
--- /dev/null
+++ b/nexus/WifiScanner.cpp
@@ -0,0 +1,96 @@
+#include <errno.h>
+#include <pthread.h>
+
+#define LOG_TAG "WifiScanner"
+#include <cutils/log.h>
+
+#include "WifiScanner.h"
+#include "Supplicant.h"
+
+extern "C" int pthread_cancel(pthread_t thread);
+
+WifiScanner::WifiScanner(Supplicant *suppl, int period) {
+ mSuppl = suppl;
+ mPeriod = period;
+ mActive = false;
+ mWorkerRunning = false;
+ mAbortRequest = false;
+ pthread_mutex_init(&mAbortRequestLock, NULL);
+ pthread_mutex_init(&mWorkerLock, NULL);
+}
+
+int WifiScanner::startPeriodicScan(bool active) {
+ mActive = active;
+
+ pthread_mutex_lock(&mWorkerLock);
+ if (mWorkerRunning) {
+ errno = EBUSY;
+ return -1;
+ }
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ if (pthread_create(&mWorker, &attr, WifiScanner::threadStart, this))
+ return -1;
+
+ return 0;
+}
+
+void *WifiScanner::threadStart(void *obj) {
+ WifiScanner *me = reinterpret_cast<WifiScanner *>(obj);
+ me->run();
+ pthread_exit(NULL);
+ return NULL;
+}
+
+void WifiScanner::threadCleanup(void *obj) {
+ WifiScanner *me = reinterpret_cast<WifiScanner *>(obj);
+
+ me->mWorkerRunning = false;
+ pthread_mutex_unlock(&me->mWorkerLock);
+
+ if (me->mAbortRequest) {
+ me->mAbortRequest = false;
+ pthread_mutex_unlock(&me->mAbortRequestLock);
+ }
+}
+
+int WifiScanner::stopPeriodicScan() {
+ pthread_mutex_lock(&mAbortRequestLock);
+ pthread_mutex_lock(&mWorkerLock);
+ if (mWorkerRunning)
+ mAbortRequest = true;
+ pthread_mutex_unlock(&mWorkerLock);
+ pthread_mutex_unlock(&mAbortRequestLock);
+
+ return 0;
+}
+
+void WifiScanner::run() {
+ LOGD("Thread started");
+
+ mWorkerRunning = true;
+ pthread_cleanup_push(WifiScanner::threadCleanup, this);
+ pthread_mutex_unlock(&mWorkerLock);
+
+ while(1) {
+ LOGD("Triggering periodic scan");
+ if (mSuppl->triggerScan(mActive)) {
+ LOGW("Error triggering scan (%s)", strerror(errno));
+ }
+
+ sleep(mPeriod);
+ pthread_mutex_lock(&mAbortRequestLock);
+ if (mAbortRequest) {
+ LOGD("Abort request!");
+ goto out;
+ }
+ pthread_mutex_unlock(&mAbortRequestLock);
+ }
+
+out:
+ pthread_cleanup_pop(1);
+ pthread_mutex_unlock(&mWorkerLock);
+}
diff --git a/nexus/WifiScanner.h b/nexus/WifiScanner.h
new file mode 100644
index 0000000..9ba1309
--- /dev/null
+++ b/nexus/WifiScanner.h
@@ -0,0 +1,36 @@
+#ifndef _WIFISCANNER_H
+#define _WIFISCANNER_H
+
+#include <pthread.h>
+
+class Supplicant;
+
+class WifiScanner {
+ pthread_t mWorker;
+ pthread_mutex_t mWorkerLock;
+ bool mWorkerRunning;
+ bool mAbortRequest;
+ pthread_mutex_t mAbortRequestLock;
+
+ Supplicant *mSuppl;
+ int mPeriod;
+ bool mActive;
+
+
+public:
+ WifiScanner(Supplicant *suppl, int period);
+ virtual ~WifiScanner() {}
+
+ int getPeriod() { return mPeriod; }
+
+ int startPeriodicScan(bool active);
+ int stopPeriodicScan();
+
+private:
+ static void *threadStart(void *obj);
+ static void threadCleanup(void *obj);
+
+ void run();
+};
+
+#endif
diff --git a/nexus/main.cpp b/nexus/main.cpp
index a26a14d..0a0b43f 100644
--- a/nexus/main.cpp
+++ b/nexus/main.cpp
@@ -20,22 +20,44 @@
#include "cutils/log.h"
#include "NetworkManager.h"
+#include "CommandListener.h"
+
+#include "LoopController.h"
+#include "VpnController.h"
+#include "TiwlanWifiController.h"
int main() {
- NetworkManager *nm;
-
LOGI("Nexus version 0.1 firing up");
- if (!(nm = new NetworkManager())) {
+ CommandListener *cl = new CommandListener();
+
+ NetworkManager *nm;
+ if (!(nm = NetworkManager::Instance())) {
LOGE("Unable to create NetworkManager");
exit (-1);
};
- if (nm->run()) {
+ nm->setBroadcaster((SocketListener *) cl);
+
+ nm->attachController(new LoopController());
+ nm->attachController(new TiwlanWifiController("/system/lib/modules/wlan.ko", "wlan", ""));
+ nm->attachController(new VpnController());
+
+
+ if (NetworkManager::Instance()->run()) {
LOGE("Unable to Run NetworkManager (%s)", strerror(errno));
exit (1);
}
+ if (cl->startListener()) {
+ LOGE("Unable to start CommandListener (%s)", strerror(errno));
+ exit (1);
+ }
+
+ while(1) {
+ sleep(1000);
+ }
+
LOGI("Nexus exiting");
exit(0);
}
diff --git a/nexus/nexctl.c b/nexus/nexctl.c
index 6d117c7..c326558 100644
--- a/nexus/nexctl.c
+++ b/nexus/nexctl.c
@@ -65,14 +65,13 @@
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_sec = 10;
to.tv_usec = 0;
FD_ZERO(&read_fds);
FD_SET(sock, &read_fds);
@@ -88,12 +87,11 @@
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) {
+ if ((rc = read(sock, buffer, sizeof(buffer)-1)) <= 0) {
fprintf(stderr, "Error reading response (%s)\n", strerror(errno));
exit(2);
}
- printf(" |%s|\n", buffer);
+ printf(" %s\n", buffer);
goto wait;
}
}