SoftapController.cpp revision 84c65a62fe7b053fed7f20274ca7379627a87b79
15af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt/* 25af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * Copyright (C) 2008 The Android Open Source Project 35af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * 45af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License"); 55af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * you may not use this file except in compliance with the License. 65af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * You may obtain a copy of the License at 75af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * 85af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * http://www.apache.org/licenses/LICENSE-2.0 95af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * 105af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * Unless required by applicable law or agreed to in writing, software 115af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS, 125af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * See the License for the specific language governing permissions and 145af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt * limitations under the License. 155af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt */ 165af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 175af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <stdlib.h> 185af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <errno.h> 195af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <fcntl.h> 205af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 215af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <sys/socket.h> 225af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <sys/stat.h> 235af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <sys/types.h> 245af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <sys/wait.h> 255af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 265af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <netinet/in.h> 275af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <arpa/inet.h> 285af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 2984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt#include <linux/wireless.h> 3084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt 315af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#define LOG_TAG "SoftapController" 325af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include <cutils/log.h> 335af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 345af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#include "SoftapController.h" 355af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 365af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtSoftapController::SoftapController() { 375af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt mPid = 0; 3884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt mSock = socket(AF_INET, SOCK_DGRAM, 0); 3984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (mSock < 0) 4084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Failed to open socket"); 4184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt memset(mIface, 0, sizeof(mIface)); 425af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt} 435af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 445af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry ShmidtSoftapController::~SoftapController() { 4584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (mSock >= 0) 4684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt close(mSock); 4784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt} 4884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt 4984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidtint SoftapController::getPrivFuncNum(char *iface, const char *fname) { 5084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt struct iwreq wrq; 5184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt struct iw_priv_args *priv_ptr; 5284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt int i, ret; 5384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt 5484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt strncpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name)); 5584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.pointer = mBuf; 5684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.length = sizeof(mBuf) / sizeof(struct iw_priv_args); 5784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.flags = 0; 5884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if ((ret = ioctl(mSock, SIOCGIWPRIV, &wrq)) < 0) { 5984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("SIOCGIPRIV failed: %d", ret); 6084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return ret; 6184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 6284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt priv_ptr = (struct iw_priv_args *)wrq.u.data.pointer; 6384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt#if 0 6484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt for(i=0;(i < wrq.u.data.length);i++) { 6584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("%s: [%x] %s\n", __func__, priv_ptr[i].cmd, priv_ptr[i].name); 6684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 6784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt#endif 6884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt for(i=0;(i < wrq.u.data.length);i++) { 6984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (strcmp(priv_ptr[i].name, fname) == 0) 7084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return priv_ptr[i].cmd; 7184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 7284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return -1; 735af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt} 745af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 755af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::startSoftap() { 7684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt struct iwreq wrq; 775af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt pid_t pid = 1; 7884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt int fnum, ret = 0; 795af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 805af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt LOGD("Softap start"); 815af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt if (mPid) { 825af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt LOGE("Softap already started"); 835af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt errno = EBUSY; 845af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt return -1; 855af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt } 8684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (mSock < 0) { 8784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Failed to open socket"); 8884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return -1; 8984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 905af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#if 0 915af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt if ((pid = fork()) < 0) { 925af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt LOGE("fork failed (%s)", strerror(errno)); 935af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt return -1; 945af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt } 955af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#endif 9684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt /* system("iwpriv wl0.1 AP_BSS_START"); */ 975af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt if (!pid) { 9884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt /* start hostapd */ 9984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return ret; 1005af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt } else { 10184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGD("Softap Started: %s", mIface); 10284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt fnum = getPrivFuncNum(mIface, "AP_BSS_START"); 10384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (fnum < 0) { 10484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Softap start - function not supported"); 10584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return -1; 10684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 10784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt strncpy(wrq.ifr_name, mIface, sizeof(wrq.ifr_name)); 10884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.length = 0; 10984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.pointer = mBuf; 11084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.flags = 0; 11184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt ret = ioctl(mSock, fnum, &wrq); 11284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (ret) { 11384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Softap start - failed: %d", ret); 11484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 11584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt else { 11684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt mPid = pid; 11784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGD("Softap start - Ok"); 11884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 1195af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt } 12084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return ret; 1215af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 1225af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt} 1235af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 1245af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::stopSoftap() { 12584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt struct iwreq wrq; 12684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt int fnum, ret; 12784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt 1285af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt LOGD("Softap stop"); 1295af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt if (mPid == 0) { 1305af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt LOGE("Softap already stopped"); 1315af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt return 0; 1325af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt } 13384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (mSock < 0) { 13484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Failed to open socket"); 13584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return -1; 13684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 13784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt fnum = getPrivFuncNum(mIface, "WL_AP_STOP"); 13884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (fnum < 0) { 13984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Softap stop - function not supported"); 14084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return -1; 14184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 14284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt strncpy(wrq.ifr_name, mIface, sizeof(wrq.ifr_name)); 14384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.length = 0; 14484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.pointer = mBuf; 14584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.flags = 0; 14684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt ret = ioctl(mSock, fnum, &wrq); 1475af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#if 0 1485af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt LOGD("Stopping Softap service"); 1495af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt kill(mPid, SIGTERM); 1505af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt waitpid(mPid, NULL, 0); 1515af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt#endif 1525af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt mPid = 0; 15384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGD("Softap service stopped: %d", ret); 15484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return ret; 1555af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt} 1565af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 1575af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtbool SoftapController::isSoftapStarted() { 1585af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt return (mPid != 0 ? true : false); 1595af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt} 1605af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt 16184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt/* 16284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt * Arguments: 16384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt * argv[2] - wlan interface 16484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt * argv[3] - softap interface 16584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt * argv[4] - command line 16684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt */ 1675af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidtint SoftapController::setSoftap(int argc, char *argv[]) { 16884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt struct iwreq wrq; 16984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt int fnum, ret; 17084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt 1715af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt LOGD("Softap set"); 17284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (mSock < 0) { 17384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Failed to open socket"); 17484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return -1; 17584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 17684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (argc < 4) { 17784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Missing arguments"); 17884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return -1; 17984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 18084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt 18184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt fnum = getPrivFuncNum(argv[2], "WL_AP_CFG"); 18284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (fnum < 0) { 18384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Softap set - function not supported"); 18484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return -1; 18584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 18684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt 18784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt strncpy(mIface, argv[3], sizeof(mIface)); 18884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt strncpy(wrq.ifr_name, argv[2], sizeof(wrq.ifr_name)); 18984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (argc >= 4) { 19084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt strncpy(mBuf, argv[4], sizeof(mBuf)); 19184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 19284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt 19384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.length = strlen(mBuf) + 1; 19484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.pointer = mBuf; 19584c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt wrq.u.data.flags = 0; 19684c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt /* system("iwpriv eth0 WL_AP_CFG ASCII_CMD=AP_CFG,SSID=\"AndroidAP\",SEC=\"open\",KEY=12345,CHANNEL=1,PREAMBLE=0,MAX_SCB=8,END"); */ 19784c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt ret = ioctl(mSock, fnum, &wrq); 19884c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt if (ret) { 19984c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGE("Softap set - failed: %d", ret); 20084c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 20184c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt else { 20284c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt LOGD("Softap set - Ok"); 20384c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt } 20484c65a62fe7b053fed7f20274ca7379627a87b79Dmitry Shmidt return ret; 2055af38c360587ca2eef0badf6137ccf018f8cd4aaDmitry Shmidt} 206