wifi.c revision ed8487244b1c9f72fb5d22c7a18918ac34063cee
1cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project/* 2cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * Copyright 2008, The Android Open Source Project 3cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * 4cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * you may not use this file except in compliance with the License. 6cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * You may obtain a copy of the License at 7cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * 8cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * 10cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * See the License for the specific language governing permissions and 14cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * limitations under the License. 15cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project */ 16cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 17cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <stdlib.h> 18cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <fcntl.h> 19cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <errno.h> 20cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <string.h> 21cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 22cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include "hardware_legacy/wifi.h" 23cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include "libwpa_client/wpa_ctrl.h" 24cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 25cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#define LOG_TAG "WifiHW" 26cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include "cutils/log.h" 27cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include "cutils/memory.h" 28cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include "cutils/misc.h" 29cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include "cutils/properties.h" 30cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include "private/android_filesystem_config.h" 31cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#ifdef HAVE_LIBC_SYSTEM_PROPERTIES 32cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ 33cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <sys/_system_properties.h> 34cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#endif 35cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 36cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic struct wpa_ctrl *ctrl_conn; 37cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic struct wpa_ctrl *monitor_conn; 38cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 39cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectextern int do_dhcp(); 40cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectextern int ifc_init(); 41cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectextern void ifc_close(); 42cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectextern char *dhcp_lasterror(); 43cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectextern void get_dhcp_info(); 44cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectextern int init_module(void *, unsigned long, const char *); 45cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectextern int delete_module(const char *, unsigned int); 46cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 47cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic char iface[PROPERTY_VALUE_MAX]; 48cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project// TODO: use new ANDROID_SOCKET mechanism, once support for multiple 49cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project// sockets is in 50cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 51243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#ifndef WIFI_DRIVER_MODULE_PATH 52243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#define WIFI_DRIVER_MODULE_PATH "/system/lib/modules/wlan.ko" 53243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#endif 54243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#ifndef WIFI_DRIVER_MODULE_NAME 55243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#define WIFI_DRIVER_MODULE_NAME "wlan" 56243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#endif 57243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#ifndef WIFI_DRIVER_MODULE_ARG 58243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#define WIFI_DRIVER_MODULE_ARG "" 59243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#endif 60243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#ifndef WIFI_FIRMWARE_LOADER 61243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#define WIFI_FIRMWARE_LOADER "" 62243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#endif 63243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt#define WIFI_TEST_INTERFACE "sta" 64243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt 65ed8487244b1c9f72fb5d22c7a18918ac34063ceeDmitry Shmidt#define WIFI_DRIVER_LOADER_DELAY 1000000 66ed8487244b1c9f72fb5d22c7a18918ac34063ceeDmitry Shmidt 67cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic const char IFACE_DIR[] = "/data/system/wpa_supplicant"; 68243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidtstatic const char DRIVER_MODULE_NAME[] = WIFI_DRIVER_MODULE_NAME; 69243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidtstatic const char DRIVER_MODULE_TAG[] = WIFI_DRIVER_MODULE_NAME " "; 70243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidtstatic const char DRIVER_MODULE_PATH[] = WIFI_DRIVER_MODULE_PATH; 71243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidtstatic const char DRIVER_MODULE_ARG[] = WIFI_DRIVER_MODULE_ARG; 72243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidtstatic const char FIRMWARE_LOADER[] = WIFI_FIRMWARE_LOADER; 73cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic const char DRIVER_PROP_NAME[] = "wlan.driver.status"; 74cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic const char SUPPLICANT_NAME[] = "wpa_supplicant"; 75cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic const char SUPP_PROP_NAME[] = "init.svc.wpa_supplicant"; 76cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic const char SUPP_CONFIG_TEMPLATE[]= "/system/etc/wifi/wpa_supplicant.conf"; 77cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic const char SUPP_CONFIG_FILE[] = "/data/misc/wifi/wpa_supplicant.conf"; 78cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic const char MODULE_FILE[] = "/proc/modules"; 79cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 80243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidtstatic int insmod(const char *filename, const char *args) 81cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 82cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project void *module; 83cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project unsigned int size; 84cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int ret; 85cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 86cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project module = load_file(filename, &size); 87cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (!module) 88cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 89cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 90243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt ret = init_module(module, size, args); 91cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 92cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project free(module); 93cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 94cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return ret; 95cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 96cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 97cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic int rmmod(const char *modname) 98cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 99cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int ret = -1; 100cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int maxtry = 10; 101cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 102cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project while (maxtry-- > 0) { 103cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ret = delete_module(modname, O_NONBLOCK | O_EXCL); 104cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ret < 0 && errno == EAGAIN) 105cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project usleep(500000); 106cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project else 107cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project break; 108cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 109cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 110cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ret != 0) 111cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGD("Unable to unload driver module \"%s\": %s\n", 112cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project modname, strerror(errno)); 113cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return ret; 114cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 115cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 116cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint do_dhcp_request(int *ipaddr, int *gateway, int *mask, 117cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int *dns1, int *dns2, int *server, int *lease) { 118cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* For test driver, always report success */ 119243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt if (strcmp(iface, WIFI_TEST_INTERFACE) == 0) 120cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 121cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 122cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ifc_init() < 0) 123cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 124cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 125cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (do_dhcp(iface) < 0) { 126cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ifc_close(); 127cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 128cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 129cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ifc_close(); 130cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project get_dhcp_info(ipaddr, gateway, mask, dns1, dns2, server, lease); 131cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 132cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 133cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 134cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectconst char *get_dhcp_error_string() { 135cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return dhcp_lasterror(); 136cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 137cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 138cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic int check_driver_loaded() { 139cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char driver_status[PROPERTY_VALUE_MAX]; 140cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project FILE *proc; 141cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char line[sizeof(DRIVER_MODULE_TAG)+10]; 142cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 143cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (!property_get(DRIVER_PROP_NAME, driver_status, NULL) 144cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project || strcmp(driver_status, "ok") != 0) { 145cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; /* driver not loaded */ 146cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 147cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* 148cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * If the property says the driver is loaded, check to 149cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * make sure that the property setting isn't just left 150cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * over from a previous manual shutdown or a runtime 151cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * crash. 152cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project */ 153cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if ((proc = fopen(MODULE_FILE, "r")) == NULL) { 154cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGW("Could not open %s: %s", MODULE_FILE, strerror(errno)); 155243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt property_set(DRIVER_PROP_NAME, "unloaded"); 156cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 157cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 158cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project while ((fgets(line, sizeof(line), proc)) != NULL) { 159cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (strncmp(line, DRIVER_MODULE_TAG, strlen(DRIVER_MODULE_TAG)) == 0) { 160cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project fclose(proc); 161cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 1; 162cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 163cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 164cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project fclose(proc); 165cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project property_set(DRIVER_PROP_NAME, "unloaded"); 166cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 167cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 168cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 169cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint wifi_load_driver() 170cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 171cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char driver_status[PROPERTY_VALUE_MAX]; 172cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int count = 100; /* wait at most 20 seconds for completion */ 173cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 174cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (check_driver_loaded()) { 175cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 176cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 177cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 178243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) 179cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 180243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt 181243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt if (strcmp(FIRMWARE_LOADER,"") == 0) { 182ed8487244b1c9f72fb5d22c7a18918ac34063ceeDmitry Shmidt usleep(WIFI_DRIVER_LOADER_DELAY); 183243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt property_set(DRIVER_PROP_NAME, "ok"); 184243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt } 185243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt else { 186243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt property_set("ctl.start", FIRMWARE_LOADER); 187243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt } 188cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project sched_yield(); 189cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project while (count-- > 0) { 190cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) { 191cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (strcmp(driver_status, "ok") == 0) 192cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 1937b43699180e593b19092eb2a091c4bca105aca77Dmitry Shmidt else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) { 1947b43699180e593b19092eb2a091c4bca105aca77Dmitry Shmidt wifi_unload_driver(); 195cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 1967b43699180e593b19092eb2a091c4bca105aca77Dmitry Shmidt } 197cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 198cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project usleep(200000); 199cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 200cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project property_set(DRIVER_PROP_NAME, "timeout"); 2017b43699180e593b19092eb2a091c4bca105aca77Dmitry Shmidt wifi_unload_driver(); 202cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 203cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 204cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 205cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint wifi_unload_driver() 206cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 207cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int count = 20; /* wait at most 10 seconds for completion */ 208243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt 209cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (rmmod(DRIVER_MODULE_NAME) == 0) { 210cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project while (count-- > 0) { 211cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (!check_driver_loaded()) 212cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project break; 213cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project usleep(500000); 214cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 215cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (count) { 216cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 217cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 218cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 219cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } else 220cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 221cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 222cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 223cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint ensure_config_file_exists() 224cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 225cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char buf[2048]; 226cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int srcfd, destfd; 227cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int nread; 228cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 229cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (access(SUPP_CONFIG_FILE, R_OK|W_OK) == 0) { 230cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 231cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } else if (errno != ENOENT) { 232cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGE("Cannot access \"%s\": %s", SUPP_CONFIG_FILE, strerror(errno)); 233cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 234cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 235cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 236cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project srcfd = open(SUPP_CONFIG_TEMPLATE, O_RDONLY); 237cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (srcfd < 0) { 238cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGE("Cannot open \"%s\": %s", SUPP_CONFIG_TEMPLATE, strerror(errno)); 239cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 240cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 241cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 242cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project destfd = open(SUPP_CONFIG_FILE, O_CREAT|O_WRONLY, 0660); 243cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (destfd < 0) { 244cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project close(srcfd); 245cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGE("Cannot create \"%s\": %s", SUPP_CONFIG_FILE, strerror(errno)); 246cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 247cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 248cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 249cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project while ((nread = read(srcfd, buf, sizeof(buf))) != 0) { 250cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (nread < 0) { 251cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGE("Error reading \"%s\": %s", SUPP_CONFIG_TEMPLATE, strerror(errno)); 252cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project close(srcfd); 253cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project close(destfd); 254cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project unlink(SUPP_CONFIG_FILE); 255cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 256cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 257cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project write(destfd, buf, nread); 258cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 259cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 260cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project close(destfd); 261cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project close(srcfd); 262cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 263cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (chown(SUPP_CONFIG_FILE, AID_SYSTEM, AID_WIFI) < 0) { 264cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGE("Error changing group ownership of %s to %d: %s", 265cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project SUPP_CONFIG_FILE, AID_WIFI, strerror(errno)); 266cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project unlink(SUPP_CONFIG_FILE); 267cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 268cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 269cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 270cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 271cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 272cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint wifi_start_supplicant() 273cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 274cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char supp_status[PROPERTY_VALUE_MAX] = {'\0'}; 275cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int count = 200; /* wait at most 20 seconds for completion */ 276cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#ifdef HAVE_LIBC_SYSTEM_PROPERTIES 277cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project const prop_info *pi; 278cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project unsigned serial = 0; 279cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#endif 280cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 281cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* Check whether already running */ 282cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (property_get(SUPP_PROP_NAME, supp_status, NULL) 283cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project && strcmp(supp_status, "running") == 0) { 284cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 285cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 286cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 287cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* Before starting the daemon, make sure its config file exists */ 288cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ensure_config_file_exists() < 0) { 289cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGE("Wi-Fi will not be enabled"); 290cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 291cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 292cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 293cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* Clear out any stale socket files that might be left over. */ 294cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project wpa_ctrl_cleanup(); 295cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 296cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#ifdef HAVE_LIBC_SYSTEM_PROPERTIES 297cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* 298cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * Get a reference to the status property, so we can distinguish 299cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * the case where it goes stopped => running => stopped (i.e., 300cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * it start up, but fails right away) from the case in which 301cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * it starts in the stopped state and never manages to start 302cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * running at all. 303cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project */ 304cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project pi = __system_property_find(SUPP_PROP_NAME); 305cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (pi != NULL) { 306cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project serial = pi->serial; 307cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 308cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#endif 309cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project property_set("ctl.start", SUPPLICANT_NAME); 310cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project sched_yield(); 311cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 312cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project while (count-- > 0) { 313007404c68f5cf6328e30b6d0edac3fd52ef36abbDmitry Shmidt#ifdef HAVE_LIBC_SYSTEM_PROPERTIES 314cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (pi == NULL) { 315cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project pi = __system_property_find(SUPP_PROP_NAME); 316cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 317cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (pi != NULL) { 318cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project __system_property_read(pi, NULL, supp_status); 319cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (strcmp(supp_status, "running") == 0) { 320cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 321cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } else if (pi->serial != serial && 322cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project strcmp(supp_status, "stopped") == 0) { 323cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 324cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 325cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 326cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#else 327cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (property_get(SUPP_PROP_NAME, supp_status, NULL)) { 328cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (strcmp(supp_status, "running") == 0) 329cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 330cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 331cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#endif 332cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project usleep(100000); 333cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 334cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 335cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 336cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 337cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint wifi_stop_supplicant() 338cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 339cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char supp_status[PROPERTY_VALUE_MAX] = {'\0'}; 340cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int count = 50; /* wait at most 5 seconds for completion */ 341cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 342cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* Check whether supplicant already stopped */ 343cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (property_get(SUPP_PROP_NAME, supp_status, NULL) 344cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project && strcmp(supp_status, "stopped") == 0) { 345cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 346cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 347cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 348cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project property_set("ctl.stop", SUPPLICANT_NAME); 349cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project sched_yield(); 350cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 351cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project while (count-- > 0) { 352cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (property_get(SUPP_PROP_NAME, supp_status, NULL)) { 353cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (strcmp(supp_status, "stopped") == 0) 354cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 355cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 356cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project usleep(100000); 357cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 358cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 359cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 360cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 361cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint wifi_connect_to_supplicant() 362cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 363cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char ifname[256]; 364cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char supp_status[PROPERTY_VALUE_MAX] = {'\0'}; 365cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 366cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* Make sure supplicant is running */ 367cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (!property_get(SUPP_PROP_NAME, supp_status, NULL) 368cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project || strcmp(supp_status, "running") != 0) { 369cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGE("Supplicant not running, cannot connect"); 370cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 371cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 372cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 373243af8b84968ec4f5afb628c43a2c541c4feee7bDmitry Shmidt property_get("wifi.interface", iface, WIFI_TEST_INTERFACE); 374cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 375cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (access(IFACE_DIR, F_OK) == 0) { 376cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project snprintf(ifname, sizeof(ifname), "%s/%s", IFACE_DIR, iface); 377cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } else { 378cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project strlcpy(ifname, iface, sizeof(ifname)); 379cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 380cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 381cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ctrl_conn = wpa_ctrl_open(ifname); 382cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ctrl_conn == NULL) { 383cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGE("Unable to open connection to supplicant on \"%s\": %s", 384cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ifname, strerror(errno)); 385cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 386cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 387cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project monitor_conn = wpa_ctrl_open(ifname); 388cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (monitor_conn == NULL) { 389cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project wpa_ctrl_close(ctrl_conn); 390cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ctrl_conn = NULL; 391cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 392cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 393cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (wpa_ctrl_attach(monitor_conn) != 0) { 394cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project wpa_ctrl_close(monitor_conn); 395cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project wpa_ctrl_close(ctrl_conn); 396cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ctrl_conn = monitor_conn = NULL; 397cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 398cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 399cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 400cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 401cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 402cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint wifi_send_command(struct wpa_ctrl *ctrl, const char *cmd, char *reply, size_t *reply_len) 403cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 404cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int ret; 405cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 406cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ctrl_conn == NULL) { 407cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGV("Not connected to wpa_supplicant - \"%s\" command dropped.\n", cmd); 408cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 409cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 410cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL); 411cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ret == -2) { 412cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGD("'%s' command timed out.\n", cmd); 413cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -2; 414cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) { 415cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 416cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 417cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (strncmp(cmd, "PING", 4) == 0) { 418cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project reply[*reply_len] = '\0'; 419cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 420cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 421cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 422cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 423cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint wifi_wait_for_event(char *buf, size_t buflen) 424cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 425cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project size_t nread = buflen - 1; 426cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int fd; 427cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project fd_set rfds; 428cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int result; 429cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project struct timeval tval; 430cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project struct timeval *tptr; 431cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 4322631f993753d726c8c6a85ab66a83db79e54f0bbIrfan Sheriff if (monitor_conn == NULL) { 433007404c68f5cf6328e30b6d0edac3fd52ef36abbDmitry Shmidt LOGD("Connection closed\n"); 4342631f993753d726c8c6a85ab66a83db79e54f0bbIrfan Sheriff strncpy(buf, WPA_EVENT_TERMINATING " - connection closed", buflen-1); 4352631f993753d726c8c6a85ab66a83db79e54f0bbIrfan Sheriff buf[buflen-1] = '\0'; 4362631f993753d726c8c6a85ab66a83db79e54f0bbIrfan Sheriff return strlen(buf); 4372631f993753d726c8c6a85ab66a83db79e54f0bbIrfan Sheriff } 438cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 439cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project result = wpa_ctrl_recv(monitor_conn, buf, &nread); 440cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (result < 0) { 441cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGD("wpa_ctrl_recv failed: %s\n", strerror(errno)); 4422631f993753d726c8c6a85ab66a83db79e54f0bbIrfan Sheriff strncpy(buf, WPA_EVENT_TERMINATING " - recv error", buflen-1); 4432631f993753d726c8c6a85ab66a83db79e54f0bbIrfan Sheriff buf[buflen-1] = '\0'; 4442631f993753d726c8c6a85ab66a83db79e54f0bbIrfan Sheriff return strlen(buf); 445cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 446cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project buf[nread] = '\0'; 447cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* LOGD("wait_for_event: result=%d nread=%d string=\"%s\"\n", result, nread, buf); */ 448cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* Check for EOF on the socket */ 449cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (result == 0 && nread == 0) { 450cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* Fabricate an event to pass up */ 451cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project LOGD("Received EOF on supplicant socket\n"); 452cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project strncpy(buf, WPA_EVENT_TERMINATING " - signal 0 received", buflen-1); 453cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project buf[buflen-1] = '\0'; 454cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return strlen(buf); 455cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 456cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* 457cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * Events strings are in the format 458cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * 459cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * <N>CTRL-EVENT-XXX 460cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * 461cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG, 462cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * etc.) and XXX is the event name. The level information is not useful 463cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * to us, so strip it off. 464cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project */ 465cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (buf[0] == '<') { 466cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char *match = strchr(buf, '>'); 467cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (match != NULL) { 468cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project nread -= (match+1-buf); 469cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project memmove(buf, match+1, nread+1); 470cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 471cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 472cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return nread; 473cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 474cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 475cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectvoid wifi_close_supplicant_connection() 476cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 477cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ctrl_conn != NULL) { 478cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project wpa_ctrl_close(ctrl_conn); 479cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ctrl_conn = NULL; 480cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 481cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (monitor_conn != NULL) { 482cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project wpa_ctrl_close(monitor_conn); 483cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project monitor_conn = NULL; 484cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 485cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 486cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 487cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint wifi_command(const char *command, char *reply, size_t *reply_len) 488cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 489cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return wifi_send_command(ctrl_conn, command, reply, reply_len); 490cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 491