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