diff options
author | San Mehat <san@google.com> | 2009-06-16 10:50:06 -0700 |
---|---|---|
committer | San Mehat <san@google.com> | 2009-06-16 10:50:06 -0700 |
commit | 5fc4129fcb9609790e2d1d3a93c7d9de8dd94ccb (patch) | |
tree | cf149a4f20c63fa5137f3b1cffd5cb2f48eb836a /nexus | |
parent | 43c16197b2a6da3a3125b4a4a9fa6b70f447043e (diff) | |
download | system_core-5fc4129fcb9609790e2d1d3a93c7d9de8dd94ccb.zip system_core-5fc4129fcb9609790e2d1d3a93c7d9de8dd94ccb.tar.gz system_core-5fc4129fcb9609790e2d1d3a93c7d9de8dd94ccb.tar.bz2 |
nexus: Add TiwlanEventListener for reading driver events directly
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'nexus')
-rw-r--r-- | nexus/TiwlanEventListener.cpp | 61 | ||||
-rw-r--r-- | nexus/TiwlanEventListener.h | 55 | ||||
-rw-r--r-- | nexus/TiwlanWifiController.cpp | 56 | ||||
-rw-r--r-- | nexus/TiwlanWifiController.h | 7 |
4 files changed, 177 insertions, 2 deletions
diff --git a/nexus/TiwlanEventListener.cpp b/nexus/TiwlanEventListener.cpp new file mode 100644 index 0000000..76e6ec1 --- /dev/null +++ b/nexus/TiwlanEventListener.cpp @@ -0,0 +1,61 @@ +/* + * 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 <pthread.h> +#include <sys/types.h> +#include <sys/types.h> +#include <sys/socket.h> + +#define LOG_TAG "TiwlanEventListener" +#include <cutils/log.h> + +#include "TiwlanEventListener.h" + +TiwlanEventListener::TiwlanEventListener(int socket) : + SocketListener(socket, false) { +} + +bool TiwlanEventListener::onDataAvailable(SocketClient *cli) { + struct ipc_ev_data *data; + + if (!(data = (struct ipc_ev_data *) malloc(sizeof(struct ipc_ev_data)))) { + LOGE("Failed to allocate packet (out of memory)"); + return true; + } + + if (recv(cli->getSocket(), data, sizeof(struct ipc_ev_data), 0) < 0) { + LOGE("recv failed (%s)", strerror(errno)); + goto out; + } + + if (data->event_type == IPC_EVENT_LINK_SPEED) { + uint32_t *spd = (uint32_t *) data->buffer; + *spd /= 2; + LOGD("Link speed = %u MB/s", *spd); + } else if (data->event_type == IPC_EVENT_LOW_SNR) { + LOGD("Low signal/noise ratio"); + } else if (data->event_type == IPC_EVENT_LOW_RSSI) { + LOGD("Low RSSI"); + } else { + LOGD("Dropping unhandled driver event %d", data->event_type); + } + + // TODO: Tell WifiController about the event +out: + free(data); + return true; +} diff --git a/nexus/TiwlanEventListener.h b/nexus/TiwlanEventListener.h new file mode 100644 index 0000000..052d6b1 --- /dev/null +++ b/nexus/TiwlanEventListener.h @@ -0,0 +1,55 @@ +/* + * 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_EVENT_LISTENER_H__ +#define _TIWLAN_EVENT_LISTENER_H__ + +#include <sysutils/SocketListener.h> + +struct wpa_ctrl; +class SocketClient; +class ITiwlanEventHandler; +class TiwlanEventFactory; + +class TiwlanEventListener: public SocketListener { + +public: + TiwlanEventListener(int sock); + virtual ~TiwlanEventListener() {} + +protected: + virtual bool onDataAvailable(SocketClient *c); +}; + +// TODO: Move all this crap into a factory +#define TI_DRIVER_MSG_PORT 9001 + +#define IPC_EVENT_LINK_SPEED 2 +#define IPC_EVENT_LOW_SNR 13 +#define IPC_EVENT_LOW_RSSI 14 + +struct ipc_ev_data { + uint32_t event_type; + void *event_id; + uint32_t process_id; + uint32_t delivery_type; + uint32_t user_param; + void *event_callback; + uint32_t bufferSize; + uint8_t buffer[2048]; +}; + +#endif diff --git a/nexus/TiwlanWifiController.cpp b/nexus/TiwlanWifiController.cpp index 6945e3e..61535c3 100644 --- a/nexus/TiwlanWifiController.cpp +++ b/nexus/TiwlanWifiController.cpp @@ -18,6 +18,9 @@ #include <fcntl.h> #include <errno.h> #include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> #include <cutils/properties.h> #define LOG_TAG "TiwlanWifiController" @@ -25,6 +28,7 @@ #include "PropertyManager.h" #include "TiwlanWifiController.h" +#include "TiwlanEventListener.h" #define DRIVER_PROP_NAME "wlan.driver.status" @@ -36,6 +40,8 @@ TiwlanWifiController::TiwlanWifiController(PropertyManager *propmngr, char *modargs) : WifiController(propmngr, handlers, modpath, modname, modargs) { + mEventListener = NULL; + mListenerSock = -1; } int TiwlanWifiController::powerUp() { @@ -43,6 +49,13 @@ int TiwlanWifiController::powerUp() { } int TiwlanWifiController::powerDown() { + if (mEventListener) { + delete mEventListener; + close(mListenerSock); + mListenerSock = -1; + mEventListener = NULL; + } + return 0; // Powerdown is currently done when the driver is unloaded } @@ -60,17 +73,56 @@ int TiwlanWifiController::loadFirmware() { // Wait for driver to be ready while (count-- > 0) { if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) { - if (strcmp(driver_status, "ok") == 0) + if (!strcmp(driver_status, "ok")) { + LOGD("Firmware loaded OK"); + + if (startDriverEventListener()) { + LOGW("Failed to start driver event listener"); + } + return 0; - else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) + } else if (!strcmp(DRIVER_PROP_NAME, "failed")) { + LOGE("Firmware load failed"); return -1; + } } usleep(200000); } property_set(DRIVER_PROP_NAME, "timeout"); + LOGE("Firmware load timed out"); return -1; } +int TiwlanWifiController::startDriverEventListener() { + struct sockaddr_in addr; + int s; + + if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + return -1; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(TI_DRIVER_MSG_PORT); + + if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(s); + return -1; + } + + mEventListener = new TiwlanEventListener(s); + + if (mEventListener->startListener()) { + LOGE("Error starting driver listener (%s)", strerror(errno)); + delete mEventListener; + mEventListener = NULL; + close(s); + return -1; + } + mListenerSock = s; + return 0; +} + bool TiwlanWifiController::isFirmwareLoaded() { // Always load the firmware return false; diff --git a/nexus/TiwlanWifiController.h b/nexus/TiwlanWifiController.h index 852a288..583be71 100644 --- a/nexus/TiwlanWifiController.h +++ b/nexus/TiwlanWifiController.h @@ -21,8 +21,12 @@ #include "WifiController.h" class IControllerHandler; +class TiwlanEventListener; class TiwlanWifiController : public WifiController { + int mListenerSock; + TiwlanEventListener *mEventListener; + public: TiwlanWifiController(PropertyManager *propmngr, IControllerHandler *handlers, char *modpath, char *modname, char *modargs); virtual ~TiwlanWifiController() {} @@ -32,5 +36,8 @@ public: virtual bool isPoweredUp(); virtual int loadFirmware(); virtual bool isFirmwareLoaded(); + +private: + int startDriverEventListener(); }; #endif |