blob: dd9d388d91e3b056063eedcae84fa08384fc3d34 [file] [log] [blame]
Raj Kushwaha41027212010-10-13 00:11:12 -07001/*
Deepthi Gowrid0ea69c2012-12-26 14:08:38 +05302 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
Raj Kushwaha41027212010-10-13 00:11:12 -07003
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
Deepthi Gowrid0ea69c2012-12-26 14:08:38 +053013 * * Neither the name of The Linux Foundation, Inc. nor the names of its
Raj Kushwaha41027212010-10-13 00:11:12 -070014 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30
31#include <stdlib.h>
32#include <fcntl.h>
33#include <errno.h>
34#include <string.h>
35#include <stdio.h>
36
Deepthi Gowrid0ea69c2012-12-26 14:08:38 +053037#include <sys/socket.h>
Raj Kushwaha41027212010-10-13 00:11:12 -070038#include <linux/if.h>
39#include <linux/wireless.h>
40#include <sys/ioctl.h>
Raj Kushwaha41027212010-10-13 00:11:12 -070041#include <sys/stat.h>
42#include <sys/types.h>
43#include <sys/wait.h>
44#include <netinet/in.h>
45#include <arpa/inet.h>
46
47#define LOG_TAG "QCLDR-"
48
49#include "cutils/log.h"
50#include "cutils/memory.h"
51#include "cutils/misc.h"
52#include "cutils/properties.h"
53#include "private/android_filesystem_config.h"
54
55#include "qsap_api.h"
56#include "qsap.h"
Raj Kushwaha41027212010-10-13 00:11:12 -070057
58#include <sys/system_properties.h>
59
60#ifndef WIFI_DRIVER_MODULE_PATH
61#define WIFI_DRIVER_MODULE_PATH "/system/lib/modules/wlan.ko"
62#endif
63
64#ifndef WIFI_DRIVER_MODULE_NAME
65#define WIFI_DRIVER_MODULE_NAME "wlan"
66#endif
67
Raj Kushwaha41027212010-10-13 00:11:12 -070068#ifdef WIFI_DRIVER_MODULE_ARG
69#undef WIFI_DRIVER_MODULE_ARG
70#endif
71
Santosh Sajjanc463f732011-12-22 18:24:56 +053072#define WIFI_DRIVER_MODULE_ARG ""
Raj Kushwaha41027212010-10-13 00:11:12 -070073
Santosh Sajjan343ec712011-07-15 14:17:15 +053074/* WIFI_SDIO_IF_DRIVER_MODULE_NAME must be defined if sdioif driver required */
75#ifdef WIFI_SDIO_IF_DRIVER_MODULE_NAME
76
77#ifndef WIFI_SDIO_IF_DRIVER_MODULE_PATH
78#define WIFI_SDIO_IF_DRIVER_MODULE_PATH "/system/lib/modules/librasdioif.ko"
79#endif
80
81
82#ifndef WIFI_SDIO_IF_DRIVER_MODULE_ARG
83#define WIFI_SDIO_IF_DRIVER_MODULE_ARG ""
84#endif
85
86#endif
87
Deepthi Gowrid4c03152012-07-17 18:42:07 +053088#ifndef WIFI_CFG80211_DRIVER_MODULE_PATH
89#define WIFI_CFG80211_DRIVER_MODULE_PATH ""
90#endif
91#ifndef WIFI_CFG80211_DRIVER_MODULE_NAME
92#define WIFI_CFG80211_DRIVER_MODULE_NAME ""
93#endif
94#ifndef WIFI_CFG80211_DRIVER_MODULE_ARG
95#define WIFI_CFG80211_DRIVER_MODULE_ARG ""
96#endif
97
Santosh Sajjan343ec712011-07-15 14:17:15 +053098
Raj Kushwaha41027212010-10-13 00:11:12 -070099extern int init_module(const char *name, u32, const s8 *);
100extern int delete_module(const char *name, int);
101
Raj Kushwahaae27f822010-11-14 17:47:11 -0800102extern struct Command qsap_str[];
103
Raj Kushwaha41027212010-10-13 00:11:12 -0700104static s32 check_driver_loaded( const s8 * tag)
105{
106 FILE *proc;
107 s8 line[126];
108
109 if ((proc = fopen("/proc/modules", "r")) == NULL) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530110 ALOGW("Could not open %s: %s", "/proc/modules", strerror(errno));
Raj Kushwaha41027212010-10-13 00:11:12 -0700111 return 0;
112 }
113
114 while ((fgets(line, sizeof(line), proc)) != NULL) {
115 if (strncmp(line, tag, strlen(tag)) == 0) {
116 fclose(proc);
117 return 1;
118 }
119 }
120
121 fclose(proc);
122
123 return 0;
124}
125
126static s32 insmod(const s8 *filename, const s8 *args, const s8 * tag)
127{
128#ifndef SDK_TEST
129 void *module;
130 s32 size;
131 s32 ret = 0;
132
133 if ( check_driver_loaded(tag) ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530134 ALOGE("Driver: %s already loaded\n", filename);
Raj Kushwaha41027212010-10-13 00:11:12 -0700135 return ret;
136 }
137
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530138 ALOGD("Loading Driver: %s %s\n", filename, args);
Raj Kushwaha41027212010-10-13 00:11:12 -0700139
140 module = (void*)load_file(filename, (unsigned int*)&size);
141
142 if (!module) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530143 ALOGE("Cannot load file: %s\n", filename);
Raj Kushwaha41027212010-10-13 00:11:12 -0700144 return -1;
145 }
146
147 ret = init_module(module, size, args);
148
149 if ( ret ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530150 ALOGE("init_module (%s:%d) failed\n", filename, (int)size);
Raj Kushwaha41027212010-10-13 00:11:12 -0700151 }
152
153 free(module);
154
155 return ret;
156#else
157 return 0;
158#endif
159}
160
161static s32 rmmod(const s8 *modname)
162{
163#ifndef SDK_TEST
164 s32 ret = 0;
165 s32 maxtry = 10;
166
167 while (maxtry-- > 0) {
168 ret = delete_module(modname, O_NONBLOCK | O_EXCL);
169
170 if (ret < 0 && errno == EAGAIN){
171 usleep(50000);
172 } else {
173 break;
174 }
175 }
176
177 if (ret != 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530178 ALOGD("Unable to unload driver module \"%s\": %s\n",
Raj Kushwaha41027212010-10-13 00:11:12 -0700179 modname, strerror(errno));
180 }
181
182 return ret;
183#else
184 return 0;
185#endif
186}
187
188static const s8 SDIO_POLLING_ON[] = "/etc/init.qcom.sdio.sh 1";
189static const s8 SDIO_POLLING_OFF[] = "/etc/init.qcom.sdio.sh 0";
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530190static const char DRIVER_CFG80211_MODULE_NAME[] = WIFI_CFG80211_DRIVER_MODULE_NAME;
191static const char DRIVER_CFG80211_MODULE_PATH[] = WIFI_CFG80211_DRIVER_MODULE_PATH;
192static const char DRIVER_CFG80211_MODULE_ARG[] = WIFI_CFG80211_DRIVER_MODULE_ARG;
Raj Kushwaha41027212010-10-13 00:11:12 -0700193
194s32 wifi_qsap_load_driver(void)
195{
196 s32 size;
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530197 s32 ret = -1;
Raj Kushwaha41027212010-10-13 00:11:12 -0700198 s32 retry;
199
Raj Kushwaha41027212010-10-13 00:11:12 -0700200
201 if (system(SDIO_POLLING_ON)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530202// ALOGE("Could not turn on the polling...");
203 }
204
205 if ('\0' != *DRIVER_CFG80211_MODULE_PATH) {
206 if (insmod(DRIVER_CFG80211_MODULE_PATH, DRIVER_CFG80211_MODULE_ARG,DRIVER_CFG80211_MODULE_NAME) < 0) {
207 ALOGE("Could not load cfg80211...");
208 return ret;
209 }
Raj Kushwaha41027212010-10-13 00:11:12 -0700210 }
211
Santosh Sajjan343ec712011-07-15 14:17:15 +0530212#ifdef WIFI_SDIO_IF_DRIVER_MODULE_NAME
213 ret = insmod(WIFI_SDIO_IF_DRIVER_MODULE_PATH, WIFI_SDIO_IF_DRIVER_MODULE_ARG, WIFI_SDIO_IF_DRIVER_MODULE_NAME " ");
Raj Kushwaha41027212010-10-13 00:11:12 -0700214
Santosh Sajjan343ec712011-07-15 14:17:15 +0530215 if ( ret != 0 ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530216 ALOGE("init_module failed sdioif\n");
Santosh Sajjan343ec712011-07-15 14:17:15 +0530217 ret = eERR_LOAD_FAILED_SDIOIF;
218 goto end;
Raj Kushwaha41027212010-10-13 00:11:12 -0700219 }
220
Santosh Sajjan343ec712011-07-15 14:17:15 +0530221 sched_yield();
222#endif
223
Raj Kushwaha41027212010-10-13 00:11:12 -0700224 ret = insmod(WIFI_DRIVER_MODULE_PATH, WIFI_DRIVER_MODULE_ARG, WIFI_DRIVER_MODULE_NAME " ");
225
226 if ( ret != 0 ) {
Santosh Sajjan343ec712011-07-15 14:17:15 +0530227#ifdef WIFI_SDIO_IF_DRIVER_MODULE_NAME
228 if ( check_driver_loaded(WIFI_SDIO_IF_DRIVER_MODULE_NAME " ") ) {
229 if ( rmmod(WIFI_SDIO_IF_DRIVER_MODULE_NAME) ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530230 ALOGE("Unable to unload the station mode librasdioif driver\n");
Raj Kushwaha41027212010-10-13 00:11:12 -0700231 }
232 }
Santosh Sajjan343ec712011-07-15 14:17:15 +0530233#endif
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530234 if ('\0' != *DRIVER_CFG80211_MODULE_NAME) {
235 rmmod(DRIVER_CFG80211_MODULE_NAME);
236 }
237 ALOGE("init_module failed libra_softap\n");
Raj Kushwaha41027212010-10-13 00:11:12 -0700238 ret = eERR_LOAD_FAILED_SOFTAP;
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530239 goto end;
Raj Kushwaha41027212010-10-13 00:11:12 -0700240 }
241
242 sched_yield();
243
244 ret = eSUCCESS;
245
246end:
247 if(system(SDIO_POLLING_OFF)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530248// ALOGE("Could not turn off the polling...");
Raj Kushwaha41027212010-10-13 00:11:12 -0700249 }
250
251 return ret;
252}
253
Raj Kushwaha13eb75f2011-03-12 10:21:45 -0800254void qsap_send_module_down_indication(void)
255{
256 int s, ret;
257 struct iwreq wrq;
258
259 /*
260 * If the driver is loaded, ask it to broadcast a netlink message
261 * that it will be closing, so listeners can close their sockets.
262 *
263 */
264
265
266 /* Equivalent to: iwpriv wlan0 sendModuleInd */
267 if ((s = socket(PF_INET, SOCK_DGRAM, 0)) >= 0) {
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +0530268 strlcpy(wrq.ifr_name, "wlan0", IFNAMSIZ);
Raj Kushwaha13eb75f2011-03-12 10:21:45 -0800269 wrq.u.data.length = 0; /* No Set arguments */
270 wrq.u.mode = 5; /* WE_MODULE_DOWN_IND sub-command */
271 ret = ioctl(s, (SIOCIWFIRSTPRIV + 1), &wrq);
Raj Kushwaha13eb75f2011-03-12 10:21:45 -0800272 if (ret < 0 ) {
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +0530273 strlcpy(wrq.ifr_name, "softap.0", IFNAMSIZ);
Yunsen Wang26a9f6b2011-07-06 11:23:58 -0700274 ret = ioctl(s, (SIOCIWFIRSTPRIV + 1), &wrq);
275 if (ret < 0 ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530276 ALOGE("ioctl failed: %s", strerror(errno));
Yunsen Wang26a9f6b2011-07-06 11:23:58 -0700277 }
Raj Kushwaha13eb75f2011-03-12 10:21:45 -0800278 }
Yunsen Wang26a9f6b2011-07-06 11:23:58 -0700279 close(s);
Raj Kushwaha13eb75f2011-03-12 10:21:45 -0800280 sched_yield();
281 }
282 else {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530283 ALOGE("Socket open failed: %s", strerror(errno));
Raj Kushwaha13eb75f2011-03-12 10:21:45 -0800284 }
285}
286
Sameer Thalappilcaf87922012-01-30 16:56:29 -0800287
288s32 qsap_send_init_ap(void)
289{
290 int s, ret;
291 struct iwreq wrq;
292 s32 status = eSUCCESS;
293 u32 *params = (u32 *)&wrq.u;
294
295 /* Equivalent to: iwpriv wlan0 initAP */
296 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +0530297 strlcpy(wrq.ifr_name, "wlan0", IFNAMSIZ);
Sameer Thalappilcaf87922012-01-30 16:56:29 -0800298 wrq.u.data.length = 0; /* No Set arguments */
299 wrq.u.data.flags = 2; /* WE_INIT_AP sub-command */
300 ret = ioctl(s, (SIOCIWFIRSTPRIV + 6), &wrq);
301 if (ret < 0 ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530302 ALOGE("ioctl failed: %s", strerror(errno));
Sameer Thalappilcaf87922012-01-30 16:56:29 -0800303 status = eERR_START_SAP;
304 }
305 close(s);
306 sched_yield();
307 }
308 else {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530309 ALOGE("Socket open failed: %s", strerror(errno));
Sameer Thalappilcaf87922012-01-30 16:56:29 -0800310 status = eERR_START_SAP;
311 }
312 return status;
313}
314
315
316s32 qsap_send_exit_ap(void)
317{
318 int s, ret;
319 struct iwreq wrq;
320 s32 status = eSUCCESS;
321 u32 *params = (u32 *)&wrq.u;
322
323 /* Equivalent to: iwpriv wlan0 exitAP */
324 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +0530325 strlcpy(wrq.ifr_name, "wlan0", IFNAMSIZ);
Sameer Thalappilcaf87922012-01-30 16:56:29 -0800326 wrq.u.data.length = 0; /* No Set arguments */
327 wrq.u.data.flags = 3; /*WE_EXIT_AP sub-command */
328
329 ret = ioctl(s, (SIOCIWFIRSTPRIV + 6), &wrq);
330 if (ret < 0 ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530331 ALOGE("ioctl failed: %s", strerror(errno));
Sameer Thalappilcaf87922012-01-30 16:56:29 -0800332 status = eERR_STOP_SAP;
333 }
334 close(s);
335 sched_yield();
336 }
337 else {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530338 ALOGE("Socket open failed: %s", strerror(errno));
Sameer Thalappilcaf87922012-01-30 16:56:29 -0800339 status = eERR_STOP_SAP;
340 }
341 return status;
342}
343
Raj Kushwaha41027212010-10-13 00:11:12 -0700344s32 wifi_qsap_unload_driver()
345{
346 s32 ret = eSUCCESS;
347
348 if(system(SDIO_POLLING_ON)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530349 ALOGE("Could not turn on the polling...");
Raj Kushwaha41027212010-10-13 00:11:12 -0700350 }
351
352 if ( check_driver_loaded(WIFI_DRIVER_MODULE_NAME " ") ) {
Raj Kushwaha13eb75f2011-03-12 10:21:45 -0800353 qsap_send_module_down_indication();
Raj Kushwaha41027212010-10-13 00:11:12 -0700354 if ( rmmod(WIFI_DRIVER_MODULE_NAME) ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530355 ALOGE("Unable to unload the libra_softap driver\n");
Raj Kushwaha41027212010-10-13 00:11:12 -0700356 ret = eERR_UNLOAD_FAILED_SOFTAP;
357 goto end;
358 }
359 }
360
361 sched_yield();
362
Santosh Sajjan343ec712011-07-15 14:17:15 +0530363#ifdef WIFI_SDIO_IF_DRIVER_MODULE_NAME
Raj Kushwaha41027212010-10-13 00:11:12 -0700364 if ( check_driver_loaded(WIFI_SDIO_IF_DRIVER_MODULE_NAME " ") ) {
365 if ( rmmod(WIFI_SDIO_IF_DRIVER_MODULE_NAME) ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530366 ALOGE("Unable to unload the librasdioif driver\n");
Raj Kushwaha41027212010-10-13 00:11:12 -0700367 ret = eERR_UNLOAD_FAILED_SDIO;
368 goto end;
369 }
370 }
Santosh Sajjan343ec712011-07-15 14:17:15 +0530371#endif
372
Raj Kushwaha41027212010-10-13 00:11:12 -0700373end:
374 if(system(SDIO_POLLING_OFF)) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530375 ALOGE("Could not turn off the polling...");
Raj Kushwaha41027212010-10-13 00:11:12 -0700376 }
377
378 return ret;
379}
380
381s32 wifi_qsap_stop_bss(void)
382{
383#define QCIEEE80211_IOCTL_STOPBSS (SIOCIWFIRSTPRIV + 6)
384 s32 sock;
385 s32 ret = eERR_STOP_BSS;
386 s8 cmd[] = "stopbss";
387 s8 interface[128];
388 s8 *iface;
389 s32 len = 128;
390 struct iwreq wrq;
391 struct iw_priv_args *priv_ptr;
392
393 if(ENABLE != is_softap_enabled()) {
394 ret = eERR_BSS_NOT_STARTED;
395 return ret;
396 }
397
Raj Kushwahaae27f822010-11-14 17:47:11 -0800398 if(NULL == (iface = qsap_get_config_value(CONFIG_FILE, &qsap_str[STR_INTERFACE], interface, (u32*)&len))) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530399 ALOGE("%s :interface error \n", __func__);
Raj Kushwaha41027212010-10-13 00:11:12 -0700400 return ret;
401 }
402
403 /* Issue the stopbss command to driver */
404 sock = socket(AF_INET, SOCK_DGRAM, 0);
405
406 if (sock < 0) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530407 ALOGE("Failed to open socket");
Raj Kushwaha41027212010-10-13 00:11:12 -0700408 return eERR_STOP_BSS;
409 }
410
Hanumantha Reddy Pothula87d01a12013-11-29 17:09:30 +0530411 strlcpy(wrq.ifr_name, iface, sizeof(wrq.ifr_name));
Raj Kushwaha41027212010-10-13 00:11:12 -0700412 wrq.u.data.length = sizeof(cmd);
413 wrq.u.data.pointer = cmd;
414 wrq.u.data.flags = 0;
415
416 ret = ioctl(sock, QCIEEE80211_IOCTL_STOPBSS, &wrq);
417
418 /* Here IOCTL is always returning non Zero: temporary fix untill driver is fixed*/
419 ret = 0;
420 close(sock);
421
422 if (ret) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530423 ALOGE("IOCTL stopbss failed: %ld", ret);
Raj Kushwaha41027212010-10-13 00:11:12 -0700424 ret = eERR_STOP_BSS;
425 } else {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530426 ALOGD("STOP BSS ISSUED");
Raj Kushwaha41027212010-10-13 00:11:12 -0700427 ret = eSUCCESS;
428 }
429
430 sched_yield();
431 return ret;
432}
433
434s32 is_softap_enabled(void)
435{
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +0530436 s32 mode = 0;
437 int ret;
Raj Kushwaha41027212010-10-13 00:11:12 -0700438
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +0530439 ret = qsap_get_mode(&mode);
440 if (eSUCCESS != ret) {
441 ALOGD("Failed to get the mode of operation\n");
Deepthi Gowrid0ea69c2012-12-26 14:08:38 +0530442 return eERR_UNKNOWN;
Raj Kushwaha41027212010-10-13 00:11:12 -0700443 }
444
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +0530445 if (mode == IW_MODE_MASTER) {
446 ALOGD("HOSTAPD Enabled\n");
447 return ENABLE;
Deepthi Gowrid0ea69c2012-12-26 14:08:38 +0530448 }
449
Vinay Krishna Eranna1c430432013-10-01 19:37:51 +0530450 ALOGD("HOSTAPD Disabled\n");
451
Raj Kushwaha41027212010-10-13 00:11:12 -0700452 return DISABLE;
453}
454
455s32 commit(void)
456{
457#ifndef SDK_TEST
458 s32 ret = eERR_COMMIT;
459
460 if ( is_softap_enabled() ) {
461 /** Stop BSS */
462 if(eSUCCESS != (ret = wifi_qsap_stop_bss())) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530463 ALOGE("%s: stop bss failed \n", __func__);
Raj Kushwaha41027212010-10-13 00:11:12 -0700464 return ret;
465 }
466 sleep(1);
467 }
468
469 ret = wifi_qsap_start_softap();
470
471 if( eSUCCESS != ret )
472 wifi_qsap_unload_driver();
473
474 return ret;
475#else
476 return eSUCCESS;
477#endif
478}
479
480s32 wifi_qsap_start_softap()
481{
482 s32 retry = 4;
Raj Kushwahaae27f822010-11-14 17:47:11 -0800483 FILE * fp;
Raj Kushwaha41027212010-10-13 00:11:12 -0700484
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530485 ALOGD("Starting Soft AP...\n");
Raj Kushwaha41027212010-10-13 00:11:12 -0700486
Raj Kushwahaae27f822010-11-14 17:47:11 -0800487 /* Check if configuration files are present, if not create the default files */
488 check_for_configuration_files();
489
Raj Kushwaha41027212010-10-13 00:11:12 -0700490 /* Delete control interface if it was left over because of previous crash */
491 if ( !is_softap_enabled() ) {
492 qsap_del_ctrl_iface();
493 }
494
Yunsen Wang458db7c2011-11-15 21:23:32 -0800495 /* Ensure correct path for ini file name */
496 qsap_set_ini_filename();
497
Raj Kushwahaae27f822010-11-14 17:47:11 -0800498 while(retry--) {
499 /* May be the configuration file is corrupted or not available, */
500 /* copy the default configuration file */
501 if ( retry == 1 )
502 wifi_qsap_reset_to_default(CONFIG_FILE, DEFAULT_CONFIG_FILE_PATH);
503
Raj Kushwaha41027212010-10-13 00:11:12 -0700504 /** Stop hostapd */
505 if(0 != property_set("ctl.start", "hostapd")) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530506 ALOGE("failed \n");
Raj Kushwaha41027212010-10-13 00:11:12 -0700507 continue;
508 }
509
510 sleep(1);
511
512 if ( is_softap_enabled() ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530513 ALOGD("success \n");
Raj Kushwaha41027212010-10-13 00:11:12 -0700514 return eSUCCESS;
515 }
516 }
517
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530518 ALOGE("Unable to start the SoftAP\n");
Raj Kushwaha41027212010-10-13 00:11:12 -0700519 return eERR_START_SAP;
520}
521
Sameer Thalappilcaf87922012-01-30 16:56:29 -0800522#ifdef QCOM_WLAN_CONCURRENCY
523s32 wifi_qsap_start_softap_in_concurrency()
524{
525 s32 status;
526 /*Send initAP IOCTL to Driver. Hostapd start is done by Netd.*/
527 status = qsap_send_init_ap();
528 return status;
529}
530
531s32 wifi_qsap_stop_softap_in_concurrency()
532{
533 s32 status;
534 /*Send exitAP IOCTL to Driver. Hostapd stop is done by Netd.*/
535 status = qsap_send_exit_ap();
536 return status;
537}
538#endif
539
540
Raj Kushwaha41027212010-10-13 00:11:12 -0700541s32 wifi_qsap_stop_softap()
542{
543 s32 ret = eSUCCESS;
544
545 if ( is_softap_enabled() ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530546 ALOGD("Stopping BSS ..... ");
Raj Kushwaha41027212010-10-13 00:11:12 -0700547
548 /** Stop the BSS */
549 if (eSUCCESS != (ret = wifi_qsap_stop_bss()) ) {
Deepthi Gowrid4c03152012-07-17 18:42:07 +0530550 ALOGE("failed \n");
Raj Kushwaha41027212010-10-13 00:11:12 -0700551 return ret;
552 }
553 sleep(1);
554 }
555
556 return ret;
557}
558
559s32 wifi_qsap_reload_softap()
560{
561 s32 ret = eERR_RELOAD_SAP;
562
563 /** SDK API to reload the firmware */
564 if (eSUCCESS != (ret = wifi_qsap_stop_softap())) {
565 return ret;
566 }
567
568 if (eSUCCESS != (ret = wifi_qsap_unload_driver())) {
569 return ret;
570 }
571
572 usleep(500000);
573
574 if (eSUCCESS != (ret = wifi_qsap_load_driver())) {
575 return ret;
576 }
577
578 sleep(1);
579
580 if (eSUCCESS != (ret = wifi_qsap_start_softap())) {
581 wifi_qsap_unload_driver();
582 return ret;
583 }
584
585 return eSUCCESS;
586}
Dedy Lansky350c3532016-05-16 11:54:10 +0300587
588static pid_t wigigSoftApPid = 0;
589static const char WIGIG_ENTROPY_FILE[] = "/data/misc/wifi/wigig_entropy.bin";
590static unsigned char dummy_key[21] = { 0x02, 0x11, 0xbe, 0x33, 0x43, 0x35,
591 0x68, 0x47, 0x84, 0x99, 0xa9, 0x2b,
592 0x1c, 0xd3, 0xee, 0xff, 0xf1, 0xe2,
593 0xf3, 0xf4, 0xf5 };
594static const char HOSTAPD_BIN_FILE[] = "/system/bin/hostapd";
595static const char WIGIG_HOSTAPD_CONF_FILE[] = "/data/misc/wifi/wigig_hostapd.conf";
596#define AP_BSS_START_DELAY 200000
597#define AP_BSS_STOP_DELAY 500000
598
599int wigig_ensure_entropy_file_exists()
600{
601 int ret;
602 int destfd;
603
604 ret = access(WIGIG_ENTROPY_FILE, R_OK|W_OK);
605 if ((ret == 0) || (errno == EACCES)) {
606 if ((ret != 0) &&
607 (chmod(WIGIG_ENTROPY_FILE, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) != 0)) {
608 ALOGE("Cannot set RW to \"%s\": %s", WIGIG_ENTROPY_FILE, strerror(errno));
609 return -1;
610 }
611 return 0;
612 }
613 destfd = TEMP_FAILURE_RETRY(open(WIGIG_ENTROPY_FILE, O_CREAT|O_RDWR, 0660));
614 if (destfd < 0) {
615 ALOGE("Cannot create \"%s\": %s", WIGIG_ENTROPY_FILE, strerror(errno));
616 return -1;
617 }
618
619 if (TEMP_FAILURE_RETRY(write(destfd, dummy_key, sizeof(dummy_key))) != sizeof(dummy_key)) {
620 ALOGE("Error writing \"%s\": %s", WIGIG_ENTROPY_FILE, strerror(errno));
621 close(destfd);
622 return -1;
623 }
624 close(destfd);
625
626 /* chmod is needed because open() didn't set permisions properly */
627 if (chmod(WIGIG_ENTROPY_FILE, 0660) < 0) {
628 ALOGE("Error changing permissions of %s to 0660: %s",
629 WIGIG_ENTROPY_FILE, strerror(errno));
630 unlink(WIGIG_ENTROPY_FILE);
631 return -1;
632 }
633
634 if (chown(WIGIG_ENTROPY_FILE, AID_SYSTEM, AID_WIFI) < 0) {
635 ALOGE("Error changing group ownership of %s to %d: %s",
636 WIGIG_ENTROPY_FILE, AID_WIFI, strerror(errno));
637 unlink(WIGIG_ENTROPY_FILE);
638 return -1;
639 }
640 return 0;
641}
642
643s32 wifi_qsap_start_wigig_softap(void)
644{
645 pid_t pid = 1;
646
647 ALOGD("%s", __func__);
648
649 if (wigigSoftApPid) {
650 ALOGE("Wigig SoftAP is already running");
651 return eERR_START_SAP;
652 }
653
654 if (wigig_ensure_entropy_file_exists() < 0) {
655 ALOGE("Wigig entropy file was not created");
656 }
657
658 if ((pid = fork()) < 0) {
659 ALOGE("fork failed (%s)", strerror(errno));
660 return eERR_START_SAP;
661 }
662
663 if (!pid) {
664 if (execl(HOSTAPD_BIN_FILE, HOSTAPD_BIN_FILE,
665 "-e", WIGIG_ENTROPY_FILE, "-dd",
666 WIGIG_HOSTAPD_CONF_FILE, (char *) NULL)) {
667 ALOGE("execl failed (%s)", strerror(errno));
668 }
669 ALOGE("Wigig SoftAP failed to start. Exiting child process...");
670 exit(-1);
671 }
672
673 wigigSoftApPid = pid;
674 ALOGD("Wigig SoftAP started successfully");
675 usleep(AP_BSS_START_DELAY);
676
677 return eSUCCESS;
678}
679
680s32 wifi_qsap_stop_wigig_softap(void)
681{
682 ALOGD("%s", __func__);
683
684 if (wigigSoftApPid == 0) {
685 ALOGE("Wigig SoftAP is not running");
686 return eSUCCESS;
687 }
688
689 ALOGD("Stopping the Wigig SoftAP...");
690 kill(wigigSoftApPid, SIGTERM);
691 waitpid(wigigSoftApPid, NULL, 0);
692
693 wigigSoftApPid = 0;
694 ALOGD("Wigig SoftAP stopped successfully");
695 usleep(AP_BSS_STOP_DELAY);
696 return eSUCCESS;
697}