Merge commit 'goog/master' into merge_master
diff --git a/init/devices.c b/init/devices.c
index 04ada63..880536c 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -126,6 +126,9 @@
     { "/dev/msm_mp3",       0660,   AID_SYSTEM,     AID_AUDIO,      1 },
     { "/dev/msm_audpre",    0660,   AID_SYSTEM,     AID_AUDIO,      0 },
     { "/dev/htc-acoustic",  0660,   AID_SYSTEM,     AID_AUDIO,      0 },
+    { "/dev/snd/dsp",       0660,   AID_SYSTEM,     AID_AUDIO,      0 },
+    { "/dev/snd/dsp1",      0660,   AID_SYSTEM,     AID_AUDIO,      0 },
+    { "/dev/snd/mixer",     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 },
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 7d14e3f..fdddf22 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -46,8 +46,11 @@
 
 #define LOG_API(...) do {} while(0)
 // #define LOG_API(...) fprintf (stderr, __VA_ARGS__)
-// #define ENABLE_ARM_DISASSEMBLY
 
+#define LOG_STACK(...) do {} while(0)
+// #define LOG_STACK(...) fprintf (stderr, __VA_ARGS__)
+
+// #define ENABLE_ARM_DISASSEMBLY
 // #define PROVIDE_TRACE_CODEGEN
 
 namespace acc {
@@ -399,27 +402,38 @@
     class ARMCodeGenerator : public CodeGenerator {
     public:
         ARMCodeGenerator() {}
+
         virtual ~ARMCodeGenerator() {}
 
         /* returns address to patch with local variable size
         */
         virtual int functionEntry(int argCount) {
             LOG_API("functionEntry(%d);\n", argCount);
+            mStackUse = 0;
             // sp -> arg4 arg5 ...
             // Push our register-based arguments back on the stack
             if (argCount > 0) {
                 int regArgCount = argCount <= 4 ? argCount : 4;
                 o4(0xE92D0000 | ((1 << argCount) - 1)); // stmfd    sp!, {}
+                mStackUse += regArgCount * 4;
             }
             // sp -> arg0 arg1 ...
             o4(0xE92D4800); // stmfd sp!, {fp, lr}
+            mStackUse += 2 * 4;
             // sp, fp -> oldfp, retadr, arg0 arg1 ....
             o4(0xE1A0B00D); // mov    fp, sp
+            LOG_STACK("functionEntry: %d\n", mStackUse);
             return o4(0xE24DD000); // sub    sp, sp, # <local variables>
+            // We don't know how many local variables we are going to use,
+            // but we will round the allocation up to a multiple of
+            // STACK_ALIGNMENT, so it won't affect the stack alignment.
         }
 
         virtual void functionExit(int argCount, int localVariableAddress, int localVariableSize) {
             LOG_API("functionExit(%d, %d, %d);\n", argCount, localVariableAddress, localVariableSize);
+            // Round local variable size up to a multiple of stack alignment
+            localVariableSize = ((localVariableSize + STACK_ALIGNMENT - 1) /
+                STACK_ALIGNMENT) * STACK_ALIGNMENT;
             // Patch local variable allocation code:
             if (localVariableSize < 0 || localVariableSize > 255) {
                 error("localVariables out of range: %d", localVariableSize);
@@ -547,11 +561,6 @@
                 error("Unimplemented op %d\n", op);
                 break;
             }
-#if 0
-            o(decodeOp(op));
-            if (op == OP_MOD)
-                o(0x92); /* xchg %edx, %eax */
-#endif
         }
 
         virtual void clearR1() {
@@ -562,11 +571,15 @@
         virtual void pushR0() {
             LOG_API("pushR0();\n");
             o4(0xE92D0001);  // stmfd   sp!,{r0}
+            mStackUse += 4;
+            LOG_STACK("pushR0: %d\n", mStackUse);
         }
 
         virtual void popR1() {
             LOG_API("popR1();\n");
             o4(0xE8BD0002);  // ldmfd   sp!,{r1}
+            mStackUse -= 4;
+            LOG_STACK("popR1: %d\n", mStackUse);
         }
 
         virtual void storeR0ToR1(bool isInt) {
@@ -690,15 +703,31 @@
 
         virtual void endFunctionCallArguments(int a, int l) {
             LOG_API("endFunctionCallArguments(0x%08x, %d);\n", a, l);
+            int argCount = l >> 2;
+            int argumentStackUse = l;
+            if (argCount > 0) {
+                int regArgCount = argCount > 4 ? 4 : argCount;
+                argumentStackUse -= regArgCount * 4;
+                o4(0xE8BD0000 | ((1 << regArgCount) - 1)); // ldmfd   sp!,{}
+            }
+            mStackUse += argumentStackUse;
+
+            // Align stack.
+            int missalignment = mStackUse - ((mStackUse / STACK_ALIGNMENT)
+                    * STACK_ALIGNMENT);
+            mStackAlignmentAdjustment = 0;
+            if (missalignment > 0) {
+                mStackAlignmentAdjustment = STACK_ALIGNMENT - missalignment;
+            }
+            l += mStackAlignmentAdjustment;
+
             if (l < 0 || l > 0x3FC) {
                 error("L out of range for stack adjustment: 0x%08x", l);
             }
             * (int*) a = 0xE24DDF00 | (l >> 2); // sub    sp, sp, #0 << 2
-            int argCount = l >> 2;
-            if (argCount > 0) {
-                int regArgCount = argCount > 4 ? 4 : argCount;
-                o4(0xE8BD0000 | ((1 << regArgCount) - 1)); // ldmfd   sp!,{}
-            }
+            mStackUse += mStackAlignmentAdjustment;
+            LOG_STACK("endFunctionCallArguments mStackUse: %d, mStackAlignmentAdjustment %d\n",
+                      mStackUse, mStackAlignmentAdjustment);
         }
 
         virtual int callForward(int symbol) {
@@ -727,7 +756,7 @@
             LOG_API("callIndirect(%d);\n", l);
             int argCount = l >> 2;
             int poppedArgs = argCount > 4 ? 4 : argCount;
-            int adjustedL = l - (poppedArgs << 2);
+            int adjustedL = l - (poppedArgs << 2) + mStackAlignmentAdjustment;
             if (adjustedL < 0 || adjustedL > 4096-4) {
                 error("l out of range for stack offset: 0x%08x", l);
             }
@@ -739,12 +768,15 @@
             LOG_API("adjustStackAfterCall(%d, %d);\n", l, isIndirect);
             int argCount = l >> 2;
             int stackArgs = argCount > 4 ? argCount - 4 : 0;
-            int stackUse = stackArgs + (isIndirect ? 1 : 0);
+            int stackUse =  stackArgs + (isIndirect ? 1 : 0)
+                + (mStackAlignmentAdjustment >> 2);
             if (stackUse) {
                 if (stackUse < 0 || stackUse > 255) {
                     error("L out of range for stack adjustment: 0x%08x", l);
                 }
                 o4(0xE28DDF00 | stackUse); // add    sp, sp, #stackUse << 2
+                mStackUse -= stackUse * 4;
+                LOG_STACK("adjustStackAfterCall: %d\n", mStackUse);
             }
         }
 
@@ -858,6 +890,13 @@
         static int runtime_MOD(int a, int b) {
             return b % a;
         }
+
+        static const int STACK_ALIGNMENT = 8;
+        int mStackUse;
+        // This variable holds the amount we adjusted the stack in the most
+        // recent endFunctionCallArguments call. It's examined by the
+        // following adjustStackAfterCall call.
+        int mStackAlignmentAdjustment;
     };
 
 #endif // PROVIDE_ARM_CODEGEN
@@ -981,7 +1020,9 @@
             if (isIndirect) {
                 l += 4;
             }
-            oad(0xc481, l); /* add $xxx, %esp */
+            if (l > 0) {
+                oad(0xc481, l); /* add $xxx, %esp */
+            }
         }
 
         virtual int jumpOffset() {
@@ -2315,8 +2356,7 @@
             } else {
                 pGen->callRelative(n - codeBuf.getPC() - pGen->jumpOffset());
             }
-            if (l | (n == 1))
-                pGen->adjustStackAfterCall(l, n == 1);
+            pGen->adjustStackAfterCall(l, n == 1);
         }
     }
 
