SoftapController.cpp revision 84c65a62fe7b053fed7f20274ca7379627a87b79
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdlib.h> 18#include <errno.h> 19#include <fcntl.h> 20 21#include <sys/socket.h> 22#include <sys/stat.h> 23#include <sys/types.h> 24#include <sys/wait.h> 25 26#include <netinet/in.h> 27#include <arpa/inet.h> 28 29#include <linux/wireless.h> 30 31#define LOG_TAG "SoftapController" 32#include <cutils/log.h> 33 34#include "SoftapController.h" 35 36SoftapController::SoftapController() { 37 mPid = 0; 38 mSock = socket(AF_INET, SOCK_DGRAM, 0); 39 if (mSock < 0) 40 LOGE("Failed to open socket"); 41 memset(mIface, 0, sizeof(mIface)); 42} 43 44SoftapController::~SoftapController() { 45 if (mSock >= 0) 46 close(mSock); 47} 48 49int SoftapController::getPrivFuncNum(char *iface, const char *fname) { 50 struct iwreq wrq; 51 struct iw_priv_args *priv_ptr; 52 int i, ret; 53 54 strncpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name)); 55 wrq.u.data.pointer = mBuf; 56 wrq.u.data.length = sizeof(mBuf) / sizeof(struct iw_priv_args); 57 wrq.u.data.flags = 0; 58 if ((ret = ioctl(mSock, SIOCGIWPRIV, &wrq)) < 0) { 59 LOGE("SIOCGIPRIV failed: %d", ret); 60 return ret; 61 } 62 priv_ptr = (struct iw_priv_args *)wrq.u.data.pointer; 63#if 0 64 for(i=0;(i < wrq.u.data.length);i++) { 65 LOGE("%s: [%x] %s\n", __func__, priv_ptr[i].cmd, priv_ptr[i].name); 66 } 67#endif 68 for(i=0;(i < wrq.u.data.length);i++) { 69 if (strcmp(priv_ptr[i].name, fname) == 0) 70 return priv_ptr[i].cmd; 71 } 72 return -1; 73} 74 75int SoftapController::startSoftap() { 76 struct iwreq wrq; 77 pid_t pid = 1; 78 int fnum, ret = 0; 79 80 LOGD("Softap start"); 81 if (mPid) { 82 LOGE("Softap already started"); 83 errno = EBUSY; 84 return -1; 85 } 86 if (mSock < 0) { 87 LOGE("Failed to open socket"); 88 return -1; 89 } 90#if 0 91 if ((pid = fork()) < 0) { 92 LOGE("fork failed (%s)", strerror(errno)); 93 return -1; 94 } 95#endif 96 /* system("iwpriv wl0.1 AP_BSS_START"); */ 97 if (!pid) { 98 /* start hostapd */ 99 return ret; 100 } else { 101 LOGD("Softap Started: %s", mIface); 102 fnum = getPrivFuncNum(mIface, "AP_BSS_START"); 103 if (fnum < 0) { 104 LOGE("Softap start - function not supported"); 105 return -1; 106 } 107 strncpy(wrq.ifr_name, mIface, sizeof(wrq.ifr_name)); 108 wrq.u.data.length = 0; 109 wrq.u.data.pointer = mBuf; 110 wrq.u.data.flags = 0; 111 ret = ioctl(mSock, fnum, &wrq); 112 if (ret) { 113 LOGE("Softap start - failed: %d", ret); 114 } 115 else { 116 mPid = pid; 117 LOGD("Softap start - Ok"); 118 } 119 } 120 return ret; 121 122} 123 124int SoftapController::stopSoftap() { 125 struct iwreq wrq; 126 int fnum, ret; 127 128 LOGD("Softap stop"); 129 if (mPid == 0) { 130 LOGE("Softap already stopped"); 131 return 0; 132 } 133 if (mSock < 0) { 134 LOGE("Failed to open socket"); 135 return -1; 136 } 137 fnum = getPrivFuncNum(mIface, "WL_AP_STOP"); 138 if (fnum < 0) { 139 LOGE("Softap stop - function not supported"); 140 return -1; 141 } 142 strncpy(wrq.ifr_name, mIface, sizeof(wrq.ifr_name)); 143 wrq.u.data.length = 0; 144 wrq.u.data.pointer = mBuf; 145 wrq.u.data.flags = 0; 146 ret = ioctl(mSock, fnum, &wrq); 147#if 0 148 LOGD("Stopping Softap service"); 149 kill(mPid, SIGTERM); 150 waitpid(mPid, NULL, 0); 151#endif 152 mPid = 0; 153 LOGD("Softap service stopped: %d", ret); 154 return ret; 155} 156 157bool SoftapController::isSoftapStarted() { 158 return (mPid != 0 ? true : false); 159} 160 161/* 162 * Arguments: 163 * argv[2] - wlan interface 164 * argv[3] - softap interface 165 * argv[4] - command line 166 */ 167int SoftapController::setSoftap(int argc, char *argv[]) { 168 struct iwreq wrq; 169 int fnum, ret; 170 171 LOGD("Softap set"); 172 if (mSock < 0) { 173 LOGE("Failed to open socket"); 174 return -1; 175 } 176 if (argc < 4) { 177 LOGE("Missing arguments"); 178 return -1; 179 } 180 181 fnum = getPrivFuncNum(argv[2], "WL_AP_CFG"); 182 if (fnum < 0) { 183 LOGE("Softap set - function not supported"); 184 return -1; 185 } 186 187 strncpy(mIface, argv[3], sizeof(mIface)); 188 strncpy(wrq.ifr_name, argv[2], sizeof(wrq.ifr_name)); 189 if (argc >= 4) { 190 strncpy(mBuf, argv[4], sizeof(mBuf)); 191 } 192 193 wrq.u.data.length = strlen(mBuf) + 1; 194 wrq.u.data.pointer = mBuf; 195 wrq.u.data.flags = 0; 196 /* system("iwpriv eth0 WL_AP_CFG ASCII_CMD=AP_CFG,SSID=\"AndroidAP\",SEC=\"open\",KEY=12345,CHANNEL=1,PREAMBLE=0,MAX_SCB=8,END"); */ 197 ret = ioctl(mSock, fnum, &wrq); 198 if (ret) { 199 LOGE("Softap set - failed: %d", ret); 200 } 201 else { 202 LOGD("Softap set - Ok"); 203 } 204 return ret; 205} 206