Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fc4129f authored by San Mehat's avatar San Mehat
Browse files

nexus: Add TiwlanEventListener for reading driver events directly



Signed-off-by: default avatarSan Mehat <san@google.com>
parent 43c16197
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
/*
 * 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;
}
+55 −0
Original line number Diff line number Diff line
/*
 * 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
+54 −2
Original line number Diff line number Diff line
@@ -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,15 +73,54 @@ 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() {
+7 −0
Original line number Diff line number Diff line
@@ -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