@@ -3025,6 +3065,11 @@
     script->compiler.getPragmas(actualStringCount, maxStringCount, strings);
 }
 
+extern "C"
+void accDisassemble(ACCscript* script) {
+    script->compiler.disassemble(stderr);
+}
+
 
 } // namespace acc
 
diff --git a/libacc/tests/main.cpp b/libacc/tests/main.cpp
index 4f8a65d..13a30d4 100644
--- a/libacc/tests/main.cpp
+++ b/libacc/tests/main.cpp
@@ -29,6 +29,11 @@
     return mainFunc(argc, argv);
 }
 
+// Private API for development:
+
+extern "C"
+void accDisassemble(ACCscript* script);
+
 int main(int argc, char** argv) {
     const char* inFile = NULL;
     bool printListing;
@@ -109,6 +114,10 @@
         }
     }
 
+    if (printListing) {
+        accDisassemble(script);
+    }
+
     if (runResults) {
         accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
 
diff --git a/libzipfile/centraldir.c b/libzipfile/centraldir.c
index 4387ceb..0391c09 100644
--- a/libzipfile/centraldir.c
+++ b/libzipfile/centraldir.c
@@ -13,7 +13,7 @@
     // central directory entries

     ENTRY_SIGNATURE = 0x02014b50,

     ENTRY_LEN = 46,          // CentralDirEnt len, excl. var fields

-    

+

     // local file header

     LFH_SIZE = 30,

 };

