1dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat/* 2dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * Copyright (C) 2008 The Android Open Source Project 3dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * 4dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * you may not use this file except in compliance with the License. 6dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * You may obtain a copy of the License at 7dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * 8dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * http://www.apache.org/licenses/LICENSE-2.0 9dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * 10dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * Unless required by applicable law or agreed to in writing, software 11dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * See the License for the specific language governing permissions and 14dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat * limitations under the License. 15dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat */ 161441e769b2767e212a3d905bee2fd3535b484ff2San Mehat 171441e769b2767e212a3d905bee2fd3535b484ff2San Mehat#include <stdlib.h> 1869772dc644e1ccc12b6394267f010100470f3c95San Mehat#include <sys/types.h> 1969772dc644e1ccc12b6394267f010100470f3c95San Mehat#include <fcntl.h> 20dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include <errno.h> 21dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 22dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#define LOG_TAG "Supplicant" 23dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include <cutils/log.h> 24dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include <cutils/properties.h> 25dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 2669772dc644e1ccc12b6394267f010100470f3c95San Mehat#include "private/android_filesystem_config.h" 2769772dc644e1ccc12b6394267f010100470f3c95San Mehat 285d6d417972f8d946c223c4efb9636b1ba4280543San Mehat#include <sysutils/ServiceManager.h> 29dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 30dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include "Supplicant.h" 31dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include "SupplicantListener.h" 321441e769b2767e212a3d905bee2fd3535b484ff2San Mehat#include "NetworkManager.h" 333c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat#include "WifiController.h" 343aff2d1de59972684bf2ab798351be5544158239San Mehat#include "SupplicantStatus.h" 35dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 36dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#include "libwpa_client/wpa_ctrl.h" 37dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 38dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#define IFACE_DIR "/data/system/wpa_supplicant" 39dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat#define DRIVER_PROP_NAME "wlan.driver.status" 405d6d417972f8d946c223c4efb9636b1ba4280543San Mehat#define SUPPLICANT_SERVICE_NAME "wpa_supplicant" 4169772dc644e1ccc12b6394267f010100470f3c95San Mehat#define SUPP_CONFIG_TEMPLATE "/system/etc/wifi/wpa_supplicant.conf" 4269772dc644e1ccc12b6394267f010100470f3c95San Mehat#define SUPP_CONFIG_FILE "/data/misc/wifi/wpa_supplicant.conf" 4369772dc644e1ccc12b6394267f010100470f3c95San Mehat 443aff2d1de59972684bf2ab798351be5544158239San MehatSupplicant::Supplicant(WifiController *wc, ISupplicantEventHandler *handlers) { 453aff2d1de59972684bf2ab798351be5544158239San Mehat mHandlers = handlers; 463c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat mController = wc; 473c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat mInterfaceName = NULL; 48dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat mCtrl = NULL; 49dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat mMonitor = NULL; 50dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat mListener = NULL; 513c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 525d6d417972f8d946c223c4efb9636b1ba4280543San Mehat mServiceManager = new ServiceManager(); 53dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 543c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat mNetworks = new WifiNetworkCollection(); 553c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat pthread_mutex_init(&mNetworksLock, NULL); 56dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat} 57dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 585d6d417972f8d946c223c4efb9636b1ba4280543San MehatSupplicant::~Supplicant() { 595d6d417972f8d946c223c4efb9636b1ba4280543San Mehat delete mServiceManager; 603c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (mInterfaceName) 613c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat free(mInterfaceName); 625d6d417972f8d946c223c4efb9636b1ba4280543San Mehat} 635d6d417972f8d946c223c4efb9636b1ba4280543San Mehat 64dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatint Supplicant::start() { 6569772dc644e1ccc12b6394267f010100470f3c95San Mehat 6669772dc644e1ccc12b6394267f010100470f3c95San Mehat if (setupConfig()) { 6769772dc644e1ccc12b6394267f010100470f3c95San Mehat LOGW("Unable to setup supplicant.conf"); 6869772dc644e1ccc12b6394267f010100470f3c95San Mehat } 693c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 705d6d417972f8d946c223c4efb9636b1ba4280543San Mehat if (mServiceManager->start(SUPPLICANT_SERVICE_NAME)) { 715d6d417972f8d946c223c4efb9636b1ba4280543San Mehat LOGE("Error starting supplicant (%s)", strerror(errno)); 725d6d417972f8d946c223c4efb9636b1ba4280543San Mehat return -1; 73dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 74dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 751441e769b2767e212a3d905bee2fd3535b484ff2San Mehat wpa_ctrl_cleanup(); 76dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat if (connectToSupplicant()) { 77dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat LOGE("Error connecting to supplicant (%s)\n", strerror(errno)); 78dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 79dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 803c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 813c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (retrieveInterfaceName()) { 823c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat LOGE("Error retrieving interface name (%s)\n", strerror(errno)); 833c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return -1; 843c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 853c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 86dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return 0; 87dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat} 88dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 89dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatint Supplicant::stop() { 90dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 91dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat if (mListener->stopListener()) { 92dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat LOGW("Unable to stop supplicant listener (%s)", strerror(errno)); 93dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 94dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 95dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 965d6d417972f8d946c223c4efb9636b1ba4280543San Mehat if (mServiceManager->stop(SUPPLICANT_SERVICE_NAME)) { 975d6d417972f8d946c223c4efb9636b1ba4280543San Mehat LOGW("Error stopping supplicant (%s)", strerror(errno)); 98dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 99dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 100dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat if (mCtrl) { 101dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat wpa_ctrl_close(mCtrl); 102dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat mCtrl = NULL; 103dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 104dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat if (mMonitor) { 105dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat wpa_ctrl_close(mMonitor); 106dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat mMonitor = NULL; 107dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 108dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 109dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return 0; 110dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat} 111dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 112dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehatbool Supplicant::isStarted() { 1135d6d417972f8d946c223c4efb9636b1ba4280543San Mehat return mServiceManager->isRunning(SUPPLICANT_SERVICE_NAME); 114dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat} 115dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 116c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::sendCommand(const char *cmd, char *reply, size_t *reply_len) { 117c4a895b7094461c98101924cf096680bfb7856f1San Mehat 118c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (!mCtrl) { 119c4a895b7094461c98101924cf096680bfb7856f1San Mehat errno = ENOTCONN; 120c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 121c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 122c4a895b7094461c98101924cf096680bfb7856f1San Mehat 123c4a895b7094461c98101924cf096680bfb7856f1San Mehat// LOGD("sendCommand(): -> '%s'", cmd); 124c4a895b7094461c98101924cf096680bfb7856f1San Mehat 125c4a895b7094461c98101924cf096680bfb7856f1San Mehat int rc; 126c4a895b7094461c98101924cf096680bfb7856f1San Mehat memset(reply, 0, *reply_len); 127c4a895b7094461c98101924cf096680bfb7856f1San Mehat if ((rc = wpa_ctrl_request(mCtrl, cmd, strlen(cmd), reply, reply_len, NULL)) == -2) { 128c4a895b7094461c98101924cf096680bfb7856f1San Mehat errno = ETIMEDOUT; 129c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 130c4a895b7094461c98101924cf096680bfb7856f1San Mehat } else if (rc < 0 || !strncmp(reply, "FAIL", 4)) { 131c4a895b7094461c98101924cf096680bfb7856f1San Mehat strcpy(reply, "FAIL"); 132c4a895b7094461c98101924cf096680bfb7856f1San Mehat errno = EIO; 133c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 134c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 135c4a895b7094461c98101924cf096680bfb7856f1San Mehat 136c4a895b7094461c98101924cf096680bfb7856f1San Mehat // LOGD("sendCommand(): <- '%s'", reply); 137c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 138c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 1393aff2d1de59972684bf2ab798351be5544158239San MehatSupplicantStatus *Supplicant::getStatus() { 1403aff2d1de59972684bf2ab798351be5544158239San Mehat char *reply; 1413aff2d1de59972684bf2ab798351be5544158239San Mehat size_t len = 4096; 1423aff2d1de59972684bf2ab798351be5544158239San Mehat 1433aff2d1de59972684bf2ab798351be5544158239San Mehat if (!(reply = (char *) malloc(len))) { 1443aff2d1de59972684bf2ab798351be5544158239San Mehat errno = ENOMEM; 1453aff2d1de59972684bf2ab798351be5544158239San Mehat return NULL; 1463aff2d1de59972684bf2ab798351be5544158239San Mehat } 1473aff2d1de59972684bf2ab798351be5544158239San Mehat 1483aff2d1de59972684bf2ab798351be5544158239San Mehat if (sendCommand("STATUS", reply, &len)) { 1493aff2d1de59972684bf2ab798351be5544158239San Mehat free(reply); 1503aff2d1de59972684bf2ab798351be5544158239San Mehat return NULL; 1513aff2d1de59972684bf2ab798351be5544158239San Mehat } 1523aff2d1de59972684bf2ab798351be5544158239San Mehat 1533aff2d1de59972684bf2ab798351be5544158239San Mehat SupplicantStatus *ss = SupplicantStatus::createStatus(reply, len); 1543aff2d1de59972684bf2ab798351be5544158239San Mehat 1553aff2d1de59972684bf2ab798351be5544158239San Mehat free (reply); 1563aff2d1de59972684bf2ab798351be5544158239San Mehat return ss; 1573aff2d1de59972684bf2ab798351be5544158239San Mehat} 1583aff2d1de59972684bf2ab798351be5544158239San Mehat 1593aff2d1de59972684bf2ab798351be5544158239San Mehat/* 1603aff2d1de59972684bf2ab798351be5544158239San Mehat * Retrieves the list of networks from Supplicant 1613aff2d1de59972684bf2ab798351be5544158239San Mehat * and merge them into our current list 1623aff2d1de59972684bf2ab798351be5544158239San Mehat */ 1633c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehatint Supplicant::refreshNetworkList() { 1643c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char *reply; 1653c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat size_t len = 4096; 1663c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 1673c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (!(reply = (char *) malloc(len))) { 1683c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat errno = ENOMEM; 1693c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return -1; 1703c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 1713c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 1723c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (sendCommand("LIST_NETWORKS", reply, &len)) { 1733c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat free(reply); 174dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 175dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 176dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 1773c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char *linep; 1783c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char *linep_next = NULL; 1793c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 1803c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (!strtok_r(reply, "\n", &linep_next)) { 1813c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat LOGW("Malformatted network list\n"); 1823aff2d1de59972684bf2ab798351be5544158239San Mehat free(reply); 1833aff2d1de59972684bf2ab798351be5544158239San Mehat errno = EIO; 1843aff2d1de59972684bf2ab798351be5544158239San Mehat return -1; 1853aff2d1de59972684bf2ab798351be5544158239San Mehat } 1863c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 187c4a895b7094461c98101924cf096680bfb7856f1San Mehat PropertyManager *pm = NetworkManager::Instance()->getPropMngr(); 1883aff2d1de59972684bf2ab798351be5544158239San Mehat pthread_mutex_lock(&mNetworksLock); 1893aff2d1de59972684bf2ab798351be5544158239San Mehat 1903aff2d1de59972684bf2ab798351be5544158239San Mehat int num_added = 0; 1913aff2d1de59972684bf2ab798351be5544158239San Mehat int num_refreshed = 0; 1923aff2d1de59972684bf2ab798351be5544158239San Mehat int num_removed = 0; 1933aff2d1de59972684bf2ab798351be5544158239San Mehat while((linep = strtok_r(NULL, "\n", &linep_next))) { 1943aff2d1de59972684bf2ab798351be5544158239San Mehat // TODO: Move the decode into a static method so we 1953aff2d1de59972684bf2ab798351be5544158239San Mehat // don't create new_wn when we don't have to. 1963aff2d1de59972684bf2ab798351be5544158239San Mehat WifiNetwork *new_wn = new WifiNetwork(mController, this, linep); 1973aff2d1de59972684bf2ab798351be5544158239San Mehat WifiNetwork *merge_wn; 1983aff2d1de59972684bf2ab798351be5544158239San Mehat 1993aff2d1de59972684bf2ab798351be5544158239San Mehat if ((merge_wn = this->lookupNetwork_UNLOCKED(new_wn->getNetworkId()))) { 2003aff2d1de59972684bf2ab798351be5544158239San Mehat num_refreshed++; 2013aff2d1de59972684bf2ab798351be5544158239San Mehat if (merge_wn->refresh()) { 2023aff2d1de59972684bf2ab798351be5544158239San Mehat LOGW("Error refreshing network %d (%s)", 2033aff2d1de59972684bf2ab798351be5544158239San Mehat merge_wn->getNetworkId(), strerror(errno)); 2043aff2d1de59972684bf2ab798351be5544158239San Mehat } 2053aff2d1de59972684bf2ab798351be5544158239San Mehat delete new_wn; 2063aff2d1de59972684bf2ab798351be5544158239San Mehat } else { 2073aff2d1de59972684bf2ab798351be5544158239San Mehat num_added++; 208c4a895b7094461c98101924cf096680bfb7856f1San Mehat char new_ns[20]; 209c4a895b7094461c98101924cf096680bfb7856f1San Mehat snprintf(new_ns, sizeof(new_ns), "wifi.net.%d", new_wn->getNetworkId()); 210c4a895b7094461c98101924cf096680bfb7856f1San Mehat new_wn->attachProperties(pm, new_ns); 2113aff2d1de59972684bf2ab798351be5544158239San Mehat mNetworks->push_back(new_wn); 2123aff2d1de59972684bf2ab798351be5544158239San Mehat if (new_wn->refresh()) { 2133aff2d1de59972684bf2ab798351be5544158239San Mehat LOGW("Unable to refresh network id %d (%s)", 2143aff2d1de59972684bf2ab798351be5544158239San Mehat new_wn->getNetworkId(), strerror(errno)); 2153aff2d1de59972684bf2ab798351be5544158239San Mehat } 2163c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 2173aff2d1de59972684bf2ab798351be5544158239San Mehat } 2183c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 2193aff2d1de59972684bf2ab798351be5544158239San Mehat if (!mNetworks->empty()) { 2203aff2d1de59972684bf2ab798351be5544158239San Mehat // TODO: Add support for detecting removed networks 2213aff2d1de59972684bf2ab798351be5544158239San Mehat WifiNetworkCollection::iterator i; 2223aff2d1de59972684bf2ab798351be5544158239San Mehat 2233aff2d1de59972684bf2ab798351be5544158239San Mehat for (i = mNetworks->begin(); i != mNetworks->end(); ++i) { 2243aff2d1de59972684bf2ab798351be5544158239San Mehat if (0) { 2253aff2d1de59972684bf2ab798351be5544158239San Mehat num_removed++; 226c4a895b7094461c98101924cf096680bfb7856f1San Mehat char del_ns[20]; 227c4a895b7094461c98101924cf096680bfb7856f1San Mehat snprintf(del_ns, sizeof(del_ns), "wifi.net.%d", (*i)->getNetworkId()); 228c4a895b7094461c98101924cf096680bfb7856f1San Mehat (*i)->detachProperties(pm, del_ns); 2293aff2d1de59972684bf2ab798351be5544158239San Mehat delete (*i); 2303aff2d1de59972684bf2ab798351be5544158239San Mehat i = mNetworks->erase(i); 2313aff2d1de59972684bf2ab798351be5544158239San Mehat } 2323aff2d1de59972684bf2ab798351be5544158239San Mehat } 2333c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 2343c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 2353aff2d1de59972684bf2ab798351be5544158239San Mehat 2363aff2d1de59972684bf2ab798351be5544158239San Mehat LOGD("Networks added %d, refreshed %d, removed %d\n", 2373aff2d1de59972684bf2ab798351be5544158239San Mehat num_added, num_refreshed, num_removed); 2383aff2d1de59972684bf2ab798351be5544158239San Mehat pthread_mutex_unlock(&mNetworksLock); 2393aff2d1de59972684bf2ab798351be5544158239San Mehat 2403c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat free(reply); 2413c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return 0; 2423c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat} 2433c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 2443c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehatint Supplicant::connectToSupplicant() { 2453c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (!isStarted()) 2463c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat LOGW("Supplicant service not running"); 2473c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 2483c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat mCtrl = wpa_ctrl_open("tiwlan0"); // XXX: 249dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat if (mCtrl == NULL) { 250dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat LOGE("Unable to open connection to supplicant on \"%s\": %s", 251dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat "tiwlan0", strerror(errno)); 252dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 253dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 254dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat mMonitor = wpa_ctrl_open("tiwlan0"); 255dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat if (mMonitor == NULL) { 256dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat wpa_ctrl_close(mCtrl); 257dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat mCtrl = NULL; 258dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 259dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 260dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat if (wpa_ctrl_attach(mMonitor) != 0) { 261dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat wpa_ctrl_close(mMonitor); 262dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat wpa_ctrl_close(mCtrl); 263dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat mCtrl = mMonitor = NULL; 264dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 265dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 266dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 2673aff2d1de59972684bf2ab798351be5544158239San Mehat mListener = new SupplicantListener(mHandlers, mMonitor); 2683c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 269dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat if (mListener->startListener()) { 270dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat LOGE("Error - unable to start supplicant listener"); 271dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat stop(); 272dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 273dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 274dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return 0; 275dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat} 276dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 277c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::setScanMode(bool active) { 278c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[255]; 279c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len = sizeof(reply); 280c4a895b7094461c98101924cf096680bfb7856f1San Mehat 281c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand((active ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE"), 282c4a895b7094461c98101924cf096680bfb7856f1San Mehat reply, &len)) { 283c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGW("triggerScan(%d): Error setting scan mode (%s)", active, 284c4a895b7094461c98101924cf096680bfb7856f1San Mehat strerror(errno)); 285dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 286dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 287c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 288c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 289dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 290c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::triggerScan() { 291c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[255]; 292c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len = sizeof(reply); 293dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 294c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("SCAN", reply, &len)) { 295c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGW("triggerScan(): Error initiating scan"); 296dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 297c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 298c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 299c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 300c4a895b7094461c98101924cf096680bfb7856f1San Mehat 301c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::getRssi(int *buffer) { 302c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[64]; 303c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len = sizeof(reply); 304c4a895b7094461c98101924cf096680bfb7856f1San Mehat 305c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("DRIVER RSSI", reply, &len)) { 306c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGW("Failed to get RSSI (%s)", strerror(errno)); 307dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 308dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 309dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 310c4a895b7094461c98101924cf096680bfb7856f1San Mehat char *next = reply; 311c4a895b7094461c98101924cf096680bfb7856f1San Mehat char *s; 312c4a895b7094461c98101924cf096680bfb7856f1San Mehat for (int i = 0; i < 3; i++) { 313c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (!(s = strsep(&next, " "))) { 314c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGE("Error parsing RSSI"); 315c4a895b7094461c98101924cf096680bfb7856f1San Mehat errno = EIO; 316c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 317c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 318c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 319c4a895b7094461c98101924cf096680bfb7856f1San Mehat *buffer = atoi(s); 320dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return 0; 321dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat} 322dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 323c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::getLinkSpeed() { 324c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[64]; 325dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat size_t len = sizeof(reply); 326dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 327c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("DRIVER LINKSPEED", reply, &len)) { 328c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGW("Failed to get LINKSPEED (%s)", strerror(errno)); 329dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 330dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 331dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 332c4a895b7094461c98101924cf096680bfb7856f1San Mehat char *next = reply; 333c4a895b7094461c98101924cf096680bfb7856f1San Mehat char *s; 334c4a895b7094461c98101924cf096680bfb7856f1San Mehat 335c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (!(s = strsep(&next, " "))) { 336c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGE("Error parsing LINKSPEED"); 337c4a895b7094461c98101924cf096680bfb7856f1San Mehat errno = EIO; 338c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 339c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 340c4a895b7094461c98101924cf096680bfb7856f1San Mehat 341c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (!(s = strsep(&next, " "))) { 342c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGE("Error parsing LINKSPEED"); 343c4a895b7094461c98101924cf096680bfb7856f1San Mehat errno = EIO; 344c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 345c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 346c4a895b7094461c98101924cf096680bfb7856f1San Mehat return atoi(s); 347c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 348c4a895b7094461c98101924cf096680bfb7856f1San Mehat 349c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::stopDriver() { 350c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[64]; 351c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len = sizeof(reply); 352c4a895b7094461c98101924cf096680bfb7856f1San Mehat 353c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGD("stopDriver()"); 354c4a895b7094461c98101924cf096680bfb7856f1San Mehat 355c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("DRIVER STOP", reply, &len)) { 356c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGW("Failed to stop driver (%s)", strerror(errno)); 357c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 358c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 359c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 360c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 361c4a895b7094461c98101924cf096680bfb7856f1San Mehat 362c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::startDriver() { 363c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[64]; 364c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len = sizeof(reply); 365c4a895b7094461c98101924cf096680bfb7856f1San Mehat 366c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGD("startDriver()"); 367c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("DRIVER START", reply, &len)) { 368c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGW("Failed to start driver (%s)", strerror(errno)); 369dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return -1; 370dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat } 371dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat return 0; 372dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat} 373dc266073e7c3127caedf26671a1c125dc8aadd8dSan Mehat 3743c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San MehatWifiNetwork *Supplicant::createNetwork() { 3753c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char reply[255]; 37682a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat size_t len = sizeof(reply) -1; 37782a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat 37882a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat if (sendCommand("ADD_NETWORK", reply, &len)) 3793c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return NULL; 3803c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 3813c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (reply[strlen(reply) -1] == '\n') 3823c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat reply[strlen(reply) -1] = '\0'; 38382a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat 3843c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat WifiNetwork *wn = new WifiNetwork(mController, this, atoi(reply)); 385c4a895b7094461c98101924cf096680bfb7856f1San Mehat PropertyManager *pm = NetworkManager::Instance()->getPropMngr(); 3863c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat pthread_mutex_lock(&mNetworksLock); 387c4a895b7094461c98101924cf096680bfb7856f1San Mehat char new_ns[20]; 388c4a895b7094461c98101924cf096680bfb7856f1San Mehat snprintf(new_ns, sizeof(new_ns), "wifi.net.%d", wn->getNetworkId()); 389c4a895b7094461c98101924cf096680bfb7856f1San Mehat wn->attachProperties(pm, new_ns); 3903c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat mNetworks->push_back(wn); 3913c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat pthread_mutex_unlock(&mNetworksLock); 3923c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return wn; 39382a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat} 39482a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat 3953c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehatint Supplicant::removeNetwork(WifiNetwork *wn) { 39682a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat char req[64]; 39782a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat 3983c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat sprintf(req, "REMOVE_NETWORK %d", wn->getNetworkId()); 39982a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat char reply[32]; 40082a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat size_t len = sizeof(reply) -1; 4013c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 40282a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat if (sendCommand(req, reply, &len)) 40382a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat return -1; 4043c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 4053c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat pthread_mutex_lock(&mNetworksLock); 4063c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat WifiNetworkCollection::iterator it; 4073c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat for (it = mNetworks->begin(); it != mNetworks->end(); ++it) { 4083c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if ((*it) == wn) { 4093c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat mNetworks->erase(it); 4103c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat break; 4113c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 4123c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 4133c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat pthread_mutex_unlock(&mNetworksLock); 41482a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat return 0; 41582a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat} 41682a2116e6b67db910bba22c4874e6ca5efd3eec0San Mehat 4173c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San MehatWifiNetwork *Supplicant::lookupNetwork(int networkId) { 4183c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat pthread_mutex_lock(&mNetworksLock); 4193aff2d1de59972684bf2ab798351be5544158239San Mehat WifiNetwork *wn = lookupNetwork_UNLOCKED(networkId); 4203aff2d1de59972684bf2ab798351be5544158239San Mehat pthread_mutex_unlock(&mNetworksLock); 4213aff2d1de59972684bf2ab798351be5544158239San Mehat return wn; 4223aff2d1de59972684bf2ab798351be5544158239San Mehat} 4233aff2d1de59972684bf2ab798351be5544158239San Mehat 4243aff2d1de59972684bf2ab798351be5544158239San MehatWifiNetwork *Supplicant::lookupNetwork_UNLOCKED(int networkId) { 4253c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat WifiNetworkCollection::iterator it; 4263c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat for (it = mNetworks->begin(); it != mNetworks->end(); ++it) { 4273c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if ((*it)->getNetworkId() == networkId) { 4283c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return *it; 4293c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 4303c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 4313c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat errno = ENOENT; 4323c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return NULL; 4333c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat} 4343c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 4353c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San MehatWifiNetworkCollection *Supplicant::createNetworkList() { 4363c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat WifiNetworkCollection *d = new WifiNetworkCollection(); 4373c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat WifiNetworkCollection::iterator i; 4383c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 4393c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat pthread_mutex_lock(&mNetworksLock); 4403c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat for (i = mNetworks->begin(); i != mNetworks->end(); ++i) 4413c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat d->push_back((*i)->clone()); 4423c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 4433c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat pthread_mutex_unlock(&mNetworksLock); 4443c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return d; 4453c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat} 4463c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 44769772dc644e1ccc12b6394267f010100470f3c95San Mehatint Supplicant::setupConfig() { 44869772dc644e1ccc12b6394267f010100470f3c95San Mehat char buf[2048]; 44969772dc644e1ccc12b6394267f010100470f3c95San Mehat int srcfd, destfd; 45069772dc644e1ccc12b6394267f010100470f3c95San Mehat int nread; 45169772dc644e1ccc12b6394267f010100470f3c95San Mehat 45269772dc644e1ccc12b6394267f010100470f3c95San Mehat if (access(SUPP_CONFIG_FILE, R_OK|W_OK) == 0) { 45369772dc644e1ccc12b6394267f010100470f3c95San Mehat return 0; 45469772dc644e1ccc12b6394267f010100470f3c95San Mehat } else if (errno != ENOENT) { 45569772dc644e1ccc12b6394267f010100470f3c95San Mehat LOGE("Cannot access \"%s\": %s", SUPP_CONFIG_FILE, strerror(errno)); 45669772dc644e1ccc12b6394267f010100470f3c95San Mehat return -1; 45769772dc644e1ccc12b6394267f010100470f3c95San Mehat } 45869772dc644e1ccc12b6394267f010100470f3c95San Mehat 45969772dc644e1ccc12b6394267f010100470f3c95San Mehat srcfd = open(SUPP_CONFIG_TEMPLATE, O_RDONLY); 46069772dc644e1ccc12b6394267f010100470f3c95San Mehat if (srcfd < 0) { 46169772dc644e1ccc12b6394267f010100470f3c95San Mehat LOGE("Cannot open \"%s\": %s", SUPP_CONFIG_TEMPLATE, strerror(errno)); 46269772dc644e1ccc12b6394267f010100470f3c95San Mehat return -1; 46369772dc644e1ccc12b6394267f010100470f3c95San Mehat } 46469772dc644e1ccc12b6394267f010100470f3c95San Mehat 46569772dc644e1ccc12b6394267f010100470f3c95San Mehat destfd = open(SUPP_CONFIG_FILE, O_CREAT|O_WRONLY, 0660); 46669772dc644e1ccc12b6394267f010100470f3c95San Mehat if (destfd < 0) { 46769772dc644e1ccc12b6394267f010100470f3c95San Mehat close(srcfd); 46869772dc644e1ccc12b6394267f010100470f3c95San Mehat LOGE("Cannot create \"%s\": %s", SUPP_CONFIG_FILE, strerror(errno)); 46969772dc644e1ccc12b6394267f010100470f3c95San Mehat return -1; 47069772dc644e1ccc12b6394267f010100470f3c95San Mehat } 47169772dc644e1ccc12b6394267f010100470f3c95San Mehat 47269772dc644e1ccc12b6394267f010100470f3c95San Mehat while ((nread = read(srcfd, buf, sizeof(buf))) != 0) { 47369772dc644e1ccc12b6394267f010100470f3c95San Mehat if (nread < 0) { 47469772dc644e1ccc12b6394267f010100470f3c95San Mehat LOGE("Error reading \"%s\": %s", SUPP_CONFIG_TEMPLATE, strerror(errno)); 47569772dc644e1ccc12b6394267f010100470f3c95San Mehat close(srcfd); 47669772dc644e1ccc12b6394267f010100470f3c95San Mehat close(destfd); 47769772dc644e1ccc12b6394267f010100470f3c95San Mehat unlink(SUPP_CONFIG_FILE); 47869772dc644e1ccc12b6394267f010100470f3c95San Mehat return -1; 47969772dc644e1ccc12b6394267f010100470f3c95San Mehat } 48069772dc644e1ccc12b6394267f010100470f3c95San Mehat write(destfd, buf, nread); 48169772dc644e1ccc12b6394267f010100470f3c95San Mehat } 48269772dc644e1ccc12b6394267f010100470f3c95San Mehat 48369772dc644e1ccc12b6394267f010100470f3c95San Mehat close(destfd); 48469772dc644e1ccc12b6394267f010100470f3c95San Mehat close(srcfd); 48569772dc644e1ccc12b6394267f010100470f3c95San Mehat 48669772dc644e1ccc12b6394267f010100470f3c95San Mehat if (chown(SUPP_CONFIG_FILE, AID_SYSTEM, AID_WIFI) < 0) { 48769772dc644e1ccc12b6394267f010100470f3c95San Mehat LOGE("Error changing group ownership of %s to %d: %s", 48869772dc644e1ccc12b6394267f010100470f3c95San Mehat SUPP_CONFIG_FILE, AID_WIFI, strerror(errno)); 48969772dc644e1ccc12b6394267f010100470f3c95San Mehat unlink(SUPP_CONFIG_FILE); 49069772dc644e1ccc12b6394267f010100470f3c95San Mehat return -1; 49169772dc644e1ccc12b6394267f010100470f3c95San Mehat } 49269772dc644e1ccc12b6394267f010100470f3c95San Mehat return 0; 49369772dc644e1ccc12b6394267f010100470f3c95San Mehat} 4943c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 4953c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehatint Supplicant::setNetworkVar(int networkId, const char *var, const char *val) { 4963c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char reply[255]; 4973c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat size_t len = sizeof(reply) -1; 4983c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 499c4a895b7094461c98101924cf096680bfb7856f1San Mehat LOGD("netid %d, var '%s' = '%s'", networkId, var, val); 5003c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char *tmp; 501c4a895b7094461c98101924cf096680bfb7856f1San Mehat asprintf(&tmp, "SET_NETWORK %d %s %s", networkId, var, val); 5023c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (sendCommand(tmp, reply, &len)) { 5033c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat free(tmp); 5043c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return -1; 5053c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 5063c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat free(tmp); 5073aff2d1de59972684bf2ab798351be5544158239San Mehat 5083aff2d1de59972684bf2ab798351be5544158239San Mehat len = sizeof(reply) -1; 5093aff2d1de59972684bf2ab798351be5544158239San Mehat if (sendCommand("SAVE_CONFIG", reply, &len)) { 5103aff2d1de59972684bf2ab798351be5544158239San Mehat LOGE("Error saving config after %s = %s", var, val); 5113aff2d1de59972684bf2ab798351be5544158239San Mehat return -1; 5123aff2d1de59972684bf2ab798351be5544158239San Mehat } 5133c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return 0; 5143c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat} 5153c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 5163c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehatconst char *Supplicant::getNetworkVar(int networkId, const char *var, 5173c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char *buffer, size_t max) { 5183c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat size_t len = max - 1; 5193c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char *tmp; 5203c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 5213c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat asprintf(&tmp, "GET_NETWORK %d %s", networkId, var); 5223c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (sendCommand(tmp, buffer, &len)) { 5233c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat free(tmp); 5243c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return NULL; 5253c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat } 5263c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat free(tmp); 5273c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return buffer; 5283c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat} 5293c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 5303c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehatint Supplicant::enableNetwork(int networkId, bool enabled) { 5313c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char req[64]; 5323c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 5333c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (enabled) 5343c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat sprintf(req, "ENABLE_NETWORK %d", networkId); 5353c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat else 5363c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat sprintf(req, "DISABLE_NETWORK %d", networkId); 5373c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 5383c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char reply[16]; 5393c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat size_t len = sizeof(reply) -1; 5403c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 5413c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (sendCommand(req, reply, &len)) 5423c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return -1; 5433c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return 0; 5443c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat} 5453c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 546c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::enablePacketFilter() { 547c4a895b7094461c98101924cf096680bfb7856f1San Mehat char req[128]; 548c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[16]; 549c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len; 550c4a895b7094461c98101924cf096680bfb7856f1San Mehat int i; 551c4a895b7094461c98101924cf096680bfb7856f1San Mehat 552c4a895b7094461c98101924cf096680bfb7856f1San Mehat for (i = 0; i <=3; i++) { 553c4a895b7094461c98101924cf096680bfb7856f1San Mehat snprintf(req, sizeof(req), "DRIVER RXFILTER-ADD %d", i); 554c4a895b7094461c98101924cf096680bfb7856f1San Mehat len = sizeof(reply); 555c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand(req, reply, &len)) 556c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 557c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 558c4a895b7094461c98101924cf096680bfb7856f1San Mehat 559c4a895b7094461c98101924cf096680bfb7856f1San Mehat len = sizeof(reply); 560c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("DRIVER RXFILTER-START", reply, &len)) 561c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 562c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 563c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 564c4a895b7094461c98101924cf096680bfb7856f1San Mehat 565c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::disablePacketFilter() { 566c4a895b7094461c98101924cf096680bfb7856f1San Mehat char req[128]; 567c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[16]; 568c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len; 569c4a895b7094461c98101924cf096680bfb7856f1San Mehat int i; 570c4a895b7094461c98101924cf096680bfb7856f1San Mehat 571c4a895b7094461c98101924cf096680bfb7856f1San Mehat len = sizeof(reply); 572c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("DRIVER RXFILTER-STOP", reply, &len)) 573c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 574c4a895b7094461c98101924cf096680bfb7856f1San Mehat 575c4a895b7094461c98101924cf096680bfb7856f1San Mehat for (i = 3; i >=0; i--) { 576c4a895b7094461c98101924cf096680bfb7856f1San Mehat snprintf(req, sizeof(req), "DRIVER RXFILTER-REMOVE %d", i); 577c4a895b7094461c98101924cf096680bfb7856f1San Mehat len = sizeof(reply); 578c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand(req, reply, &len)) 579c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 580c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 581c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 582c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 583c4a895b7094461c98101924cf096680bfb7856f1San Mehat 584c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::enableBluetoothCoexistenceScan() { 585c4a895b7094461c98101924cf096680bfb7856f1San Mehat char req[128]; 586c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[16]; 587c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len; 588c4a895b7094461c98101924cf096680bfb7856f1San Mehat int i; 589c4a895b7094461c98101924cf096680bfb7856f1San Mehat 590c4a895b7094461c98101924cf096680bfb7856f1San Mehat len = sizeof(reply); 591c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("DRIVER BTCOEXSCAN-START", reply, &len)) 592c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 593c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 594c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 595c4a895b7094461c98101924cf096680bfb7856f1San Mehat 596c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::disableBluetoothCoexistenceScan() { 597c4a895b7094461c98101924cf096680bfb7856f1San Mehat char req[128]; 598c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[16]; 599c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len; 600c4a895b7094461c98101924cf096680bfb7856f1San Mehat int i; 601c4a895b7094461c98101924cf096680bfb7856f1San Mehat 602c4a895b7094461c98101924cf096680bfb7856f1San Mehat len = sizeof(reply); 603c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("DRIVER BTCOEXSCAN-STOP", reply, &len)) 604c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 605c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 606c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 607c4a895b7094461c98101924cf096680bfb7856f1San Mehat 608c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::setBluetoothCoexistenceMode(int mode) { 609c4a895b7094461c98101924cf096680bfb7856f1San Mehat char req[64]; 610c4a895b7094461c98101924cf096680bfb7856f1San Mehat 611c4a895b7094461c98101924cf096680bfb7856f1San Mehat sprintf(req, "DRIVER BTCOEXMODE %d", mode); 612c4a895b7094461c98101924cf096680bfb7856f1San Mehat 613c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[16]; 614c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len = sizeof(reply) -1; 615c4a895b7094461c98101924cf096680bfb7856f1San Mehat 616c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand(req, reply, &len)) 617c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 618c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 619c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 620c4a895b7094461c98101924cf096680bfb7856f1San Mehat 621c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::setApScanMode(int mode) { 622c4a895b7094461c98101924cf096680bfb7856f1San Mehat char req[64]; 623c4a895b7094461c98101924cf096680bfb7856f1San Mehat 624c4a895b7094461c98101924cf096680bfb7856f1San Mehat// LOGD("setApScanMode(%d)", mode); 625c4a895b7094461c98101924cf096680bfb7856f1San Mehat sprintf(req, "AP_SCAN %d", mode); 626c4a895b7094461c98101924cf096680bfb7856f1San Mehat 627c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[16]; 628c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len = sizeof(reply) -1; 629c4a895b7094461c98101924cf096680bfb7856f1San Mehat 630c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand(req, reply, &len)) 631c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 632c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 633c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 634c4a895b7094461c98101924cf096680bfb7856f1San Mehat 6353c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 6363c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehatint Supplicant::retrieveInterfaceName() { 6373c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat char reply[255]; 6383c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat size_t len = sizeof(reply) -1; 6393c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 6403c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat if (sendCommand("INTERFACES", reply, &len)) 6413c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return -1; 6423c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat 6433c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat reply[strlen(reply)-1] = '\0'; 6443c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat mInterfaceName = strdup(reply); 6453c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat return 0; 6463c5a6f0bc8aefc4dacab8e95ba9017a7ac7d91f5San Mehat} 647c4a895b7094461c98101924cf096680bfb7856f1San Mehat 648c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::reconnect() { 649c4a895b7094461c98101924cf096680bfb7856f1San Mehat char req[128]; 650c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[16]; 651c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len; 652c4a895b7094461c98101924cf096680bfb7856f1San Mehat int i; 653c4a895b7094461c98101924cf096680bfb7856f1San Mehat 654c4a895b7094461c98101924cf096680bfb7856f1San Mehat len = sizeof(reply); 655c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("RECONNECT", reply, &len)) 656c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 657c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 658c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 659c4a895b7094461c98101924cf096680bfb7856f1San Mehat 660c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::disconnect() { 661c4a895b7094461c98101924cf096680bfb7856f1San Mehat char req[128]; 662c4a895b7094461c98101924cf096680bfb7856f1San Mehat char reply[16]; 663c4a895b7094461c98101924cf096680bfb7856f1San Mehat size_t len; 664c4a895b7094461c98101924cf096680bfb7856f1San Mehat int i; 665c4a895b7094461c98101924cf096680bfb7856f1San Mehat 666c4a895b7094461c98101924cf096680bfb7856f1San Mehat len = sizeof(reply); 667c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (sendCommand("DISCONNECT", reply, &len)) 668c4a895b7094461c98101924cf096680bfb7856f1San Mehat return -1; 669c4a895b7094461c98101924cf096680bfb7856f1San Mehat return 0; 670c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 671c4a895b7094461c98101924cf096680bfb7856f1San Mehat 672c4a895b7094461c98101924cf096680bfb7856f1San Mehatint Supplicant::getNetworkCount() { 673c4a895b7094461c98101924cf096680bfb7856f1San Mehat pthread_mutex_lock(&mNetworksLock); 674c4a895b7094461c98101924cf096680bfb7856f1San Mehat int cnt = mNetworks->size(); 675c4a895b7094461c98101924cf096680bfb7856f1San Mehat pthread_mutex_unlock(&mNetworksLock); 676c4a895b7094461c98101924cf096680bfb7856f1San Mehat return cnt; 677c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 678