Home | History | Annotate | Download | only in nexus
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdlib.h>
     18 #include <fcntl.h>
     19 #include <errno.h>
     20 #include <string.h>
     21 #include <sys/types.h>
     22 #include <sys/socket.h>
     23 #include <arpa/inet.h>
     24 
     25 #include <cutils/properties.h>
     26 #define LOG_TAG "TiwlanWifiController"
     27 #include <cutils/log.h>
     28 
     29 #include "PropertyManager.h"
     30 #include "TiwlanWifiController.h"
     31 #include "TiwlanEventListener.h"
     32 
     33 #define DRIVER_PROP_NAME "wlan.driver.status"
     34 
     35 extern "C" int sched_yield(void);
     36 
     37 TiwlanWifiController::TiwlanWifiController(PropertyManager *propmngr,
     38                                            IControllerHandler *handlers,
     39                                            char *modpath, char *modname,
     40                                            char *modargs) :
     41                       WifiController(propmngr, handlers, modpath, modname,
     42                                      modargs) {
     43     mEventListener = NULL;
     44     mListenerSock = -1;
     45 }
     46 
     47 int TiwlanWifiController::powerUp() {
     48     return 0; // Powerup is currently done when the driver is loaded
     49 }
     50 
     51 int TiwlanWifiController::powerDown() {
     52     if (mEventListener) {
     53         delete mEventListener;
     54         shutdown(mListenerSock, SHUT_RDWR);
     55         close(mListenerSock);
     56         mListenerSock = -1;
     57         mEventListener = NULL;
     58     }
     59 
     60     return 0; // Powerdown is currently done when the driver is unloaded
     61 }
     62 
     63 bool TiwlanWifiController::isPoweredUp() {
     64     return isKernelModuleLoaded(getModuleName());
     65 }
     66 
     67 int TiwlanWifiController::loadFirmware() {
     68     char driver_status[PROPERTY_VALUE_MAX];
     69     int count = 100;
     70 
     71     property_set("ctl.start", "wlan_loader");
     72     sched_yield();
     73 
     74     // Wait for driver to be ready
     75     while (count-- > 0) {
     76         if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
     77             if (!strcmp(driver_status, "ok")) {
     78                 LOGD("Firmware loaded OK");
     79 
     80                 if (startDriverEventListener()) {
     81                     LOGW("Failed to start driver event listener (%s)",
     82                          strerror(errno));
     83                 }
     84 
     85                 return 0;
     86             } else if (!strcmp(DRIVER_PROP_NAME, "failed")) {
     87                 LOGE("Firmware load failed");
     88                 return -1;
     89             }
     90         }
     91         usleep(200000);
     92     }
     93     property_set(DRIVER_PROP_NAME, "timeout");
     94     LOGE("Firmware load timed out");
     95     return -1;
     96 }
     97 
     98 int TiwlanWifiController::startDriverEventListener() {
     99     struct sockaddr_in addr;
    100 
    101     if (mListenerSock != -1) {
    102         LOGE("Listener already started!");
    103         errno = EBUSY;
    104         return -1;
    105     }
    106 
    107     if ((mListenerSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    108         LOGE("socket failed (%s)", strerror(errno));
    109         return -1;
    110     }
    111 
    112     memset(&addr, 0, sizeof(addr));
    113     addr.sin_family = AF_INET;
    114     addr.sin_addr.s_addr = htonl(INADDR_ANY);
    115     addr.sin_port = htons(TI_DRIVER_MSG_PORT);
    116 
    117     if (bind(mListenerSock,
    118              (struct sockaddr *) &addr,
    119              sizeof(addr)) < 0) {
    120         LOGE("bind failed (%s)", strerror(errno));
    121         goto out_err;
    122     }
    123 
    124     mEventListener = new TiwlanEventListener(mListenerSock);
    125 
    126     if (mEventListener->startListener()) {
    127         LOGE("Error starting driver listener (%s)", strerror(errno));
    128         goto out_err;
    129     }
    130     return 0;
    131 out_err:
    132     if (mEventListener) {
    133         delete mEventListener;
    134         mEventListener = NULL;
    135     }
    136     if (mListenerSock != -1) {
    137         shutdown(mListenerSock, SHUT_RDWR);
    138         close(mListenerSock);
    139         mListenerSock = -1;
    140     }
    141     return -1;
    142 }
    143 
    144 bool TiwlanWifiController::isFirmwareLoaded() {
    145     // Always load the firmware
    146     return false;
    147 }
    148