@@ -73,8 +73,6 @@
     unsigned short  lastModFileTime;

     unsigned short  lastModFileDate;

     unsigned long   crc32;

-    unsigned long   compressedSize;

-    unsigned long   uncompressedSize;

     unsigned short  extraFieldLength;

     unsigned short  fileCommentLength;

     unsigned short  diskNumberStart;

@@ -85,7 +83,7 @@
     const unsigned char*  fileComment;

     unsigned int dataOffset;

     unsigned short lfhExtraFieldSize;

-    

+

 

     p = *buf;

 

@@ -106,7 +104,7 @@
     lastModFileTime = read_le_short(&p[0x0c]);

     lastModFileDate = read_le_short(&p[0x0e]);

     crc32 = read_le_int(&p[0x10]);

-    compressedSize = read_le_int(&p[0x14]);

+    entry->compressedSize = read_le_int(&p[0x14]);

     entry->uncompressedSize = read_le_int(&p[0x18]);

     entry->fileNameLength = read_le_short(&p[0x1c]);

     extraFieldLength = read_le_short(&p[0x1e]);

@@ -141,14 +139,14 @@
         fileComment = NULL;

     }

     p += fileCommentLength;

-    

+

     *buf = p;

 

     // the size of the extraField in the central dir is how much data there is,

     // but the one in the local file header also contains some padding.

     p = file->buf + localHeaderRelOffset;

     extraFieldLength = read_le_short(&p[0x1c]);

-    

+

     dataOffset = localHeaderRelOffset + LFH_SIZE

         + entry->fileNameLength + extraFieldLength;

     entry->data = file->buf + dataOffset;

@@ -243,7 +241,7 @@
             free(entry);

             goto bail;

         }

-        

+

         // add it to our list

         entry->next = file->entries;

         file->entries = entry;

@@ -253,4 +251,3 @@
 bail:

     return -1;

 }

-

diff --git a/libzipfile/zipfile.c b/libzipfile/zipfile.c
index b52d02d..a401a9b 100644
--- a/libzipfile/zipfile.c
+++ b/libzipfile/zipfile.c
@@ -82,13 +82,13 @@
     unsigned long crc;
     int err = 0;
     int zerr;
-    
+
     memset(&zstream, 0, sizeof(zstream));
     zstream.zalloc = Z_NULL;
     zstream.zfree = Z_NULL;
     zstream.opaque = Z_NULL;
     zstream.next_in = (void*)in;
-    zstream.avail_in = unlen;
+    zstream.avail_in = clen;
     zstream.next_out = (Bytef*) out;
     zstream.avail_out = unlen;
     zstream.data_type = Z_UNKNOWN;
@@ -99,7 +99,7 @@
     if (zerr != Z_OK) {
         return -1;
     }
-    
+
     // uncompress the data
     zerr = inflate(&zstream, Z_FINISH);
     if (zerr != Z_STREAM_END) {
@@ -107,7 +107,7 @@
                     zstream.total_out);
         err = -1;
     }
