SoftapController.cpp revision 54cf7fda69c3c442e7d2ac370a9c942fdb38dcd7
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/socket.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/ioctl.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/wait.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netinet/in.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <arpa/inet.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/wireless.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <openssl/evp.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <openssl/sha.h> 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "SoftapController" 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/log.h> 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netutils/ifc.h> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "wifi.h" 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SoftapController.h" 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSoftapController::SoftapController() { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPid = 0; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSock = socket(AF_INET, SOCK_DGRAM, 0); 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSock < 0) 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Failed to open socket"); 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(mIface, 0, sizeof(mIface)); 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSoftapController::~SoftapController() { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSock >= 0) 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(mSock); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SoftapController::setCommand(char *iface, const char *fname, unsigned buflen) { 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_HOSTAPD 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char tBuf[SOFTAP_MAX_BUFFER_SIZE]; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct iwreq wrq; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct iw_priv_args *priv_ptr; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i, j, ret; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cmd = 0, sub_cmd = 0; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strncpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name)); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wrq.u.data.pointer = tBuf; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wrq.u.data.length = sizeof(tBuf) / sizeof(struct iw_priv_args); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wrq.u.data.flags = 0; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((ret = ioctl(mSock, SIOCGIWPRIV, &wrq)) < 0) { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("SIOCGIPRIV failed: %d", ret); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project priv_ptr = (struct iw_priv_args *)wrq.u.data.pointer; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(i=0; i < wrq.u.data.length;i++) { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcmp(priv_ptr[i].name, fname) == 0) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmd = priv_ptr[i].cmd; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == wrq.u.data.length) { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("iface:%s, fname: %s - function not supported", iface, fname); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cmd < SIOCDEVPRIVATE) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(j=0; j < i; j++) { 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((priv_ptr[j].set_args == priv_ptr[i].set_args) && 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (priv_ptr[j].get_args == priv_ptr[i].get_args) && 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (priv_ptr[j].name[0] == '\0')) 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (j == i) { 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("iface:%s, fname: %s - invalid private ioctl", iface, fname); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sub_cmd = cmd; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmd = priv_ptr[j].cmd; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strncpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name)); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((buflen == 0) && (*mBuf != 0)) 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wrq.u.data.length = strlen(mBuf) + 1; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wrq.u.data.length = buflen; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wrq.u.data.pointer = mBuf; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wrq.u.data.flags = sub_cmd; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = ioctl(mSock, cmd, &wrq); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SoftapController::startDriver(char *iface) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSock < 0) { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap driver start - failed to open socket"); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!iface || (iface[0] == '\0')) { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Softap driver start - wrong interface"); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iface = mIface; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *mBuf = 0; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setCommand(iface, "START"); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap driver start: %d", ret); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_HOSTAPD 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ifc_init(); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = ifc_up(iface); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ifc_close(); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project usleep(AP_DRIVER_START_DELAY); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Softap driver start: %d", ret); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SoftapController::stopDriver(char *iface) { 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSock < 0) { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap driver stop - failed to open socket"); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!iface || (iface[0] == '\0')) { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Softap driver stop - wrong interface"); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iface = mIface; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *mBuf = 0; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_HOSTAPD 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ifc_init(); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = ifc_down(iface); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ifc_close(); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret < 0) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap %s down: %d", iface, ret); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setCommand(iface, "STOP"); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Softap driver stop: %d", ret); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SoftapController::startSoftap() { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pid_t pid = 1; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret = 0; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPid) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap already started"); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSock < 0) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap startap - failed to open socket"); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_HOSTAPD 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((pid = fork()) < 0) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("fork failed (%s)", strerror(errno)); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!pid) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_HOSTAPD 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (execl("/system/bin/hostapd", "/system/bin/hostapd", "-B", 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "/data/misc/wifi/hostapd.conf", (char *) NULL)) { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("execl failed (%s)", strerror(errno)); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Should never get here!"); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *mBuf = 0; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setCommand(mIface, "AP_BSS_START"); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap startap - failed: %d", ret); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPid = pid; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Softap startap - Ok"); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project usleep(AP_BSS_START_DELAY); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SoftapController::stopSoftap() { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPid == 0) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap already stopped"); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_HOSTAPD 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Stopping Softap service"); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kill(mPid, SIGTERM); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitpid(mPid, NULL, 0); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSock < 0) { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap stopap - failed to open socket"); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *mBuf = 0; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setCommand(mIface, "AP_BSS_STOP"); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPid = 0; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Softap service stopped: %d", ret); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project usleep(AP_BSS_STOP_DELAY); 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool SoftapController::isSoftapStarted() { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mPid != 0 ? true : false); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SoftapController::addParam(int pos, const char *cmd, const char *arg) 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos < 0) 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pos; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((unsigned)(pos + strlen(cmd) + strlen(arg) + 1) >= sizeof(mBuf)) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Command line is too big"); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos += sprintf(&mBuf[pos], "%s=%s,", cmd, arg); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pos; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Arguments: 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[2] - wlan interface 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[3] - softap interface 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[4] - SSID 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[5] - Security 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[6] - Key 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[7] - Channel 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[8] - Preamble 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[9] - Max SCB 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SoftapController::setSoftap(int argc, char *argv[]) { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char psk[SHA256_DIGEST_LENGTH]; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char psk_str[2*SHA256_DIGEST_LENGTH+1]; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret, i = 0; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char *ssid, *iface; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSock < 0) { 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap set - failed to open socket"); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argc < 4) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap set - missing arguments"); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strncpy(mIface, argv[3], sizeof(mIface)); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iface = argv[2]; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Create command line */ 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "ASCII_CMD", "AP_CFG"); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argc > 4) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssid = argv[4]; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssid = (char *)"AndroidAP"; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "SSID", ssid); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argc > 5) { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "SEC", argv[5]); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "SEC", "open"); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argc > 6) { 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int j; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Use the PKCS#5 PBKDF2 with 4096 iterations 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PKCS5_PBKDF2_HMAC_SHA1(argv[6], strlen(argv[6]), 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reinterpret_cast<const unsigned char *>(ssid), strlen(ssid), 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4096, SHA256_DIGEST_LENGTH, psk); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (j=0; j < SHA256_DIGEST_LENGTH; j++) { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(&psk_str[j<<1], "%02x", psk[j]); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project psk_str[j<<1] = '\0'; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "KEY", psk_str); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "KEY", "12345678"); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argc > 7) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "CHANNEL", argv[7]); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "CHANNEL", "6"); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argc > 8) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "PREAMBLE", argv[8]); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "PREAMBLE", "0"); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argc > 9) { 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "MAX_SCB", argv[9]); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = addParam(i, "MAX_SCB", "8"); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((i < 0) || ((unsigned)(i + 4) >= sizeof(mBuf))) { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap set - command is too big"); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return i; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(&mBuf[i], "END"); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* system("iwpriv eth0 WL_AP_CFG ASCII_CMD=AP_CFG,SSID=\"AndroidAP\",SEC=\"open\",KEY=12345,CHANNEL=1,PREAMBLE=0,MAX_SCB=8,END"); */ 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setCommand(iface, "AP_SET_CFG"); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap set - failed: %d", ret); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Softap set - Ok"); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project usleep(AP_SET_CFG_DELAY); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Arguments: 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[2] - interface name 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * argv[3] - AP or STA 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SoftapController::fwReloadSoftap(int argc, char *argv[]) 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret, i = 0; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char *iface; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char *fwpath; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSock < 0) { 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap fwrealod - failed to open socket"); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argc < 4) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap fwreload - missing arguments"); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iface = argv[2]; 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcmp(argv[3], "AP") == 0) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_AP); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (strcmp(argv[3], "P2P") == 0) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_P2P); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_STA); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!fwpath) 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_HOSTAPD 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = wifi_change_fw_path((const char *)fwpath); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(mBuf, "FW_PATH=%s", fwpath); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setCommand(iface, "WL_FW_RELOAD"); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap fwReload - failed: %d", ret); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Softap fwReload - Ok"); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint SoftapController::clientsSoftap(char **retbuf) 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSock < 0) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap clients - failed to open socket"); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *mBuf = 0; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = setCommand(mIface, "AP_GET_STA_LIST", SOFTAP_MAX_BUFFER_SIZE); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret) { 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Softap clients - failed: %d", ret); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asprintf(retbuf, "Softap clients:%s", mBuf); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("Softap clients:%s", mBuf); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project