summaryrefslogtreecommitdiffstats
path: root/nexus
diff options
context:
space:
mode:
authorSan Mehat <san@google.com>2009-06-16 10:50:06 -0700
committerSan Mehat <san@google.com>2009-06-16 10:50:06 -0700
commit5fc4129fcb9609790e2d1d3a93c7d9de8dd94ccb (patch)
treecf149a4f20c63fa5137f3b1cffd5cb2f48eb836a /nexus
parent43c16197b2a6da3a3125b4a4a9fa6b70f447043e (diff)
downloadsystem_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.cpp61
-rw-r--r--nexus/TiwlanEventListener.h55
-rw-r--r--nexus/TiwlanWifiController.cpp56
-rw-r--r--nexus/TiwlanWifiController.h7
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