-    
+
      inflateEnd(&zstream);
     return err;
 }
diff --git a/logcat/event-log-tags b/logcat/event-log-tags
index 13f7488..8b49fa8 100644
--- a/logcat/event-log-tags
+++ b/logcat/event-log-tags
@@ -94,7 +94,7 @@
 2800 gtalkservice (eventType|1)
 # This event is logged for GTalk connection state changes. The status field is an int, but
 # it really contains 4 separate values, each taking up a byte
-# (eventType, connection state, connection error, network state)
+#     (eventType << 24) + (connection state << 16) + (connection error << 8) + network state
 2801 gtalk_connection (status|1)
 
 2802 watchdog (Service|3)
@@ -135,6 +135,26 @@
 3100 boot_progress_pms_ready (time|2|3)
 # + check activity_launch_time for Home app
 
+# This event is logged when GTalk connection is closed.
+# The status field is an int, but contains 2 different values, it's represented as
+#
+#     (networkType << 8) + connection error
+#
+# the possible error values are
+#
+# no_error=0, no_network=1, connection_failed=2, unknown_host=3, auth_failed=4,
+# auth_expired=5, heart_beat_timeout=6, server_error=7, server_reject_rate_limiting=8, unknown=10
+#
+# duration is the connection duration.
+4000 gtalk_conn_close (status|1),(duration|1)
+
+# This event is logged for GTalk heartbeat resets
+# interval_and_nt contains both the heartbeat interval and the network type, It's represented as
+#     (networkType << 16) + interval
+# interval is in seconds; network type can be 0 (mobile) or 1 (wifi); ip is the host ip addr.
+4001 gtalk_heartbeat_reset (interval_and_nt|1),(ip|3)
+
+
 # Do not change these names without updating the checkin_events setting in
 # google3/googledata/wireless/android/provisioning/gservices.config !!
 #
diff --git a/nexus/Android.mk b/nexus/Android.mk
index 6172e62..865f58a 100644
--- a/nexus/Android.mk
+++ b/nexus/Android.mk
@@ -33,7 +33,8 @@
                   SupplicantScanResultsEvent.cpp       \
                   SupplicantConnectionTimeoutEvent.cpp \
                   SupplicantDisconnectedEvent.cpp      \
-                  SupplicantStatus.cpp
+                  SupplicantStatus.cpp                 \
+                  TiwlanEventListener.cpp
 
 LOCAL_MODULE:= nexus
 
diff --git a/nexus/SupplicantAssociatingEvent.cpp b/nexus/SupplicantAssociatingEvent.cpp
index 00a85b6..c6e9fe3 100644
--- a/nexus/SupplicantAssociatingEvent.cpp
+++ b/nexus/SupplicantAssociatingEvent.cpp
@@ -29,6 +29,7 @@
 
     mBssid = NULL;
     mSsid = NULL;
+    mFreq = -1;
 
     // SSID 'default' 
     // OR
diff --git a/nexus/SupplicantStatus.cpp b/nexus/SupplicantStatus.cpp
index 87f6c98..b3c560a 100644
--- a/nexus/SupplicantStatus.cpp
+++ b/nexus/SupplicantStatus.cpp
@@ -17,7 +17,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define LOG_TAG "SupplicantState"
+#define LOG_TAG "SupplicantStatus"
 #include <cutils/log.h>
 
 #include "SupplicantStatus.h"
@@ -52,18 +52,37 @@
     char *next = data;
     char *line;
     while((line = strsep(&next, "\n"))) {
-        char *token = strsep(&next, "=");
-        char *value = strsep(&next, "=");
-
+        char *line_next =  line;
+        char *token = strsep(&line_next, "=");
+        char *value = strsep(&line_next, "=");
         if (!strcmp(token, "bssid"))
             bssid = strdup(value);
         else if (!strcmp(token, "ssid"))
             ssid = strdup(value);
         else if (!strcmp(token, "id"))
             id = atoi(value);
-        else if (!strcmp(token, "wpa_state"))
-            state = atoi(value);
-        else
+        else if (!strcmp(token, "wpa_state")) {
+            if (!strcmp(value, "DISCONNECTED"))
+                state = SupplicantState::DISCONNECTED;
+            else if (!strcmp(value, "INACTIVE"))
+                state = SupplicantState::INACTIVE;
+            else if (!strcmp(value, "SCANNING"))
+                state = SupplicantState::SCANNING;
+            else if (!strcmp(value, "ASSOCIATING"))
+                state = SupplicantState::ASSOCIATING;
+            else if (!strcmp(value, "ASSOCIATED"))
+                state = SupplicantState::ASSOCIATED;
+            else if (!strcmp(value, "FOURWAY_HANDSHAKE"))
+                state = SupplicantState::FOURWAY_HANDSHAKE;
+            else if (!strcmp(value, "GROUP_HANDSHAKE"))
+                state = SupplicantState::GROUP_HANDSHAKE;
+            else if (!strcmp(value, "COMPLETED"))
+                state = SupplicantState::COMPLETED;
+            else if (!strcmp(value, "IDLE"))
+                state = SupplicantState::IDLE;
+            else 
+                LOGE("Unknown supplicant state '%s'", value);
+        } else
             LOGD("Ignoring unsupported status token '%s'", token);
     }
 
diff --git a/nexus/TiwlanEventListener.cpp b/nexus/TiwlanEventListener.cpp
new file mode 100644
index 0000000..15e6930
--- /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) {
+        LOGW("Low signal/noise ratio");
+    } else if (data->event_type == IPC_EVENT_LOW_RSSI) {
+        LOGW("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 @@
                                            char *modargs) :
                       WifiController(propmngr, handlers, modpath, modname,
                                      modargs) {
+    mEventListener = NULL;
+    mListenerSock = -1;
 }
 
 int TiwlanWifiController::powerUp() {
@@ -43,6 +49,13 @@
 }
 
 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 @@
     // 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 @@
     virtual bool isPoweredUp();
     virtual int loadFirmware();
     virtual bool isFirmwareLoaded();
+
+private:
+    int startDriverEventListener();
 };
 #endif
diff --git a/nexus/WifiController.cpp b/nexus/WifiController.cpp
index 5c5db1a..b7bd6ed 100644
--- a/nexus/WifiController.cpp
+++ b/nexus/WifiController.cpp
@@ -69,7 +69,9 @@
 }
 
 int WifiController::enable() {
+
     if (!isPoweredUp()) {
+        LOGI("Powering up");
         sendStatusBroadcast("Powering up WiFi hardware");
         if (powerUp()) {
             LOGE("Powerup failed (%s)", strerror(errno));
@@ -78,6 +80,7 @@
     }
 
     if (mModuleName[0] != '\0' && !isKernelModuleLoaded(mModuleName)) {
+        LOGI("Loading driver");
         sendStatusBroadcast("Loading WiFi driver");
         if (loadKernelModule(mModulePath, mModuleArgs)) {
             LOGE("Kernel module load failed (%s)", strerror(errno));
@@ -86,6 +89,7 @@
     }
 
     if (!isFirmwareLoaded()) {
+        LOGI("Loading firmware");
         sendStatusBroadcast("Loading WiFI firmware");
         if (loadFirmware()) {
             LOGE("Firmware load failed (%s)", strerror(errno));
@@ -94,6 +98,7 @@
     }
 
     if (!mSupplicant->isStarted()) {
+        LOGI("Starting WPA Supplicant");
         sendStatusBroadcast("Starting WPA Supplicant");
         if (mSupplicant->start()) {
             LOGE("Supplicant start failed (%s)", strerror(errno));
@@ -113,6 +118,7 @@
     mPropMngr->registerProperty("wifi.scanmode", this);
     mPropMngr->registerProperty("wifi.interface", this);
 
+    LOGI("Enabled successfully");
     return 0;
 
 out_unloadmodule:
diff --git a/rootdir/init.rc b/rootdir/init.rc
index cf7d885..47acd15 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -51,7 +51,7 @@
     mkdir /dev/cpuctl/bg_non_interactive
     chown system system /dev/cpuctl/bg_non_interactive/tasks
     chmod 0777 /dev/cpuctl/bg_non_interactive/tasks
-    write /dev/cpuctl/bg_non_interactive/cpu.shares 1
+    write /dev/cpuctl/bg_non_interactive/cpu.shares 16
 
 # mount mtd partitions
     # Mount /system rw first to give the filesystem a chance to save a checkpoint